killbill-uncached

Merge branch 'jdbi-rework'

5/31/2017 6:45:49 AM

Changes

account/pom.xml 10(+5 -5)

beatrix/pom.xml 8(+4 -4)

catalog/pom.xml 4(+0 -4)

catalog/src/main/java/org/killbill/billing/catalog/dao/PlanPhaseKeysCollectionBinder.java 57(+0 -57)

invoice/pom.xml 10(+5 -5)

overdue/pom.xml 8(+4 -4)

payment/pom.xml 4(+0 -4)

payment/src/main/java/org/killbill/billing/payment/dao/PaymentStateCollectionBinder.java 57(+0 -57)

payment/src/main/java/org/killbill/billing/payment/dao/StateCollectionBinder.java 58(+0 -58)

payment/src/main/java/org/killbill/billing/payment/dao/TransactionStatusCollectionBinder.java 57(+0 -57)

pom.xml 2(+1 -1)

tenant/pom.xml 10(+5 -5)

usage/pom.xml 10(+5 -5)

util/pom.xml 10(+5 -5)

util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoStringTemplate.java 145(+0 -145)

util/src/main/java/org/killbill/billing/util/tag/dao/UUIDCollectionBinder.java 54(+0 -54)

Details

account/pom.xml 10(+5 -5)

diff --git a/account/pom.xml b/account/pom.xml
index c00ef95..54e34a8 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -79,7 +79,7 @@
         </dependency>
         <dependency>
             <groupId>org.antlr</groupId>
-            <artifactId>stringtemplate</artifactId>
+            <artifactId>ST4</artifactId>
             <scope>runtime</scope>
         </dependency>
         <dependency>
@@ -88,10 +88,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-api</artifactId>
         </dependency>
@@ -162,6 +158,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-jdbi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.commons</groupId>
             <artifactId>killbill-queue</artifactId>
         </dependency>
         <dependency>
diff --git a/account/src/main/java/org/killbill/billing/account/dao/AccountEmailSqlDao.java b/account/src/main/java/org/killbill/billing/account/dao/AccountEmailSqlDao.java
index 80856ce..5108df8 100644
--- a/account/src/main/java/org/killbill/billing/account/dao/AccountEmailSqlDao.java
+++ b/account/src/main/java/org/killbill/billing/account/dao/AccountEmailSqlDao.java
@@ -20,7 +20,7 @@ import java.util.List;
 import java.util.UUID;
 
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
@@ -30,17 +30,17 @@ import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface AccountEmailSqlDao extends EntitySqlDao<AccountEmailModelDao, AccountEmail> {
 
     @SqlUpdate
     @Audited(ChangeType.DELETE)
-    public void markEmailAsDeleted(@BindBean final AccountEmailModelDao accountEmail,
-                                   @BindBean final InternalCallContext context);
+    public void markEmailAsDeleted(@SmartBindBean final AccountEmailModelDao accountEmail,
+                                   @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     public List<AccountEmailModelDao> getEmailByAccountId(@Bind("accountId") final UUID accountId,
-                                                          @BindBean final InternalTenantContext context);
+                                                          @SmartBindBean final InternalTenantContext context);
 }
diff --git a/account/src/main/java/org/killbill/billing/account/dao/AccountSqlDao.java b/account/src/main/java/org/killbill/billing/account/dao/AccountSqlDao.java
index 77bea77..1506e64 100644
--- a/account/src/main/java/org/killbill/billing/account/dao/AccountSqlDao.java
+++ b/account/src/main/java/org/killbill/billing/account/dao/AccountSqlDao.java
@@ -27,44 +27,44 @@ import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface AccountSqlDao extends EntitySqlDao<AccountModelDao, Account> {
 
     @SqlQuery
     public AccountModelDao getAccountByKey(@Bind("externalKey") final String key,
-                                           @BindBean final InternalTenantContext context);
+                                           @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public UUID getIdFromKey(@Bind("externalKey") final String key,
-                             @BindBean final InternalTenantContext context);
+                             @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public Integer getBCD(@Bind("id") String accountId,
-                          @BindBean final InternalTenantContext context);
+                          @SmartBindBean final InternalTenantContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
-    public void update(@BindBean final AccountModelDao account,
-                       @BindBean final InternalCallContext context);
+    public void update(@SmartBindBean final AccountModelDao account,
+                       @SmartBindBean final InternalCallContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     public Object updatePaymentMethod(@Bind("id") String accountId,
                                       @Bind("paymentMethodId") String paymentMethodId,
-                                      @BindBean final InternalCallContext context);
+                                      @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     List<AccountModelDao> getAccountsByParentId(@Bind("parentAccountId") UUID parentAccountId,
-                                                @BindBean final InternalTenantContext context);
+                                                @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public AccountModelDao luckySearch(@Bind("searchKey") final String searchKey,
-                                       @BindBean final InternalTenantContext context);
+                                       @SmartBindBean final InternalTenantContext context);
 
 }
diff --git a/account/src/main/resources/org/killbill/billing/account/dao/AccountEmailSqlDao.sql.stg b/account/src/main/resources/org/killbill/billing/account/dao/AccountEmailSqlDao.sql.stg
index fa5d62b..e54ad7d 100644
--- a/account/src/main/resources/org/killbill/billing/account/dao/AccountEmailSqlDao.sql.stg
+++ b/account/src/main/resources/org/killbill/billing/account/dao/AccountEmailSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group AccountEmailSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "account_emails"
 
diff --git a/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg b/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg
index 937b12f..c46855d 100644
--- a/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg
+++ b/account/src/main/resources/org/killbill/billing/account/dao/AccountSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group AccountSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "accounts"
 
@@ -64,7 +64,7 @@ tableValues() ::= <<
 
 /** The accounts table doesn't have an account_record_id column (it's the record_id) **/
 accountRecordIdFieldWithComma(prefix) ::= ""
-accountRecordIdValueWithComma(prefix) ::= ""
+accountRecordIdValueWithComma() ::= ""
 
 update() ::= <<
 update accounts set
@@ -91,7 +91,7 @@ update accounts set
 , updated_date = :updatedDate
 , updated_by = :updatedBy
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
@@ -101,19 +101,19 @@ updatePaymentMethod() ::= <<
     SET payment_method_id = :paymentMethodId
     , updated_date = :updatedDate
     , updated_by = :updatedBy
-    WHERE id = :id <AND_CHECK_TENANT()>;
+    WHERE id = :id <AND_CHECK_TENANT("")>;
 >>
 
 getAccountByKey() ::= <<
-    select <allTableFields()>
+    select <allTableFields("")>
     from accounts
-    where external_key = :externalKey <AND_CHECK_TENANT()>;
+    where external_key = :externalKey <AND_CHECK_TENANT("")>;
 >>
 
 getBCD() ::= <<
     select billing_cycle_day_local
     from accounts
-    where id = :id <AND_CHECK_TENANT()>;
+    where id = :id <AND_CHECK_TENANT("")>;
 >>
 
 searchQuery(prefix) ::= <<
@@ -130,50 +130,50 @@ select
 <allTableFields("t.")>
 from <tableName()> t
 join (
-  select distinct <recordIdField()>
+  select distinct <recordIdField("")>
   from (
     (
-      select <recordIdField()>
+      select <recordIdField("")>
       from <tableName()>
-      where <idField()> = :searchKey
-      <andCheckSoftDeletionWithComma()>
-      <AND_CHECK_TENANT()>
+      where <idField("")> = :searchKey
+      <andCheckSoftDeletionWithComma("")>
+      <AND_CHECK_TENANT("")>
       limit 1
     )
     union all
     (
-      select <recordIdField()>
+      select <recordIdField("")>
       from <tableName()>
       where name = :searchKey
-      <andCheckSoftDeletionWithComma()>
-      <AND_CHECK_TENANT()>
+      <andCheckSoftDeletionWithComma("")>
+      <AND_CHECK_TENANT("")>
       limit 1
     )
     union all
     (
-      select <recordIdField()>
+      select <recordIdField("")>
       from <tableName()>
       where email = :searchKey
-      <andCheckSoftDeletionWithComma()>
-      <AND_CHECK_TENANT()>
+      <andCheckSoftDeletionWithComma("")>
+      <AND_CHECK_TENANT("")>
       limit 1
     )
     union all
     (
-      select <recordIdField()>
+      select <recordIdField("")>
       from <tableName()>
       where external_key = :searchKey
-      <andCheckSoftDeletionWithComma()>
-      <AND_CHECK_TENANT()>
+      <andCheckSoftDeletionWithComma("")>
+      <AND_CHECK_TENANT("")>
       limit 1
     )
     union all
     (
-      select <recordIdField()>
+      select <recordIdField("")>
       from <tableName()>
       where company_name = :searchKey
-      <andCheckSoftDeletionWithComma()>
-      <AND_CHECK_TENANT()>
+      <andCheckSoftDeletionWithComma("")>
+      <AND_CHECK_TENANT("")>
       limit 1
     )
   ) search_with_idx
@@ -185,14 +185,14 @@ limit 1
 getIdFromKey() ::= <<
     SELECT id
     FROM accounts
-    WHERE external_key = :externalKey <AND_CHECK_TENANT()>;
+    WHERE external_key = :externalKey <AND_CHECK_TENANT("")>;
 >>
 
 getAccountsByParentId() ::= <<
-    select <allTableFields()>
+    select <allTableFields("")>
     from accounts
     where parent_account_id = :parentAccountId
-    <AND_CHECK_TENANT()>
-    <defaultOrderBy()>
+    <AND_CHECK_TENANT("")>
+    <defaultOrderBy("")>
     ;
 >>

beatrix/pom.xml 8(+4 -4)

diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index 2a3f84e..8efa8f2 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -115,10 +115,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-account</artifactId>
             <type>test-jar</type>
@@ -299,6 +295,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-jdbi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.commons</groupId>
             <artifactId>killbill-queue</artifactId>
         </dependency>
         <dependency>

catalog/pom.xml 4(+0 -4)

diff --git a/catalog/pom.xml b/catalog/pom.xml
index 62c6c12..ae8e7f6 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -76,10 +76,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-api</artifactId>
         </dependency>
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java
index 87061c9..5b3b633 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.java
@@ -22,7 +22,7 @@ import java.util.List;
 
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
@@ -30,7 +30,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface CatalogOverridePhaseDefinitionSqlDao extends Transactional<CatalogOverridePhaseDefinitionSqlDao>, CloseMe {
 
     @SqlUpdate
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.java
index 8570039..47ac60c 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.java
@@ -19,7 +19,7 @@ package org.killbill.billing.catalog.dao;
 
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
@@ -27,7 +27,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface CatalogOverridePlanDefinitionSqlDao extends Transactional<CatalogOverridePlanDefinitionSqlDao>, CloseMe {
 
     @SqlUpdate
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.java b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.java
index 3993ddf..ae7d936 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -21,15 +21,16 @@ import java.util.Collection;
 
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
 import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.unstable.BindIn;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface CatalogOverridePlanPhaseSqlDao extends Transactional<CatalogOverridePlanPhaseSqlDao>, CloseMe {
 
     @SqlUpdate
@@ -41,7 +42,7 @@ public interface CatalogOverridePlanPhaseSqlDao extends Transactional<CatalogOve
                                                           @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    public Long getTargetPlanDefinition(@PlanPhaseKeysCollectionBinder final Collection<String> concatPhaseNumAndPhaseDefRecordId,
+    public Long getTargetPlanDefinition(@BindIn("keys") final Collection<String> concatPhaseNumAndPhaseDefRecordId,
                                         @Bind("targetCount") final Integer targetCount,
                                         @SmartBindBean final InternalTenantContext context);
 
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.sql.stg
index e51ae47..7e987c9 100644
--- a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.sql.stg
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePhaseDefinitionSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group CatalogOverridePhaseDefinitionSqlDao;
-
 tableName() ::= "catalog_override_phase_definition"
 
 
@@ -39,7 +37,7 @@ allTableValues() ::= <<
 
 create() ::= <<
 insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
 )
 values (
 <tableValues()>
@@ -48,7 +46,7 @@ values (
 >>
 
 getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where record_id = :recordId
 and tenant_record_id = :tenantRecordId
@@ -56,7 +54,7 @@ and tenant_record_id = :tenantRecordId
 >>
 
 getByAttributes() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where parent_phase_name = :parentPhaseName
 and currency = :currency
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.sql.stg
index 3024bc0..b9ae158 100644
--- a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.sql.stg
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanDefinitionSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group CatalogOverridePlanDefinitionSqlDao;
-
 tableName() ::= "catalog_override_plan_definition"
 
 tableFields(prefix) ::= <<
@@ -34,7 +32,7 @@ allTableValues() ::= <<
 
 create() ::= <<
 insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
 )
 values (
 <tableValues()>
@@ -43,7 +41,7 @@ values (
 >>
 
 getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where record_id = :recordId
 and tenant_record_id = :tenantRecordId
diff --git a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.sql.stg b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.sql.stg
index be35a86..ba61278 100644
--- a/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.sql.stg
+++ b/catalog/src/main/resources/org/killbill/billing/catalog/dao/CatalogOverridePlanPhaseSqlDao.sql.stg
@@ -1,6 +1,3 @@
-group CatalogOverridePlanPhaseSqlDao;
-
-
 tableName() ::= "catalog_override_plan_phase"
 
 
@@ -36,7 +33,7 @@ allTableValues() ::= <<
 
 create() ::= <<
 insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
 )
 values (
 <tableValues()>
@@ -45,7 +42,7 @@ values (
 >>
 
 getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from
 <tableName()>
 where record_id = :recordId
@@ -62,7 +59,7 @@ from (select
       from
       <tableName()>
       where
-      concat_ws(',', phase_number, phase_def_record_id) in (<keys: {key | :key_<i0>}; separator="," >)
+      concat_ws(',', phase_number, phase_def_record_id) in (<keys>)
       and tenant_record_id = :tenantRecordId
       group by target_plan_def_record_id) tmp
 where
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 61ad861..943e067 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -75,7 +75,7 @@
         </dependency>
         <dependency>
             <groupId>org.antlr</groupId>
-            <artifactId>stringtemplate</artifactId>
+            <artifactId>ST4</artifactId>
             <scope>runtime</scope>
         </dependency>
         <dependency>
@@ -88,10 +88,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-account</artifactId>
         </dependency>
@@ -185,6 +181,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-jdbi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.commons</groupId>
             <artifactId>killbill-queue</artifactId>
         </dependency>
         <dependency>
diff --git a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.java b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.java
index 95024c3..344a645 100644
--- a/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.java
+++ b/entitlement/src/main/java/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.java
@@ -28,33 +28,33 @@ import org.killbill.billing.entitlement.api.BlockingState;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface BlockingStateSqlDao extends EntitySqlDao<BlockingStateModelDao, BlockingState> {
 
     @SqlQuery
     public abstract BlockingStateModelDao getBlockingStateForService(@Bind("blockableId") UUID blockableId,
                                                                      @Bind("service") String serviceName,
                                                                      @Bind("effectiveDate") Date effectiveDate,
-                                                                     @BindBean final InternalTenantContext context);
+                                                                     @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public abstract List<BlockingStateModelDao> getBlockingState(@Bind("blockableId") UUID blockableId,
                                                                  @Bind("effectiveDate") Date effectiveDate,
-                                                                 @BindBean final InternalTenantContext context);
+                                                                 @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public abstract List<BlockingStateModelDao> getBlockingHistoryForService(@Bind("blockableId") UUID blockableId,
                                                                              @Bind("service") String serviceName,
-                                                                             @BindBean final InternalTenantContext context);
+                                                                             @SmartBindBean final InternalTenantContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     public void unactiveEvent(@Bind("id") String id,
-                              @BindBean final InternalCallContext context);
+                              @SmartBindBean final InternalCallContext context);
 }
diff --git a/entitlement/src/main/resources/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.sql.stg b/entitlement/src/main/resources/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.sql.stg
index feeee40..9d78819 100644
--- a/entitlement/src/main/resources/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.sql.stg
+++ b/entitlement/src/main/resources/org/killbill/billing/entitlement/dao/BlockingStateSqlDao.sql.stg
@@ -1,5 +1,4 @@
-group BlockingStateSqlDao: EntitySqlDao;
-
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "blocking_states"
 
@@ -45,14 +44,14 @@ tableValues() ::= <<
 
 getBlockingStateForService() ::= <<
 select
-<allTableFields()>
+<allTableFields("")>
 from
 <tableName()>
 where blockable_id = :blockableId
 and service = :service
 and effective_date \<= :effectiveDate
 and is_active
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 -- We want the current state, hence the order desc and limit 1
 order by effective_date desc, record_id desc
 limit 1
@@ -71,7 +70,7 @@ getBlockingState() ::= <<
          where blockable_id = :blockableId
          and effective_date \<= :effectiveDate
          and is_active
-         <AND_CHECK_TENANT()>
+         <AND_CHECK_TENANT("")>
          group by service
  ) tmp
  on t.record_id = tmp.record_id
@@ -81,14 +80,14 @@ getBlockingState() ::= <<
 
 getBlockingHistoryForService() ::= <<
 select
-<allTableFields()>
+<allTableFields("")>
 from
 <tableName()>
 where blockable_id = :blockableId
 and service = :service
 and is_active
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
@@ -97,6 +96,6 @@ update
 <tableName()>
 set is_active = false
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>

invoice/pom.xml 10(+5 -5)

diff --git a/invoice/pom.xml b/invoice/pom.xml
index e57f88a..36df3a0 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -80,7 +80,7 @@
         </dependency>
         <dependency>
             <groupId>org.antlr</groupId>
-            <artifactId>stringtemplate</artifactId>
+            <artifactId>ST4</artifactId>
             <scope>runtime</scope>
         </dependency>
         <dependency>
@@ -89,10 +89,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.joda</groupId>
             <artifactId>joda-money</artifactId>
         </dependency>
@@ -191,6 +187,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-jdbi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.commons</groupId>
             <artifactId>killbill-locker</artifactId>
         </dependency>
         <dependency>
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java
index 8c7ded7..7a864d9 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java
@@ -27,38 +27,38 @@ import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface InvoiceItemSqlDao extends EntitySqlDao<InvoiceItemModelDao, InvoiceItem> {
 
     @SqlQuery
     List<InvoiceItemModelDao> getInvoiceItemsByInvoice(@Bind("invoiceId") final String invoiceId,
-                                                       @BindBean final InternalTenantContext context);
+                                                       @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     List<InvoiceItemModelDao> getInvoiceItemsBySubscription(@Bind("subscriptionId") final String subscriptionId,
-                                                            @BindBean final InternalTenantContext context);
+                                                            @SmartBindBean final InternalTenantContext context);
 
 
     @SqlQuery
     List<InvoiceItemModelDao> getAdjustedOrRepairedInvoiceItemsByLinkedId(@Bind("linkedItemId") final String linkedItemId,
-                                                            @BindBean final InternalTenantContext context);
+                                                            @SmartBindBean final InternalTenantContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     void updateAmount(@Bind("id") String invoiceItemId,
                       @Bind("amount")BigDecimal amount,
-                      @BindBean final InternalCallContext context);
+                      @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     List<InvoiceItemModelDao> getInvoiceItemsByParentInvoice(@Bind("parentInvoiceId") final String parentInvoiceId,
-                                                             @BindBean final InternalTenantContext context);
+                                                             @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    BigDecimal getAccountCBA(@BindBean final InternalTenantContext context);
+    BigDecimal getAccountCBA(@SmartBindBean final InternalTenantContext context);
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.java
index 2973f53..dbaa0a9 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -19,27 +19,26 @@ package org.killbill.billing.invoice.dao;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.UUID;
 
 import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.invoice.api.InvoiceParentChild;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
-import org.killbill.billing.util.tag.dao.UUIDCollectionBinder;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.unstable.BindIn;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface InvoiceParentChildrenSqlDao extends EntitySqlDao<InvoiceParentChildModelDao, InvoiceParentChild> {
 
     @SqlQuery
     List<InvoiceParentChildModelDao> getChildInvoicesByParentInvoiceId(@Bind("parentInvoiceId") final String parentInvoiceId,
-                                                                       @BindBean final InternalTenantContext context);
+                                                                       @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    List<InvoiceParentChildModelDao> getParentChildMappingsByChildInvoiceIds(@UUIDCollectionBinder final Collection<String> childInvoiceIds,
-                                                                             @BindBean final InternalTenantContext context);
+    List<InvoiceParentChildModelDao> getParentChildMappingsByChildInvoiceIds(@BindIn("ids") final Collection<String> childInvoiceIds,
+                                                                             @SmartBindBean final InternalTenantContext context);
 
 }
 
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java
index d763bd1..994eb58 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.java
@@ -27,47 +27,47 @@ import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.api.InvoicePayment;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface InvoicePaymentSqlDao extends EntitySqlDao<InvoicePaymentModelDao, InvoicePayment> {
 
 
     @SqlQuery
     public List<InvoicePaymentModelDao> getByPaymentId(@Bind("paymentId") final String paymentId,
-                                                       @BindBean final InternalTenantContext context);
+                                                       @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public List<InvoicePaymentModelDao> getAllPaymentsForInvoiceIncludedInit(@Bind("invoiceId") final String invoiceId,
-                                                              @BindBean final InternalTenantContext context);
+                                                              @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     List<InvoicePaymentModelDao> getInvoicePayments(@Bind("paymentId") final String paymentId,
-                                                    @BindBean final InternalTenantContext context);
+                                                    @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     InvoicePaymentModelDao getPaymentForCookieId(@Bind("paymentCookieId") final String paymentCookieId,
-                                                 @BindBean final InternalTenantContext context);
+                                                 @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     BigDecimal getRemainingAmountPaid(@Bind("invoicePaymentId") final String invoicePaymentId,
-                                      @BindBean final InternalTenantContext context);
+                                      @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     UUID getAccountIdFromInvoicePaymentId(@Bind("invoicePaymentId") final String invoicePaymentId,
-                                          @BindBean final InternalTenantContext context);
+                                          @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     List<InvoicePaymentModelDao> getChargeBacksByAccountId(@Bind("accountId") final String accountId,
-                                                           @BindBean final InternalTenantContext context);
+                                                           @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     List<InvoicePaymentModelDao> getChargebacksByPaymentId(@Bind("paymentId") final String paymentId,
-                                                           @BindBean final InternalTenantContext context);
+                                                           @SmartBindBean final InternalTenantContext context);
 
     @SqlUpdate
     void updateAttempt(@Bind("recordId") Long recordId,
@@ -79,5 +79,5 @@ public interface InvoicePaymentSqlDao extends EntitySqlDao<InvoicePaymentModelDa
                        @Bind("paymentCookieId") final String paymentCookieId,
                        @Bind("linkedInvoicePaymentId") final String linkedInvoicePaymentId,
                        @Bind("success") final boolean success,
-                       @BindBean final InternalTenantContext context);
+                       @SmartBindBean final InternalTenantContext context);
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
index 9ed8f28..6d405b0 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceSqlDao.java
@@ -28,36 +28,36 @@ import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
-import org.killbill.billing.util.tag.dao.UUIDCollectionBinder;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.unstable.BindIn;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface InvoiceSqlDao extends EntitySqlDao<InvoiceModelDao, Invoice> {
 
     @SqlQuery
     List<InvoiceModelDao> getInvoicesBySubscription(@Bind("subscriptionId") final String subscriptionId,
-                                                    @BindBean final InternalTenantContext context);
+                                                    @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     UUID getInvoiceIdByPaymentId(@Bind("paymentId") final String paymentId,
-                                 @BindBean final InternalTenantContext context);
+                                 @SmartBindBean final InternalTenantContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     void updateStatus(@Bind("id") String invoiceId,
                       @Bind("status") String status,
-                      @BindBean final InternalCallContext context);
+                      @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     InvoiceModelDao getParentDraftInvoice(@Bind("accountId") final String parentAccountId,
-                                          @BindBean final InternalTenantContext context);
+                                          @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    List<InvoiceModelDao> getByIds(@UUIDCollectionBinder final Collection<String> invoiceIds,
-                                   @BindBean final InternalTenantContext context);
+    List<InvoiceModelDao> getByIds(@BindIn("ids") final Collection<String> invoiceIds,
+                                   @SmartBindBean final InternalTenantContext context);
 }
 
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
index c99d95c..c7596b4 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group InvoiceItemSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "invoice_items"
 
@@ -46,27 +46,27 @@ tableValues() ::= <<
 
 
 getInvoiceItemsByInvoice() ::= <<
-  SELECT <allTableFields()>
+  SELECT <allTableFields("")>
   FROM <tableName()>
   WHERE invoice_id = :invoiceId
-  <AND_CHECK_TENANT()>
+  <AND_CHECK_TENANT("")>
   ;
 >>
 
 getInvoiceItemsBySubscription() ::= <<
-  SELECT <allTableFields()>
+  SELECT <allTableFields("")>
   FROM <tableName()>
   WHERE subscription_id = :subscriptionId
-  <AND_CHECK_TENANT()>
+  <AND_CHECK_TENANT("")>
   ;
 >>
 
 getAdjustedOrRepairedInvoiceItemsByLinkedId() ::= <<
-  SELECT <allTableFields()>
+  SELECT <allTableFields("")>
   FROM <tableName()>
   WHERE linked_item_id = :linkedItemId
   AND type IN ('ITEM_ADJ', 'REPAIR_ADJ')
-  <AND_CHECK_TENANT()>
+  <AND_CHECK_TENANT("")>
   ;
 >>
 
@@ -74,7 +74,7 @@ updateAmount() ::= <<
     UPDATE <tableName()>
     SET amount = :amount
     WHERE id = :id
-    <AND_CHECK_TENANT()>;
+    <AND_CHECK_TENANT("")>;
 >>
 
 getInvoiceItemsByParentInvoice() ::= <<
@@ -83,7 +83,7 @@ getInvoiceItemsByParentInvoice() ::= <<
   INNER JOIN invoice_parent_children invRel ON invRel.child_invoice_id = items.invoice_id
   WHERE invRel.parent_invoice_id = :parentInvoiceId
   <AND_CHECK_TENANT("items.")>
-  <defaultOrderBy()>
+  <defaultOrderBy("")>
   ;
 >>
 
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.sql.stg
index 2a96b7a..93cd6e9 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceParentChildrenSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group InvoiceParentChildrenSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "invoice_parent_children"
 
@@ -29,17 +29,17 @@ allTableValues() ::= <<
 >>
 
 getChildInvoicesByParentInvoiceId() ::= <<
-   SELECT <allTableFields()>
+   SELECT <allTableFields("")>
    FROM <tableName()>
    WHERE parent_invoice_id = :parentInvoiceId
-   <AND_CHECK_TENANT()>
-   <defaultOrderBy()>
+   <AND_CHECK_TENANT("")>
+   <defaultOrderBy("")>
  >>
 
 getParentChildMappingsByChildInvoiceIds(ids) ::= <<
-   SELECT <allTableFields()>
+   SELECT <allTableFields("")>
    FROM <tableName()>
-   WHERE child_invoice_id in (<ids: {id | :id_<i0>}; separator="," >)
-   <AND_CHECK_TENANT()>
-   <defaultOrderBy()>
+   WHERE child_invoice_id in (<ids>)
+   <AND_CHECK_TENANT("")>
+   <defaultOrderBy("")>
  >>
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
index 7fb6bb6..140ff05 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group InvoicePayment: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "invoice_payments"
 
@@ -45,41 +45,41 @@ AND payment_id IS NOT NULL
 >>
 
 getByPaymentId() ::= <<
-  SELECT <allTableFields()>
+  SELECT <allTableFields("")>
   FROM <tableName()>
   WHERE payment_id = :paymentId
-  <AND_CHECK_TENANT()>
-  <defaultOrderBy()>
+  <AND_CHECK_TENANT("")>
+  <defaultOrderBy("")>
   ;
 >>
 
 getPaymentForCookieId() ::= <<
-  SELECT <allTableFields()>
+  SELECT <allTableFields("")>
   FROM <tableName()>
   WHERE payment_cookie_id = :paymentCookieId
-  <AND_CHECK_TENANT()>
-  <defaultOrderBy()>
+  <AND_CHECK_TENANT("")>
+  <defaultOrderBy("")>
   LIMIT 1
   ;
 >>
 
 getAllPaymentsForInvoiceIncludedInit() ::= <<
-  SELECT <allTableFields()>
+  SELECT <allTableFields("")>
   FROM <tableName()>
   WHERE invoice_id = :invoiceId
-  <AND_CHECK_TENANT()>
-  <defaultOrderBy()>
+  <AND_CHECK_TENANT("")>
+  <defaultOrderBy("")>
   ;
 >>
 
 
 
 getInvoicePayments() ::= <<
-    SELECT <allTableFields()>
+    SELECT <allTableFields("")>
     FROM <tableName()>
     WHERE payment_id = :paymentId
-    <AND_CHECK_TENANT()>
-    <defaultOrderBy()>
+    <AND_CHECK_TENANT("")>
+    <defaultOrderBy("")>
     ;
 >>
 
@@ -88,7 +88,7 @@ getRemainingAmountPaid() ::= <<
     FROM <tableName()>
     WHERE (id = :invoicePaymentId OR linked_invoice_payment_id = :invoicePaymentId)
     AND success
-    <AND_CHECK_TENANT()>
+    <AND_CHECK_TENANT("")>
     ;
 >>
 
@@ -114,12 +114,12 @@ getChargeBacksByAccountId() ::= <<
 >>
 
 getChargebacksByPaymentId() ::= <<
-    SELECT <allTableFields()>
+    SELECT <allTableFields("")>
     FROM <tableName()>
     WHERE type = 'CHARGED_BACK'
     AND linked_invoice_payment_id IN (SELECT id FROM invoice_payments WHERE payment_id = :paymentId)
     AND success
-    <AND_CHECK_TENANT()>
+    <AND_CHECK_TENANT("")>
     ;
 >>
 
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
index 812767f..ab962d9 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group InvoiceDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "invoices"
 
@@ -59,23 +59,23 @@ updateStatus() ::= <<
     UPDATE <tableName()>
     SET status = :status
     WHERE id = :id
-    <AND_CHECK_TENANT()>;
+    <AND_CHECK_TENANT("")>;
 >>
 
 getParentDraftInvoice() ::= <<
-  SELECT <allTableFields()>
+  SELECT <allTableFields("")>
     FROM <tableName()>
    WHERE account_id = :accountId
      AND status = 'DRAFT'
-   <AND_CHECK_TENANT()>
-   <defaultOrderBy()>
+   <AND_CHECK_TENANT("")>
+   <defaultOrderBy("")>
 >>
 
 getByIds(ids) ::= <<
 select
   <allTableFields("t.")>
 from <tableName()> t
-where <idField("t.")> in (<ids: {id | :id_<i0>}; separator="," >)
+where <idField("t.")> in (<ids>)
 <AND_CHECK_TENANT("t.")>
 ;
 >>

overdue/pom.xml 8(+4 -4)

diff --git a/overdue/pom.xml b/overdue/pom.xml
index 74d69c5..9afaee4 100644
--- a/overdue/pom.xml
+++ b/overdue/pom.xml
@@ -83,10 +83,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-api</artifactId>
         </dependency>
@@ -162,6 +158,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-jdbi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.commons</groupId>
             <artifactId>killbill-locker</artifactId>
         </dependency>
         <dependency>

payment/pom.xml 4(+0 -4)

diff --git a/payment/pom.xml b/payment/pom.xml
index 3bddc1f..6c012f7 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -101,10 +101,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-account</artifactId>
             <scope>test</scope>
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.java
index cbbbc66..5ef0bb6 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.java
@@ -28,14 +28,14 @@ import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.Entity;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.Define;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface PaymentAttemptSqlDao extends EntitySqlDao<PaymentAttemptModelDao, Entity> {
 
     @SqlUpdate
@@ -43,7 +43,7 @@ public interface PaymentAttemptSqlDao extends EntitySqlDao<PaymentAttemptModelDa
     void updateAttempt(@Bind("id") final String attemptId,
                        @Bind("transactionId") final String transactionId,
                        @Bind("stateName") final String stateName,
-                       @BindBean final InternalCallContext context);
+                       @SmartBindBean final InternalCallContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
@@ -52,15 +52,15 @@ public interface PaymentAttemptSqlDao extends EntitySqlDao<PaymentAttemptModelDa
                                      @Bind("transactionId") final String transactionId,
                                      @Bind("stateName") final String stateName,
                                      @Bind("pluginProperties") final byte[] pluginProperties,
-                                     @BindBean final InternalCallContext context);
+                                     @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     List<PaymentAttemptModelDao> getByTransactionExternalKey(@Bind("transactionExternalKey") final String transactionExternalKey,
-                                                             @BindBean final InternalTenantContext context);
+                                                             @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     List<PaymentAttemptModelDao> getByPaymentExternalKey(@Bind("paymentExternalKey") final String paymentExternalKey,
-                                                         @BindBean final InternalTenantContext context);
+                                                         @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     Long getCountByStateNameAcrossTenants(@Bind("stateName") final String stateName,
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java
index da14f3e..5512781 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java
@@ -22,7 +22,7 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
@@ -33,37 +33,37 @@ import org.killbill.billing.payment.api.PaymentMethod;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.customizers.Define;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface PaymentMethodSqlDao extends EntitySqlDao<PaymentMethodModelDao, PaymentMethod> {
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     void markPaymentMethodAsDeleted(@Bind("id") final String paymentMethodId,
-                                    @BindBean final InternalCallContext context);
+                                    @SmartBindBean final InternalCallContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     void unmarkPaymentMethodAsDeleted(@Bind("id") final String paymentMethodId,
-                                      @BindBean final InternalCallContext context);
+                                      @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
-    PaymentMethodModelDao getByExternalKey(@Bind("externalKey") String paymentMethodExternalKey, @BindBean InternalTenantContext context);
+    PaymentMethodModelDao getByExternalKey(@Bind("externalKey") String paymentMethodExternalKey, @SmartBindBean InternalTenantContext context);
 
     @SqlQuery
-    PaymentMethodModelDao getPaymentMethodByExternalKeyIncludedDeleted(@Bind("externalKey") String paymentMethodExternalKey, @BindBean InternalTenantContext context);
+    PaymentMethodModelDao getPaymentMethodByExternalKeyIncludedDeleted(@Bind("externalKey") String paymentMethodExternalKey, @SmartBindBean InternalTenantContext context);
 
     @SqlQuery
     PaymentMethodModelDao getPaymentMethodIncludedDelete(@Bind("id") final String paymentMethodId,
-                                                         @BindBean final InternalTenantContext context);
+                                                         @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    List<PaymentMethodModelDao> getForAccount(@BindBean final InternalTenantContext context);
+    List<PaymentMethodModelDao> getForAccount(@SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    List<PaymentMethodModelDao> getForAccountIncludedDelete(@BindBean final InternalTenantContext context);
+    List<PaymentMethodModelDao> getForAccountIncludedDelete(@SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     @SmartFetchSize(shouldStream = true)
@@ -71,10 +71,10 @@ public interface PaymentMethodSqlDao extends EntitySqlDao<PaymentMethodModelDao,
                                                            @Bind("offset") final Long offset,
                                                            @Bind("rowCount") final Long rowCount,
                                                            @Define("ordering") final String ordering,
-                                                           @BindBean final InternalTenantContext context);
+                                                           @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public Long getCountByPluginName(@Bind("pluginName") final String pluginName,
-                                     @BindBean final InternalTenantContext context);
+                                     @SmartBindBean final InternalTenantContext context);
 
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java
index ee8ad0f..e932660 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java
@@ -1,7 +1,8 @@
 /*
- * Copyright 2014 Groupon, Inc
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
- * Groupon licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
  * License.  You may obtain a copy of the License at:
  *
@@ -27,56 +28,57 @@ import org.killbill.billing.payment.api.Payment;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.killbill.commons.jdbi.statement.SmartFetchSize;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.Define;
+import org.skife.jdbi.v2.unstable.BindIn;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface PaymentSqlDao extends EntitySqlDao<PaymentModelDao, Payment> {
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     void updatePaymentForNewTransaction(@Bind("id") final String paymentId,
-                                        @BindBean final InternalCallContext context);
+                                        @SmartBindBean final InternalCallContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     Object updatePaymentStateName(@Bind("id") final String paymentId,
                                   @Bind("stateName") final String stateName,
-                                  @BindBean final InternalCallContext context);
+                                  @SmartBindBean final InternalCallContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     Object updateLastSuccessPaymentStateName(@Bind("id") final String paymentId,
                                              @Bind("stateName") final String stateName,
                                              @Bind("lastSuccessStateName") final String lastSuccessStateName,
-                                             @BindBean final InternalCallContext context);
+                                             @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     public PaymentModelDao getPaymentByExternalKey(@Bind("externalKey") final String externalKey,
-                                                   @BindBean final InternalTenantContext context);
+                                                   @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    public List<PaymentModelDao> getPaymentsByStatesAcrossTenants(@StateCollectionBinder final Collection<String> states,
+    public List<PaymentModelDao> getPaymentsByStatesAcrossTenants(@BindIn("states") final Collection<String> states,
                                                                   @Bind("createdBeforeDate") final Date createdBeforeDate,
                                                                   @Bind("createdAfterDate") final Date createdAfterDate,
                                                                   @Bind("limit") final int limit);
 
     @SqlQuery
     @SmartFetchSize(shouldStream = true)
-    public Iterator<PaymentModelDao> searchByState(@PaymentStateCollectionBinder final Collection<String> paymentStates,
+    public Iterator<PaymentModelDao> searchByState(@BindIn("states") final Collection<String> paymentStates,
                                                    @Bind("offset") final Long offset,
                                                    @Bind("rowCount") final Long rowCount,
                                                    @Define("ordering") final String ordering,
-                                                   @BindBean final InternalTenantContext context);
+                                                   @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    public Long getSearchByStateCount(@PaymentStateCollectionBinder final Collection<String> paymentStates,
-                                      @BindBean final InternalTenantContext context);
+    public Long getSearchByStateCount(@BindIn("states") final Collection<String> paymentStates,
+                                      @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     @SmartFetchSize(shouldStream = true)
@@ -84,9 +86,9 @@ public interface PaymentSqlDao extends EntitySqlDao<PaymentModelDao, Payment> {
                                                      @Bind("offset") final Long offset,
                                                      @Bind("rowCount") final Long rowCount,
                                                      @Define("ordering") final String ordering,
-                                                     @BindBean final InternalTenantContext context);
+                                                     @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public Long getCountByPluginName(@Bind("pluginName") final String pluginName,
-                                     @BindBean final InternalTenantContext context);
+                                     @SmartBindBean final InternalTenantContext context);
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/TransactionSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/TransactionSqlDao.java
index ba8b739..b6666b7 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/TransactionSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/TransactionSqlDao.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -30,14 +30,15 @@ import org.killbill.billing.payment.api.PaymentTransaction;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.Define;
+import org.skife.jdbi.v2.unstable.BindIn;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface TransactionSqlDao extends EntitySqlDao<PaymentTransactionModelDao, PaymentTransaction> {
 
     @SqlUpdate
@@ -49,19 +50,19 @@ public interface TransactionSqlDao extends EntitySqlDao<PaymentTransactionModelD
                                    @Bind("transactionStatus") final String transactionStatus,
                                    @Bind("gatewayErrorCode") final String gatewayErrorCode,
                                    @Bind("gatewayErrorMsg") final String gatewayErrorMsg,
-                                   @BindBean final InternalCallContext context);
+                                   @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     List<PaymentTransactionModelDao> getPaymentTransactionsByExternalKey(@Bind("transactionExternalKey") final String transactionExternalKey,
-                                                                         @BindBean final InternalTenantContext context);
+                                                                         @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    Long getCountByTransactionStatusPriorDateAcrossTenants(@TransactionStatusCollectionBinder final Collection<String> statuses,
+    Long getCountByTransactionStatusPriorDateAcrossTenants(@BindIn("statuses") final Collection<String> statuses,
                                                            @Bind("createdBeforeDate") final Date createdBeforeDate,
                                                            @Bind("createdAfterDate") final Date createdAfterDate);
 
     @SqlQuery
-    Iterator<PaymentTransactionModelDao> getByTransactionStatusPriorDateAcrossTenants(@TransactionStatusCollectionBinder final Collection<String> statuses,
+    Iterator<PaymentTransactionModelDao> getByTransactionStatusPriorDateAcrossTenants(@BindIn("statuses") final Collection<String> statuses,
                                                                                       @Bind("createdBeforeDate") final Date createdBeforeDate,
                                                                                       @Bind("createdAfterDate") final Date createdAfterDate,
                                                                                       @Bind("offset") final Long offset,
@@ -70,7 +71,7 @@ public interface TransactionSqlDao extends EntitySqlDao<PaymentTransactionModelD
 
     @SqlQuery
     public List<PaymentTransactionModelDao> getByPaymentId(@Bind("paymentId") final UUID paymentId,
-                                                           @BindBean final InternalTenantContext context);
+                                                           @SmartBindBean final InternalTenantContext context);
 }
 
 
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
index ebde91c..39dad12 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group PaymentAttemptSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "payment_attempts"
 
@@ -49,7 +49,7 @@ from <tableName()>
 where transaction_external_key = :transactionExternalKey
 <andCheckSoftDeletionWithComma("")>
 <AND_CHECK_TENANT("")>
-<defaultOrderBy()>
+<defaultOrderBy("")>
 ;
 >>
 
@@ -59,8 +59,8 @@ select
 from <tableName()>
 where payment_external_key = :paymentExternalKey
 <andCheckSoftDeletionWithComma("")>
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
@@ -72,7 +72,7 @@ from <tableName()>
 where state_name = :stateName
 and created_date \< :createdBeforeDate
 <andCheckSoftDeletionWithComma("")>
-order by <recordIdField()> <ordering>
+order by <recordIdField("")> <ordering>
 limit :rowCount offset :offset
 ;
 >>
@@ -95,7 +95,7 @@ set state_name = :stateName
 , updated_by = :updatedBy
 , updated_date = :updatedDate
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
@@ -108,7 +108,7 @@ set state_name = :stateName
 , updated_by = :updatedBy
 , updated_date = :updatedDate
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg
index 67c65f1..a26b7dd 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg
@@ -1,6 +1,4 @@
-group PaymentMethodSqlDao: EntitySqlDao;
-
-
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "payment_methods"
 
@@ -36,7 +34,7 @@ set is_active = false
 , updated_by = :updatedBy
 , updated_date = :updatedDate
 where  id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
@@ -46,51 +44,51 @@ set is_active = true
 , updated_by = :updatedBy
 , updated_date = :updatedDate
 where  id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
 getByExternalKey() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where external_key = :externalKey
-<andCheckSoftDeletionWithComma()>
-<AND_CHECK_TENANT()>
+<andCheckSoftDeletionWithComma("")>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
 getPaymentMethodByExternalKeyIncludedDeleted() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where external_key = :externalKey
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
 getPaymentMethodIncludedDelete(accountId) ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
 getForAccount() ::= <<
 select
-<allTableFields()>
+<allTableFields("")>
 from <tableName()>
-where <accountRecordIdField()> = :accountRecordId
-<andCheckSoftDeletionWithComma()>
-<AND_CHECK_TENANT()>
+where <accountRecordIdField("")> = :accountRecordId
+<andCheckSoftDeletionWithComma("")>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
 getForAccountIncludedDelete() ::= <<
 select
-<allTableFields()>
+<allTableFields("")>
 from <tableName()>
-where <accountRecordIdField()> = :accountRecordId
-<AND_CHECK_TENANT()>
+where <accountRecordIdField("")> = :accountRecordId
+<AND_CHECK_TENANT("")>
 ;
 >>
 
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg
index b15a04b..395dfae 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group PaymentSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "payments"
 
@@ -41,7 +41,7 @@ update <tableName()>
 set updated_by = :updatedBy
 , updated_date = :updatedDate
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
@@ -51,7 +51,7 @@ set state_name = :stateName
 , updated_by = :updatedBy
 , updated_date = :updatedDate
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
@@ -62,7 +62,7 @@ set state_name = :stateName
 , updated_by = :updatedBy
 , updated_date = :updatedDate
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
@@ -71,7 +71,7 @@ select
 <allTableFields("")>
 from <tableName()>
 where external_key = :externalKey
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
@@ -87,12 +87,12 @@ select
 <allTableFields("t.")>
 from <tableName()> t
 join (
-  select <recordIdField()>
+  select <recordIdField("")>
   from <tableName()>
-  where state_name in (<states: {state | :state_<i0>}; separator="," >)
-  <AND_CHECK_TENANT()>
-  <andCheckSoftDeletionWithComma()>
-  order by <recordIdField()> <ordering>
+  where state_name in (<states>)
+  <AND_CHECK_TENANT("")>
+  <andCheckSoftDeletionWithComma("")>
+  order by <recordIdField("")> <ordering>
   limit :rowCount offset :offset
 ) optimization on <recordIdField("optimization.")> = <recordIdField("t.")>
 order by <recordIdField("t.")> <ordering>
@@ -103,7 +103,7 @@ getSearchByStateCount(states) ::= <<
 select
   count(1) as count
 from <tableName()> t
-where t.state_name in (<states: {state | :state_<i0>}; separator="," >)
+where t.state_name in (<states>)
 <andCheckSoftDeletionWithComma("t.")>
 <AND_CHECK_TENANT("t.")>
 ;
@@ -138,7 +138,7 @@ from <tableName()> t
 where
 created_date >= :createdAfterDate
 and created_date \< :createdBeforeDate
-and state_name in (<states: {state | :state_<i0>}; separator="," >)
+and state_name in (<states>)
 limit :limit
 ;
 >>
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/TransactionSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/TransactionSqlDao.sql.stg
index 1f19f0b..cbdc740 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/TransactionSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/TransactionSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TransactionSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "payment_transactions"
 
@@ -51,8 +51,8 @@ select
 <allTableFields("")>
 from <tableName()>
 where transaction_external_key = :transactionExternalKey
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
@@ -68,29 +68,29 @@ set transaction_status = :transactionStatus
 , updated_by = :updatedBy
 , updated_date = :updatedDate
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
 getByPaymentId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where payment_id = :paymentId
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
 
 /* Does not include AND_CHECK_TENANT() since this is a global operation */
 getByTransactionStatusPriorDateAcrossTenants(statuses, ordering) ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where
 created_date >= :createdAfterDate
 and created_date \< :createdBeforeDate
-and transaction_status in (<statuses: {status | :status_<i0>}; separator="," >)
-order by <recordIdField()> <ordering>
+and transaction_status in (<statuses>)
+order by <recordIdField("")> <ordering>
 limit :rowCount offset :offset
 ;
 >>
@@ -102,7 +102,7 @@ from <tableName()>
 where
 created_date >= :createdAfterDate
 and created_date \< :createdBeforeDate
-and transaction_status in (<statuses: {status | :status_<i0>}; separator="," >)
+and transaction_status in (<statuses>)
 ;
 >>
 

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index cd1e5c3..69b6a5a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.140.28</version>
+        <version>0.140.32</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.18.9-SNAPSHOT</version>
diff --git a/profiles/killbill/pom.xml b/profiles/killbill/pom.xml
index 8546b92..72163e6 100644
--- a/profiles/killbill/pom.xml
+++ b/profiles/killbill/pom.xml
@@ -233,10 +233,6 @@
             <scope>runtime</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-account</artifactId>
         </dependency>
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
index ff6de44..d05cc24 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -66,8 +66,6 @@ import org.killbill.billing.subscription.glue.DefaultSubscriptionModule;
 import org.killbill.billing.tenant.glue.DefaultTenantModule;
 import org.killbill.billing.usage.glue.UsageModule;
 import org.killbill.billing.util.config.definition.NotificationConfig;
-import org.killbill.billing.util.dao.AuditLogModelDaoMapper;
-import org.killbill.billing.util.dao.RecordIdIdMappingsMapper;
 import org.killbill.billing.util.email.EmailModule;
 import org.killbill.billing.util.email.templates.TemplateModule;
 import org.killbill.billing.util.glue.AuditModule;
@@ -79,6 +77,7 @@ import org.killbill.billing.util.glue.ConfigModule;
 import org.killbill.billing.util.glue.CustomFieldModule;
 import org.killbill.billing.util.glue.ExportModule;
 import org.killbill.billing.util.glue.GlobalLockerModule;
+import org.killbill.billing.util.glue.IDBISetup;
 import org.killbill.billing.util.glue.KillBillShiroAopModule;
 import org.killbill.billing.util.glue.KillbillApiAopModule;
 import org.killbill.billing.util.glue.NodesModule;
@@ -86,11 +85,9 @@ import org.killbill.billing.util.glue.NonEntityDaoModule;
 import org.killbill.billing.util.glue.RecordIdModule;
 import org.killbill.billing.util.glue.SecurityModule;
 import org.killbill.billing.util.glue.TagStoreModule;
-import org.killbill.billing.util.security.shiro.dao.SessionModelDao;
 import org.killbill.clock.Clock;
 import org.killbill.clock.ClockMock;
 import org.killbill.commons.embeddeddb.EmbeddedDB;
-import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.ResultSetMapperFactory;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
@@ -124,11 +121,14 @@ public class KillbillServerModule extends KillbillPlatformModule {
         super.configureDao();
 
         final Multibinder<ResultSetMapperFactory> resultSetMapperFactorySetBinder = Multibinder.newSetBinder(binder(), ResultSetMapperFactory.class);
-        resultSetMapperFactorySetBinder.addBinding().toInstance(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
+        for (final ResultSetMapperFactory resultSetMapperFactory : IDBISetup.mapperFactoriesToRegister()) {
+            resultSetMapperFactorySetBinder.addBinding().toInstance(resultSetMapperFactory);
+        }
 
         final Multibinder<ResultSetMapper> resultSetMapperSetBinder = Multibinder.newSetBinder(binder(), ResultSetMapper.class);
-        resultSetMapperSetBinder.addBinding().to(AuditLogModelDaoMapper.class).asEagerSingleton();
-        resultSetMapperSetBinder.addBinding().to(RecordIdIdMappingsMapper.class).asEagerSingleton();
+        for (final ResultSetMapper resultSetMapper : IDBISetup.mappersToRegister()) {
+            resultSetMapperSetBinder.addBinding().toInstance(resultSetMapper);
+        }
     }
 
     @Override
diff --git a/subscription/pom.xml b/subscription/pom.xml
index 04ffee7..d35c6a9 100644
--- a/subscription/pom.xml
+++ b/subscription/pom.xml
@@ -75,7 +75,7 @@
         </dependency>
         <dependency>
             <groupId>org.antlr</groupId>
-            <artifactId>stringtemplate</artifactId>
+            <artifactId>ST4</artifactId>
             <scope>runtime</scope>
         </dependency>
         <dependency>
@@ -84,10 +84,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-account</artifactId>
             <scope>test</scope>
@@ -169,6 +165,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-jdbi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.commons</groupId>
             <artifactId>killbill-queue</artifactId>
         </dependency>
         <dependency>
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/BundleSqlDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/BundleSqlDao.java
index 585e013..bc8f9f2 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/BundleSqlDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/BundleSqlDao.java
@@ -20,7 +20,7 @@ import java.util.Date;
 import java.util.List;
 
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
@@ -31,33 +31,33 @@ import org.killbill.billing.subscription.engine.dao.model.SubscriptionBundleMode
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface BundleSqlDao extends EntitySqlDao<SubscriptionBundleModelDao, SubscriptionBaseBundle> {
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     public void updateBundleExternalKey(@Bind("id") String id,
                                         @Bind("externalKey") String externalKey,
-                                        @BindBean final InternalCallContext context);
+                                        @SmartBindBean final InternalCallContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     public void updateBundleLastSysTime(@Bind("id") String id,
                                         @Bind("lastSysUpdateDate") Date lastSysUpdate,
-                                        @BindBean final InternalCallContext context);
+                                        @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     public List<SubscriptionBundleModelDao> getBundlesFromAccountAndKey(@Bind("accountId") String accountId,
                                                                         @Bind("externalKey") String externalKey,
-                                                                        @BindBean final InternalTenantContext context);
+                                                                        @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public List<SubscriptionBundleModelDao> getBundleFromAccount(@Bind("accountId") String accountId,
-                                                                 @BindBean final InternalTenantContext context);
+                                                                 @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public List<SubscriptionBundleModelDao> getBundlesForKey(@Bind("externalKey") String externalKey,
-                                                             @BindBean final InternalTenantContext context);
+                                                             @SmartBindBean final InternalTenantContext context);
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java
index c47d482..0e195db 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.java
@@ -26,34 +26,34 @@ import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface SubscriptionEventSqlDao extends EntitySqlDao<SubscriptionEventModelDao, SubscriptionBaseEvent> {
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     public void unactiveEvent(@Bind("id") String id,
-                              @BindBean final InternalCallContext context);
+                              @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     public List<SubscriptionEventModelDao> getFutureActiveEventForSubscription(@Bind("subscriptionId") String subscriptionId,
                                                                                @Bind("now") Date now,
-                                                                               @BindBean final InternalTenantContext context);
+                                                                               @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public List<SubscriptionEventModelDao> getFutureOrPresentActiveEventForSubscription(@Bind("subscriptionId") String subscriptionId,
                                                                                         @Bind("now") Date now,
-                                                                                        @BindBean final InternalTenantContext context);
+                                                                                        @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public List<SubscriptionEventModelDao> getActiveEventsForSubscription(@Bind("subscriptionId") String subscriptionId,
-                                                                          @BindBean final InternalTenantContext context);
+                                                                          @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    public List<SubscriptionEventModelDao> getFutureActiveEventsForAccount(@Bind("now") Date now, @BindBean final InternalTenantContext context);
+    public List<SubscriptionEventModelDao> getFutureActiveEventsForAccount(@Bind("now") Date now, @SmartBindBean final InternalTenantContext context);
 }
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.java
index b47b5ba..c0c2495 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.java
@@ -20,7 +20,7 @@ import java.util.Date;
 import java.util.List;
 
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
@@ -31,18 +31,18 @@ import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface SubscriptionSqlDao extends EntitySqlDao<SubscriptionModelDao, SubscriptionBase> {
 
     @SqlQuery
     public List<SubscriptionModelDao> getSubscriptionsFromBundleId(@Bind("bundleId") String bundleId,
-                                                                   @BindBean final InternalTenantContext context);
+                                                                   @SmartBindBean final InternalTenantContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     public void updateChargedThroughDate(@Bind("id") String id, @Bind("chargedThroughDate") Date chargedThroughDate,
-                                         @BindBean final InternalCallContext context);
+                                         @SmartBindBean final InternalCallContext context);
 
 }
diff --git a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/BundleSqlDao.sql.stg b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/BundleSqlDao.sql.stg
index 4495409..9a5337c 100644
--- a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/BundleSqlDao.sql.stg
+++ b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/BundleSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group BundleSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "bundles"
 
@@ -32,7 +32,7 @@ last_sys_update_date = :lastSysUpdateDate
 , updated_by = :createdBy
 , updated_date = :updatedDate
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
@@ -43,38 +43,38 @@ external_key = :externalKey
 , updated_by = :createdBy
 , updated_date = :updatedDate
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
 getBundlesForKey() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from bundles
 where
 external_key = :externalKey
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
 getBundlesFromAccountAndKey() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from bundles
 where
 external_key = :externalKey
 and account_id = :accountId
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
 getBundleFromAccount() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from bundles
 where
 account_id = :accountId
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
diff --git a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg
index cfb3ec4..94d407f 100644
--- a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg
+++ b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionEventSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group EventSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "subscription_events"
 
@@ -53,59 +53,59 @@ is_active = false
 , updated_date = :updatedDate
 where
 id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>
 
 getFutureActiveEventForSubscription() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 , record_id as total_ordering
 from <tableName()>
 where
 subscription_id = :subscriptionId
 and is_active = true
 and effective_date > :now
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
 
 getFutureOrPresentActiveEventForSubscription() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 , record_id as total_ordering
 from <tableName()>
 where
 subscription_id = :subscriptionId
 and is_active = true
 and effective_date >= :now
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
 getActiveEventsForSubscription() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 , record_id as total_ordering
 from <tableName()>
 where
 subscription_id = :subscriptionId
 and is_active = true
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
 getFutureActiveEventsForAccount() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 , record_id as total_ordering
 from <tableName()>
 where
 account_record_id = :accountRecordId
 and is_active = true
 and effective_date > :now
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
diff --git a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.sql.stg b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.sql.stg
index 47ae310..3f9388d 100644
--- a/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.sql.stg
+++ b/subscription/src/main/resources/org/killbill/billing/subscription/engine/dao/SubscriptionSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group SubscriptionSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "subscriptions"
 
@@ -31,11 +31,11 @@ tableValues() ::= <<
 
 getSubscriptionsFromBundleId() ::= <<
 select
-<allTableFields()>
+<allTableFields("")>
 from <tableName()>
 where bundle_id = :bundleId
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
@@ -46,6 +46,6 @@ charged_through_date = :chargedThroughDate
 , updated_by = :createdBy
 , updated_date = :updatedDate
 where id = :id
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 ;
 >>

tenant/pom.xml 10(+5 -5)

diff --git a/tenant/pom.xml b/tenant/pom.xml
index ab5a3b0..7103725 100644
--- a/tenant/pom.xml
+++ b/tenant/pom.xml
@@ -74,7 +74,7 @@
         </dependency>
         <dependency>
             <groupId>org.antlr</groupId>
-            <artifactId>stringtemplate</artifactId>
+            <artifactId>ST4</artifactId>
             <scope>runtime</scope>
         </dependency>
         <dependency>
@@ -82,10 +82,6 @@
             <artifactId>shiro-core</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-api</artifactId>
         </dependency>
@@ -150,6 +146,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-jdbi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.commons</groupId>
             <artifactId>killbill-queue</artifactId>
         </dependency>
         <dependency>
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.java
index 1925151..281d07c 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.java
@@ -21,11 +21,11 @@ import java.util.List;
 
 import org.killbill.billing.util.entity.Entity;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface TenantBroadcastSqlDao extends EntitySqlDao<TenantBroadcastModelDao, Entity> {
 
     @SqlQuery
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantKVSqlDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantKVSqlDao.java
index c0cac34..fe99bea 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantKVSqlDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantKVSqlDao.java
@@ -24,32 +24,32 @@ import org.killbill.billing.tenant.api.TenantKV;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface TenantKVSqlDao extends EntitySqlDao<TenantKVModelDao, TenantKV> {
 
     @SqlQuery
     public List<TenantKVModelDao> getTenantValueForKey(@Bind("tenantKey") final String key,
-                                                       @BindBean final InternalTenantContext context);
+                                                       @SmartBindBean final InternalTenantContext context);
 
 
     @SqlQuery
     public List<TenantKVModelDao> searchTenantKeyValues(@Bind("tenantKeyPrefix") final String tenantKeyPrefix,
-                                                       @BindBean final InternalTenantContext context);
+                                                       @SmartBindBean final InternalTenantContext context);
 
     @SqlUpdate
     @Audited(ChangeType.DELETE)
     public void markTenantKeyAsDeleted(@Bind("id")final String id,
-                                       @BindBean final InternalCallContext context);
+                                       @SmartBindBean final InternalCallContext context);
 
     @SqlUpdate
     @Audited(ChangeType.UPDATE)
     public Object updateTenantValueKey(@Bind("id") final String id,
                                        @Bind("tenantValue") final String tenantValue,
-                                       @BindBean final InternalCallContext context);
+                                       @SmartBindBean final InternalCallContext context);
 }
diff --git a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantSqlDao.java b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantSqlDao.java
index cf97271..ab4ded9 100644
--- a/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantSqlDao.java
+++ b/tenant/src/main/java/org/killbill/billing/tenant/dao/TenantSqlDao.java
@@ -24,9 +24,9 @@ import org.skife.jdbi.v2.sqlobject.SqlQuery;
 
 import org.killbill.billing.tenant.api.Tenant;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface TenantSqlDao extends EntitySqlDao<TenantModelDao, Tenant> {
 
     @SqlQuery
diff --git a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.sql.stg b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.sql.stg
index b0e5bc3..b843665 100644
--- a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.sql.stg
+++ b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantBroadcastSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TenantBroadcastSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "tenant_broadcasts"
 
@@ -26,7 +26,7 @@ tableValues() ::= <<
 
 /* No account_record_id field */
 accountRecordIdFieldWithComma(prefix) ::= ""
-accountRecordIdValueWithComma(prefix) ::= ""
+accountRecordIdValueWithComma() ::= ""
 
 
 getLatestEntries() ::= <<
diff --git a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantKVSqlDao.sql.stg b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantKVSqlDao.sql.stg
index 9495969..19cfb11 100644
--- a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantKVSqlDao.sql.stg
+++ b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantKVSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TenantKVSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "tenant_kvs"
 
diff --git a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantSqlDao.sql.stg b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantSqlDao.sql.stg
index 56c8986..25cfc6f 100644
--- a/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantSqlDao.sql.stg
+++ b/tenant/src/main/resources/org/killbill/billing/tenant/dao/TenantSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TenantDaoSql: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "tenants"
 
@@ -23,7 +23,7 @@ tableValues() ::= <<
 
 /* No account_record_id field */
 accountRecordIdFieldWithComma(prefix) ::= ""
-accountRecordIdValueWithComma(prefix) ::= ""
+accountRecordIdValueWithComma() ::= ""
 
 /* No tenant_record_id field */
 tenantRecordIdFieldWithComma(prefix) ::= ""
@@ -33,8 +33,8 @@ CHECK_TENANT(prefix) ::= "1 = 1"
 /* Override default create call to include secrets */
 create() ::= <<
 insert into <tableName()> (
-  <idField()>
-, <tableFields()>
+  <idField("")>
+, <tableFields("")>
 , api_secret
 , api_salt
 )

usage/pom.xml 10(+5 -5)

diff --git a/usage/pom.xml b/usage/pom.xml
index 74bf3c6..611ec07 100644
--- a/usage/pom.xml
+++ b/usage/pom.xml
@@ -70,14 +70,10 @@
         </dependency>
         <dependency>
             <groupId>org.antlr</groupId>
-            <artifactId>stringtemplate</artifactId>
+            <artifactId>ST4</artifactId>
             <scope>runtime</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-account</artifactId>
             <scope>test</scope>
@@ -143,6 +139,10 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-jdbi</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-all</artifactId>
             <scope>test</scope>
diff --git a/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java b/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
index 89fc3a2..e947fa5 100644
--- a/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
+++ b/usage/src/main/java/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.java
@@ -27,17 +27,17 @@ import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.util.callcontext.InternalTenantContextBinder;
 import org.killbill.billing.util.entity.Entity;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlBatch;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface RolledUpUsageSqlDao extends EntitySqlDao<RolledUpUsageModelDao, Entity> {
 
     @SqlBatch
-    void create(@BindBean Iterable<RolledUpUsageModelDao> usages,
+    void create(@SmartBindBean Iterable<RolledUpUsageModelDao> usages,
                 @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlQuery
diff --git a/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg b/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
index b1d739c..44db9b9 100644
--- a/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
+++ b/usage/src/main/resources/org/killbill/billing/usage/dao/RolledUpUsageSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group RolledUpUsageSqlDao : EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "rolled_up_usage"
 
@@ -29,45 +29,45 @@ select
 from <tableName()>
 where subscription_id = :subscriptionId
 and tracking_id = :trackingId
-<AND_CHECK_TENANT()>
+<AND_CHECK_TENANT("")>
 limit 1
 ;
 >>
 
 getUsageForSubscription() ::= <<
 select
-  <allTableFields()>
+  <allTableFields("")>
 from <tableName()>
 where subscription_id = :subscriptionId
 and record_date >= :startDate
 and record_date \< :endDate
 and unit_type = :unitType
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
 getAllUsageForSubscription() ::= <<
 select
-  <allTableFields()>
+  <allTableFields("")>
 from <tableName()>
 where subscription_id = :subscriptionId
 and record_date >= :startDate
 and record_date \< :endDate
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
 getRawUsageForAccount() ::= <<
 select
-  <allTableFields()>
+  <allTableFields("")>
 from <tableName()>
 where account_record_id = :accountRecordId
 and record_date >= :startDate
 and record_date \< :endDate
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 

util/pom.xml 10(+5 -5)

diff --git a/util/pom.xml b/util/pom.xml
index f1616a7..07328b9 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -135,7 +135,7 @@
         </dependency>
         <dependency>
             <groupId>org.antlr</groupId>
-            <artifactId>stringtemplate</artifactId>
+            <artifactId>ST4</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.commons</groupId>
@@ -174,10 +174,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>org.jdbi</groupId>
-            <artifactId>jdbi</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.joda</groupId>
             <artifactId>joda-money</artifactId>
             <version>0.9</version>
@@ -196,6 +192,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.billing</groupId>
+            <artifactId>killbill-platform-lifecycle</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-platform-osgi</artifactId>
         </dependency>
         <dependency>
diff --git a/util/src/main/java/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.java b/util/src/main/java/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.java
index 9efa110..fb6e7a5 100644
--- a/util/src/main/java/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.java
@@ -19,17 +19,17 @@ package org.killbill.billing.util.broadcast.dao;
 
 import java.util.List;
 
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface BroadcastSqlDao {
 
     @SqlUpdate
-    public void create(@BindBean final BroadcastModelDao broadcastModelDao);
+    public void create(@SmartBindBean final BroadcastModelDao broadcastModelDao);
 
     @SqlQuery
     public List<BroadcastModelDao> getLatestEntries(@Bind("recordId") final Long recordId);
diff --git a/util/src/main/java/org/killbill/billing/util/broadcast/dao/DefaultBroadcastDao.java b/util/src/main/java/org/killbill/billing/util/broadcast/dao/DefaultBroadcastDao.java
index 6d7f32a..8ceda0e 100644
--- a/util/src/main/java/org/killbill/billing/util/broadcast/dao/DefaultBroadcastDao.java
+++ b/util/src/main/java/org/killbill/billing/util/broadcast/dao/DefaultBroadcastDao.java
@@ -39,8 +39,6 @@ public class DefaultBroadcastDao implements BroadcastDao {
     public DefaultBroadcastDao(final IDBI dbi, final Clock clock) {
         this.dbi = dbi;
         this.clock = clock;
-        ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(BroadcastModelDao.class));
-
     }
 
     @Override
diff --git a/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java b/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java
index 53e589e..f75fd4b 100644
--- a/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.java
@@ -20,7 +20,7 @@ import java.util.List;
 import java.util.UUID;
 
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
@@ -31,18 +31,18 @@ import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.customfield.CustomField;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface CustomFieldSqlDao extends EntitySqlDao<CustomFieldModelDao, CustomField> {
 
     @SqlUpdate
     @Audited(ChangeType.DELETE)
     void markTagAsDeleted(@Bind("id") String customFieldId,
-                          @BindBean InternalCallContext context);
+                          @SmartBindBean InternalCallContext context);
 
     @SqlQuery
     List<CustomFieldModelDao> getCustomFieldsForObject(@Bind("objectId") UUID objectId,
                                                        @Bind("objectType") ObjectType objectType,
-                                                       @BindBean InternalTenantContext internalTenantContext);
+                                                       @SmartBindBean InternalTenantContext internalTenantContext);
 }
diff --git a/util/src/main/java/org/killbill/billing/util/dao/AuditSqlDao.java b/util/src/main/java/org/killbill/billing/util/dao/AuditSqlDao.java
index 7ca13e0..e9cf5b8 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/AuditSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/AuditSqlDao.java
@@ -21,8 +21,9 @@ package org.killbill.billing.util.dao;
 import java.util.Iterator;
 import java.util.List;
 
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.Define;
@@ -34,7 +35,6 @@ import org.killbill.billing.util.audit.dao.AuditLogModelDao;
 import org.killbill.billing.util.cache.Cachable;
 import org.killbill.billing.util.cache.Cachable.CacheType;
 import org.killbill.billing.util.cache.CachableKey;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
 
 /**
  * Note 1: cache invalidation has to happen for audit logs (which is tricky in the multi-nodes scenario).
@@ -45,33 +45,33 @@ import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
  * <p/>
  * Note 2: in the queries below, tableName always refers to the TableName enum, not the actual table name (TableName.getTableName()).
  */
-@EntitySqlDaoStringTemplate("/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg")
+@KillBillSqlDaoStringTemplate("/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg")
 // Note: @RegisterMapper annotation won't work here as we build the SqlObject via EntitySqlDao (annotations won't be inherited for JDBI)
 public interface AuditSqlDao {
 
     @SqlUpdate
-    public void insertAuditFromTransaction(@BindBean final EntityAudit audit,
-                                           @BindBean final InternalCallContext context);
+    public void insertAuditFromTransaction(@SmartBindBean final EntityAudit audit,
+                                           @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     @SmartFetchSize(shouldStream = true)
-    public Iterator<AuditLogModelDao> getAuditLogsForAccountRecordId(@BindBean final InternalTenantContext context);
+    public Iterator<AuditLogModelDao> getAuditLogsForAccountRecordId(@SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     @SmartFetchSize(shouldStream = true)
     public Iterator<AuditLogModelDao> getAuditLogsForTableNameAndAccountRecordId(@Bind("tableName") final String tableName,
-                                                                                 @BindBean final InternalTenantContext context);
+                                                                                 @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     @Cachable(CacheType.AUDIT_LOG)
     public List<AuditLogModelDao> getAuditLogsForTargetRecordId(@CachableKey(1) @Bind("tableName") final String tableName,
                                                                 @CachableKey(2) @Bind("targetRecordId") final long targetRecordId,
-                                                                @BindBean final InternalTenantContext context);
+                                                                @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     @Cachable(CacheType.AUDIT_LOG_VIA_HISTORY)
     public List<AuditLogModelDao> getAuditLogsViaHistoryForTargetRecordId(@CachableKey(1) @Bind("tableName") final String historyTableName, /* Uppercased - used to find entries in audit_log table */
                                                                           @CachableKey(2) @Define("historyTableName") final String actualHistoryTableName, /* Actual table name, used in the inner join query */
                                                                           @CachableKey(3) @Bind("targetRecordId") final long targetRecordId,
-                                                                          @BindBean final InternalTenantContext context);
+                                                                          @SmartBindBean final InternalTenantContext context);
 }
diff --git a/util/src/main/java/org/killbill/billing/util/dao/EntityHistoryBinder.java b/util/src/main/java/org/killbill/billing/util/dao/EntityHistoryBinder.java
index e5afcf6..42d7ceb 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/EntityHistoryBinder.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/EntityHistoryBinder.java
@@ -53,7 +53,7 @@ public @interface EntityHistoryBinder {
                 @Override
                 public void bind(final SQLStatement<?> q, final EntityHistoryBinder bind, final EntityHistoryModelDao<M, E> history) {
                     try {
-                        // Emulate @BindBean
+                        // Emulate @SmartBindBean
                         final M arg = history.getEntity();
                         final BeanInfo infos = Introspector.getBeanInfo(arg.getClass());
                         final PropertyDescriptor[] props = infos.getPropertyDescriptors();
diff --git a/util/src/main/java/org/killbill/billing/util/dao/HistorySqlDao.java b/util/src/main/java/org/killbill/billing/util/dao/HistorySqlDao.java
index 5f6d2d1..e1f7cee 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/HistorySqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/HistorySqlDao.java
@@ -24,7 +24,7 @@ import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.util.entity.Entity;
 import org.killbill.billing.util.entity.dao.EntityModelDao;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.GetGeneratedKeys;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@@ -33,9 +33,9 @@ public interface HistorySqlDao<M extends EntityModelDao<E>, E extends Entity> {
 
     @SqlQuery
     public List<EntityHistoryModelDao<M, E>> getHistoryForTargetRecordId(@Bind("targetRecordId") final long targetRecordId,
-                                                                         @BindBean InternalCallContext context);
+                                                                         @SmartBindBean InternalCallContext context);
     @SqlUpdate
     @GetGeneratedKeys
     public Long addHistoryFromTransaction(@EntityHistoryBinder EntityHistoryModelDao<M, E> history,
-                                          @BindBean InternalCallContext context);
+                                          @SmartBindBean InternalCallContext context);
 }
diff --git a/util/src/main/java/org/killbill/billing/util/dao/NonEntitySqlDao.java b/util/src/main/java/org/killbill/billing/util/dao/NonEntitySqlDao.java
index 798b334..650f052 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/NonEntitySqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/NonEntitySqlDao.java
@@ -21,15 +21,15 @@ package org.killbill.billing.util.dao;
 import java.util.UUID;
 
 import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.customizers.Define;
 import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface NonEntitySqlDao extends Transactional<NonEntitySqlDao>, CloseMe {
 
     @SqlQuery
@@ -62,19 +62,19 @@ public interface NonEntitySqlDao extends Transactional<NonEntitySqlDao>, CloseMe
     @SqlQuery
     public Iterable<RecordIdIdMappings> getHistoryRecordIdIdMappings(@Define("tableName") String tableName,
                                                                      @Define("historyTableName") String historyTableName,
-                                                                     @BindBean final InternalTenantContext context);
+                                                                     @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public Iterable<RecordIdIdMappings> getHistoryRecordIdIdMappingsForAccountsTable(@Define("tableName") String tableName,
                                                                                      @Define("historyTableName") String historyTableName,
-                                                                                     @BindBean final InternalTenantContext context);
+                                                                                     @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public Iterable<RecordIdIdMappings> getHistoryRecordIdIdMappingsForTablesWithoutAccountRecordId(@Define("tableName") String tableName,
                                                                                                     @Define("historyTableName") String historyTableName,
-                                                                                                    @BindBean final InternalTenantContext context);
+                                                                                                    @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public Iterable<RecordIdIdMappings> getRecordIdIdMappings(@Define("tableName") String tableName,
-                                                              @BindBean final InternalTenantContext context);
+                                                              @SmartBindBean final InternalTenantContext context);
 }
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java
index ede762c..a4ddb91 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDao.java
@@ -32,40 +32,41 @@ import org.killbill.billing.util.dao.AuditSqlDao;
 import org.killbill.billing.util.dao.HistorySqlDao;
 import org.killbill.billing.util.entity.Entity;
 import org.killbill.commons.jdbi.statement.SmartFetchSize;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.Define;
 import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface EntitySqlDao<M extends EntityModelDao<E>, E extends Entity> extends AuditSqlDao, HistorySqlDao<M, E>, Transactional<EntitySqlDao<M, E>>, CloseMe {
 
     @SqlUpdate
     @Audited(ChangeType.INSERT)
-    public Object create(@BindBean final M entity,
-                         @BindBean final InternalCallContext context) throws EntityPersistenceException;
+    public Object create(@SmartBindBean final M entity,
+                         @SmartBindBean final InternalCallContext context) throws EntityPersistenceException;
 
     @SqlQuery
     public M getById(@Bind("id") final String id,
-                     @BindBean final InternalTenantContext context);
+                     @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public M getByRecordId(@Bind("recordId") final Long recordId,
-                           @BindBean final InternalTenantContext context);
+                           @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    public List<M> getByAccountRecordId(@BindBean final InternalTenantContext context);
+    public List<M> getByAccountRecordId(@SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    public List<M> getByAccountRecordIdIncludedDeleted(@BindBean final InternalTenantContext context);
+    public List<M> getByAccountRecordIdIncludedDeleted(@SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     @Cachable(CacheType.RECORD_ID)
     public Long getRecordId(@CachableKey(1) @Bind("id") final String id,
-                            @BindBean final InternalTenantContext context);
+                            @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     @SmartFetchSize(shouldStream = true)
@@ -74,16 +75,16 @@ public interface EntitySqlDao<M extends EntityModelDao<E>, E extends Entity> ext
                               @Bind("offset") final Long offset,
                               @Bind("rowCount") final Long rowCount,
                               @Define("ordering") final String ordering,
-                              @BindBean final InternalTenantContext context);
+                              @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     public Long getSearchCount(@Bind("searchKey") final String searchKey,
                                @Bind("likeSearchKey") final String likeSearchKey,
-                               @BindBean final InternalTenantContext context);
+                               @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     @SmartFetchSize(shouldStream = true)
-    public Iterator<M> getAll(@BindBean final InternalTenantContext context);
+    public Iterator<M> getAll(@SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
     @SmartFetchSize(shouldStream = true)
@@ -91,11 +92,11 @@ public interface EntitySqlDao<M extends EntityModelDao<E>, E extends Entity> ext
                            @Bind("rowCount") final Long rowCount,
                            @Define("orderBy") final String orderBy,
                            @Define("ordering") final String ordering,
-                           @BindBean final InternalTenantContext context);
+                           @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    public Long getCount(@BindBean final InternalTenantContext context);
+    public Long getCount(@SmartBindBean final InternalTenantContext context);
 
     @SqlUpdate
-    public void test(@BindBean final InternalTenantContext context);
+    public void test(@SmartBindBean final InternalTenantContext context);
 }
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
index 654d0da..f6ba247 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
@@ -32,6 +32,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.annotation.Nullable;
 
@@ -51,7 +52,6 @@ import org.killbill.billing.util.dao.EntityHistoryModelDao;
 import org.killbill.billing.util.dao.NonEntityDao;
 import org.killbill.billing.util.dao.TableName;
 import org.killbill.billing.util.entity.Entity;
-import org.killbill.billing.util.tag.dao.UUIDCollectionBinder;
 import org.killbill.clock.Clock;
 import org.killbill.commons.profiling.Profiling;
 import org.killbill.commons.profiling.Profiling.WithProfilingCallback;
@@ -62,6 +62,7 @@ import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.exceptions.DBIException;
 import org.skife.jdbi.v2.exceptions.StatementException;
 import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.unstable.BindIn;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -84,6 +85,8 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>, 
 
     private final Logger logger = LoggerFactory.getLogger(EntitySqlDaoWrapperInvocationHandler.class);
 
+    private final Map<String, Annotation[][]> parameterAnnotationsByMethod = new ConcurrentHashMap<String, Annotation[][]>();
+
     private final Class<S> sqlDaoClass;
     private final S sqlDao;
     private final Handle handle;
@@ -227,7 +230,7 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>, 
         if (cache != null && objectType != null) {
             // Find all arguments marked with @CachableKey
             final Map<Integer, Object> keyPieces = new LinkedHashMap<Integer, Object>();
-            final Annotation[][] annotations = method.getParameterAnnotations();
+            final Annotation[][] annotations = getAnnotations(method);
             for (int i = 0; i < annotations.length; i++) {
                 for (int j = 0; j < annotations[i].length; j++) {
                     final Annotation annotation = annotations[i][j];
@@ -408,7 +411,8 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>, 
     }
 
     private List<String> retrieveEntityIdsFromArguments(final Method method, final Object[] args) {
-        final Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+        final Annotation[][] parameterAnnotations = getAnnotations(method);
+
         int i = -1;
         for (final Object arg : args) {
             i++;
@@ -430,7 +434,7 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>, 
             for (final Annotation annotation : parameterAnnotations[i]) {
                 if (arg instanceof String && Bind.class.equals(annotation.annotationType()) && ("id").equals(((Bind) annotation).value())) {
                     return ImmutableList.<String>of((String) arg);
-                } else if (arg instanceof Collection && UUIDCollectionBinder.class.equals(annotation.annotationType())) {
+                } else if (arg instanceof Collection && BindIn.class.equals(annotation.annotationType()) && ("ids").equals(((BindIn) annotation).value())) {
                     return ImmutableList.<String>copyOf((Collection) arg);
                 }
             }
@@ -438,6 +442,19 @@ public class EntitySqlDaoWrapperInvocationHandler<S extends EntitySqlDao<M, E>, 
         return ImmutableList.<String>of();
     }
 
+    private Annotation[][] getAnnotations(final Method method) {
+        // Expensive to compute
+        final String methodString = method.toString();
+
+        // Method.getParameterAnnotations() generates lots of garbage objects
+        Annotation[][] parameterAnnotations = parameterAnnotationsByMethod.get(methodString);
+        if (parameterAnnotations == null) {
+            parameterAnnotations = method.getParameterAnnotations();
+            parameterAnnotationsByMethod.put(methodString, parameterAnnotations);
+        }
+        return parameterAnnotations;
+    }
+
     private Builder<String> extractEntityIdsFromBatchArgument(final Iterable arg) {
         final Iterator iterator = arg.iterator();
         final Builder<String> entityIds = new Builder<String>();
diff --git a/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java b/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java
new file mode 100644
index 0000000..0e78d66
--- /dev/null
+++ b/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.util.glue;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import org.killbill.billing.lifecycle.ServiceFinder;
+import org.killbill.billing.util.broadcast.dao.BroadcastModelDao;
+import org.killbill.billing.util.dao.AuditLogModelDaoMapper;
+import org.killbill.billing.util.dao.EntityHistoryModelDaoMapperFactory;
+import org.killbill.billing.util.dao.RecordIdIdMappingsMapper;
+import org.killbill.billing.util.entity.Entity;
+import org.killbill.billing.util.entity.dao.EntitySqlDao;
+import org.killbill.billing.util.nodes.dao.NodeInfoModelDao;
+import org.killbill.billing.util.security.shiro.dao.RolesPermissionsModelDao;
+import org.killbill.billing.util.security.shiro.dao.SessionModelDao;
+import org.killbill.billing.util.security.shiro.dao.UserModelDao;
+import org.killbill.billing.util.security.shiro.dao.UserRolesModelDao;
+import org.killbill.billing.util.validation.dao.DatabaseSchemaSqlDao;
+import org.killbill.bus.dao.BusEventModelDao;
+import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
+import org.killbill.notificationq.dao.NotificationEventModelDao;
+import org.skife.jdbi.v2.ResultSetMapperFactory;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+public class IDBISetup {
+
+    public static List<? extends ResultSetMapperFactory> mapperFactoriesToRegister() {
+        final Builder<ResultSetMapperFactory> builder = ImmutableList.<ResultSetMapperFactory>builder();
+        builder.add(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
+        builder.add(new LowerToCamelBeanMapperFactory(BroadcastModelDao.class));
+        builder.add(new LowerToCamelBeanMapperFactory(NodeInfoModelDao.class));
+        builder.add(new LowerToCamelBeanMapperFactory(UserModelDao.class));
+        builder.add(new LowerToCamelBeanMapperFactory(UserRolesModelDao.class));
+        builder.add(new LowerToCamelBeanMapperFactory(RolesPermissionsModelDao.class));
+        builder.add(new LowerToCamelBeanMapperFactory(BusEventModelDao.class));
+        builder.add(new LowerToCamelBeanMapperFactory(NotificationEventModelDao.class));
+
+        final ServiceFinder<EntitySqlDao> serviceFinder = new ServiceFinder<EntitySqlDao>(IDBISetup.class.getClassLoader(), EntitySqlDao.class.getName());
+        for (final Class<? extends EntitySqlDao> sqlObjectType : serviceFinder.getServices()) {
+            // Find the model class associated with this sqlObjectType (which is a SqlDao class) to register its mapper
+            // If a custom mapper is defined via @RegisterMapper, don't register our generic one
+            if (sqlObjectType.getGenericInterfaces() != null &&
+                sqlObjectType.getAnnotation(RegisterMapper.class) == null) {
+                for (int i = 0; i < sqlObjectType.getGenericInterfaces().length; i++) {
+                    if (sqlObjectType.getGenericInterfaces()[i] instanceof ParameterizedType) {
+                        final ParameterizedType type = (ParameterizedType) sqlObjectType.getGenericInterfaces()[i];
+                        for (int j = 0; j < type.getActualTypeArguments().length; j++) {
+                            final Type modelType = type.getActualTypeArguments()[j];
+                            if (modelType instanceof Class) {
+                                final Class modelClazz = (Class) modelType;
+                                if (Entity.class.isAssignableFrom(modelClazz)) {
+                                    builder.add(new LowerToCamelBeanMapperFactory(modelClazz));
+                                    builder.add(new EntityHistoryModelDaoMapperFactory(modelClazz, sqlObjectType));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return builder.build();
+    }
+
+    public static List<? extends ResultSetMapper> mappersToRegister() {
+        return ImmutableList.<ResultSetMapper>builder()
+                .add(new AuditLogModelDaoMapper())
+                .add(new RecordIdIdMappingsMapper())
+                .add(new DatabaseSchemaSqlDao.ColumnInfoMapper())
+                .build();
+    }
+}
diff --git a/util/src/main/java/org/killbill/billing/util/nodes/dao/DefaultNodeInfoDao.java b/util/src/main/java/org/killbill/billing/util/nodes/dao/DefaultNodeInfoDao.java
index 8d1c264..2c951ba 100644
--- a/util/src/main/java/org/killbill/billing/util/nodes/dao/DefaultNodeInfoDao.java
+++ b/util/src/main/java/org/killbill/billing/util/nodes/dao/DefaultNodeInfoDao.java
@@ -39,8 +39,6 @@ public class DefaultNodeInfoDao implements NodeInfoDao {
     public DefaultNodeInfoDao(final IDBI dbi, final Clock clock) {
         this.dbi = dbi;
         this.clock = clock;
-        ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(NodeInfoModelDao.class));
-
     }
 
     @Override
diff --git a/util/src/main/java/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.java b/util/src/main/java/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.java
index ceedde4..e2be7f8 100644
--- a/util/src/main/java/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.java
@@ -20,17 +20,17 @@ package org.killbill.billing.util.nodes.dao;
 import java.util.Date;
 import java.util.List;
 
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface NodeInfoSqlDao {
 
     @SqlUpdate
-    public void create(@BindBean final NodeInfoModelDao nodeInfo);
+    public void create(@SmartBindBean final NodeInfoModelDao nodeInfo);
 
     @SqlUpdate
     public void updateNodeInfo(@Bind("nodeName") final String nodeName, @Bind("nodeInfo") final String nodeInfo, @Bind("updatedDate") final Date updatedDate);
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java
index 7dc71e7..013f859 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/DefaultUserDao.java
@@ -54,9 +54,6 @@ public class DefaultUserDao implements UserDao {
         this.dbi = dbi;
         this.clock = clock;
         this.securityConfig = securityConfig;
-        ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(UserModelDao.class));
-        ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(UserRolesModelDao.class));
-        ((DBI) dbi).registerMapper(new LowerToCamelBeanMapperFactory(RolesPermissionsModelDao.class));
     }
 
     @Override
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
index f277430..409f2a3 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.java
@@ -18,14 +18,14 @@
 
 package org.killbill.billing.util.security.shiro.dao;
 
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface JDBCSessionSqlDao extends Transactional<JDBCSessionSqlDao> {
 
     @SqlQuery
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java
index 029b268..dccee99 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.java
@@ -19,14 +19,14 @@ package org.killbill.billing.util.security.shiro.dao;
 
 import java.util.List;
 
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface RolesPermissionsSqlDao extends Transactional<RolesPermissionsSqlDao> {
 
     @SqlQuery
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.java
index 8c25d9b..e413146 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.java
@@ -20,14 +20,14 @@ package org.killbill.billing.util.security.shiro.dao;
 import java.util.Date;
 import java.util.List;
 
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface UserRolesSqlDao extends Transactional<UserRolesSqlDao> {
 
     @SqlQuery
diff --git a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.java b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.java
index 6c7cd31..d9c659e 100644
--- a/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.java
@@ -19,14 +19,14 @@ package org.killbill.billing.util.security.shiro.dao;
 
 import java.util.Date;
 
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface UsersSqlDao extends Transactional<UsersSqlDao> {
 
     @SqlQuery
diff --git a/util/src/main/java/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.java b/util/src/main/java/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.java
index 076ef0d..929fa42 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.java
@@ -1,7 +1,9 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
  * License.  You may obtain a copy of the License at:
  *
@@ -19,36 +21,36 @@ package org.killbill.billing.util.tag.dao;
 import java.util.Collection;
 import java.util.List;
 
-import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
-import org.skife.jdbi.v2.sqlobject.SqlQuery;
-import org.skife.jdbi.v2.sqlobject.SqlUpdate;
-
-import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
 import org.killbill.billing.util.tag.TagDefinition;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.unstable.BindIn;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface TagDefinitionSqlDao extends EntitySqlDao<TagDefinitionModelDao, TagDefinition> {
 
     @SqlQuery
     public TagDefinitionModelDao getByName(@Bind("name") final String definitionName,
-                                           @BindBean final InternalTenantContext context);
+                                           @SmartBindBean final InternalTenantContext context);
 
     @SqlUpdate
     @Audited(ChangeType.DELETE)
     public void markTagDefinitionAsDeleted(@Bind("id") final String definitionId,
-                                           @BindBean final InternalCallContext context);
+                                           @SmartBindBean final InternalCallContext context);
 
     @SqlQuery
     public int tagDefinitionUsageCount(@Bind("id") final String definitionId,
-                                       @BindBean final InternalTenantContext context);
+                                       @SmartBindBean final InternalTenantContext context);
 
     @SqlQuery
-    public List<TagDefinitionModelDao> getByIds(@UUIDCollectionBinder final Collection<String> definitionIds,
-                                                @BindBean final InternalTenantContext context);
+    public List<TagDefinitionModelDao> getByIds(@BindIn("ids") final Collection<String> definitionIds,
+                                                @SmartBindBean final InternalTenantContext context);
 }
diff --git a/util/src/main/java/org/killbill/billing/util/tag/dao/TagSqlDao.java b/util/src/main/java/org/killbill/billing/util/tag/dao/TagSqlDao.java
index d1f0b67..257d5c3 100644
--- a/util/src/main/java/org/killbill/billing/util/tag/dao/TagSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/tag/dao/TagSqlDao.java
@@ -20,7 +20,7 @@ import java.util.List;
 import java.util.UUID;
 
 import org.skife.jdbi.v2.sqlobject.Bind;
-import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.killbill.commons.jdbi.binder.SmartBindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
@@ -30,24 +30,24 @@ import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.util.audit.ChangeType;
 import org.killbill.billing.util.entity.dao.Audited;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.killbill.billing.util.tag.Tag;
 
-@EntitySqlDaoStringTemplate
+@KillBillSqlDaoStringTemplate
 public interface TagSqlDao extends EntitySqlDao<TagModelDao, Tag> {
 
     @SqlUpdate
     @Audited(ChangeType.DELETE)
     void markTagAsDeleted(@Bind("id") String tagId,
-                          @BindBean InternalCallContext context);
+                          @SmartBindBean InternalCallContext context);
 
     @SqlQuery
     List<TagModelDao> getTagsForObject(@Bind("objectId") UUID objectId,
                                        @Bind("objectType") ObjectType objectType,
-                                       @BindBean InternalTenantContext internalTenantContext);
+                                       @SmartBindBean InternalTenantContext internalTenantContext);
 
     @SqlQuery
     List<TagModelDao> getTagsForObjectIncludedDeleted(@Bind("objectId") UUID objectId,
                                                       @Bind("objectType") ObjectType objectType,
-                                                      @BindBean InternalTenantContext internalTenantContext);
+                                                      @SmartBindBean InternalTenantContext internalTenantContext);
 }
diff --git a/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java b/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java
index 78e6d0f..aedee08 100644
--- a/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -24,16 +24,14 @@ import java.util.List;
 
 import javax.annotation.Nullable;
 
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 import org.killbill.billing.util.validation.DefaultColumnInfo;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
-import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-@EntitySqlDaoStringTemplate
-@RegisterMapper(DatabaseSchemaSqlDao.ColumnInfoMapper.class)
+@KillBillSqlDaoStringTemplate
 public interface DatabaseSchemaSqlDao {
 
     @SqlQuery
diff --git a/util/src/main/resources/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.sql.stg
index 49fa45a..a26bac2 100644
--- a/util/src/main/resources/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/broadcast/dao/BroadcastSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group BroadcastSqlDao;
-
 tableName() ::= "service_broadcasts"
 
 
@@ -29,9 +27,13 @@ allTableValues() ::= <<
 , <tableValues()>
 >>
 
+defaultOrderBy(prefix) ::= <<
+order by <prefix>record_id ASC
+>>
+
 create() ::= <<
 insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
 )
 values (
 <tableValues()>
diff --git a/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
index af3948a..ca8defa 100644
--- a/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/customfield/dao/CustomFieldSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group CustomFieldSqlDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 andCheckSoftDeletionWithComma(prefix) ::= "and <prefix>is_active"
 
@@ -41,14 +41,14 @@ where <idField("")> = :id
 
 getCustomFieldsForObject() ::= <<
 select
-<allTableFields()>
+<allTableFields("")>
 from <tableName()>
 where
 object_id = :objectId
 and object_type = :objectType
 and is_active
-<AND_CHECK_TENANT()>
-<defaultOrderBy()>
+<AND_CHECK_TENANT("")>
+<defaultOrderBy("")>
 ;
 >>
 
diff --git a/util/src/main/resources/org/killbill/billing/util/dao/NonEntitySqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/dao/NonEntitySqlDao.sql.stg
index b7e4d4b..6b6972f 100644
--- a/util/src/main/resources/org/killbill/billing/util/dao/NonEntitySqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/dao/NonEntitySqlDao.sql.stg
@@ -1,5 +1,3 @@
-group NonEntitySqlDao;
-
 getRecordIdFromObject(tableName) ::= <<
 select
   record_id
diff --git a/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg
index 2d96592..26faf51 100644
--- a/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg
@@ -1,6 +1,3 @@
-group EntitySqlDao;
-
-
 /******************   To override in each EntitySqlDao template file *****************************/
 
 tableName() ::= ""
@@ -152,10 +149,10 @@ select
 <allTableFields("t.")>
 from <tableName()> t
 join (
-  select <recordIdField()>
+  select <recordIdField("")>
   from <tableName()>
-  where <CHECK_TENANT()>
-  <andCheckSoftDeletionWithComma()>
+  where <CHECK_TENANT("")>
+  <andCheckSoftDeletionWithComma("")>
   order by <orderBy> <ordering>
   limit :rowCount offset :offset
 ) optimization on <recordIdField("optimization.")> = <recordIdField("t.")>
@@ -292,10 +289,10 @@ where (<searchQuery("t.")>)
 
 create() ::= <<
 insert into <tableName()> (
-  <idField()>
-, <tableFields()>
-<accountRecordIdFieldWithComma()>
-<tenantRecordIdFieldWithComma()>
+  <idField("")>
+, <tableFields("")>
+<accountRecordIdFieldWithComma("")>
+<tenantRecordIdFieldWithComma("")>
 )
 values (
   <idValue()>
@@ -338,7 +335,7 @@ auditTableValues() ::= <<
 
 getHistoryForTargetRecordId() ::= <<
 select
-  <idField()>
+  <idField("")>
 , <historyTableFields("t.")>
 <accountRecordIdFieldWithComma("t.")>
 <tenantRecordIdFieldWithComma("t.")>
@@ -351,10 +348,10 @@ order by <recordIdField("t.")> ASC
 
 addHistoryFromTransaction() ::= <<
 insert into <historyTableName()> (
-  <idField()>
-, <historyTableFields()>
-<accountRecordIdFieldWithComma()>
-<tenantRecordIdFieldWithComma()>
+  <idField("")>
+, <historyTableFields("")>
+<accountRecordIdFieldWithComma("")>
+<tenantRecordIdFieldWithComma("")>
 )
 values (
   <idValue()>
@@ -368,7 +365,7 @@ values (
 
 insertAuditFromTransaction() ::= <<
 insert into <auditTableName()> (
-<auditTableFields()>
+<auditTableFields("")>
 )
 values (
 <auditTableValues()>
diff --git a/util/src/main/resources/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.sql.stg
index 312c45d..87463e6 100644
--- a/util/src/main/resources/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/nodes/dao/NodeInfoSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group NodeInfoSqlDao;
-
 tableName() ::= "node_infos"
 
 tableFields(prefix) ::= <<
@@ -31,7 +29,7 @@ allTableValues() ::= <<
 
 create() ::= <<
 insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
 )
 values (
 <tableValues()>
@@ -40,7 +38,7 @@ values (
 >>
 
 getByNodeName() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where node_name = :nodeName
 and is_active
@@ -48,7 +46,7 @@ and is_active
 >>
 
 getAll() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where is_active
 order by node_name asc
@@ -68,4 +66,4 @@ delete
 from <tableName()>
 where node_name = :nodeName
 ;
->>
\ No newline at end of file
+>>
diff --git a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
index b002312..e6091e5 100644
--- a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/JDBCSessionSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group JDBCSessionSqlDao;
-
 read() ::= <<
 select
   record_id
diff --git a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg
index 5da1774..febc7ee 100644
--- a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/RolesPermissionsSqlDao.sql.stg
@@ -1,6 +1,3 @@
-group RolesPermissionsSqlDao;
-
-
 tableName() ::= "roles_permissions"
 
 tableFields(prefix) ::= <<
@@ -37,7 +34,7 @@ allTableValues() ::= <<
 
 create() ::= <<
 insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
 )
 values (
 <tableValues()>
@@ -46,7 +43,7 @@ values (
 >>
 
 getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where record_id = :recordId
 and is_active
@@ -55,7 +52,7 @@ and is_active
 
 
 getByRoleName() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where role_name = :roleName
 and is_active
diff --git a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.sql.stg
index 0c9fe1c..3d4d327 100644
--- a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UserRolesSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group UserRolesSqlDao;
-
 tableName() ::= "user_roles"
 
 tableFields(prefix) ::= <<
@@ -36,7 +34,7 @@ allTableValues() ::= <<
 
 create() ::= <<
 insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
 )
 values (
 <tableValues()>
@@ -45,7 +43,7 @@ values (
 >>
 
 getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where record_id = :recordId
 and is_active
@@ -53,7 +51,7 @@ and is_active
 >>
 
 getByUsername() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where username = :username
 and is_active
diff --git a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.sql.stg
index 07bd4d5..94a6882 100644
--- a/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/security/shiro/dao/UsersSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group UsersSqlDao;
-
 tableName() ::= "users"
 
 tableFields(prefix) ::= <<
@@ -38,7 +36,7 @@ allTableValues() ::= <<
 
 create() ::= <<
 insert into <tableName()> (
-<tableFields()>
+<tableFields("")>
 )
 values (
 <tableValues()>
@@ -47,7 +45,7 @@ values (
 >>
 
 getByRecordId() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where record_id = :recordId
 and is_active
@@ -55,7 +53,7 @@ and is_active
 >>
 
 getByUsername() ::= <<
-select <allTableFields()>
+select <allTableFields("")>
 from <tableName()>
 where username = :username
 and is_active
diff --git a/util/src/main/resources/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
index a1efb99..cc1f546 100644
--- a/util/src/main/resources/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/tag/dao/TagDefinitionSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TagDefinitionDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "tag_definitions"
 
@@ -63,7 +63,7 @@ select
   <allTableFields("t.")>
 from <tableName()> t
 where t.is_active
-and <idField("t.")> in (<ids: {id | :id_<i0>}; separator="," >)
+and <idField("t.")> in (<ids>)
 <AND_CHECK_TENANT("t.")>
 ;
 >>
diff --git a/util/src/main/resources/org/killbill/billing/util/tag/dao/TagSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/tag/dao/TagSqlDao.sql.stg
index 177ec5b..6f4d604 100644
--- a/util/src/main/resources/org/killbill/billing/util/tag/dao/TagSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/tag/dao/TagSqlDao.sql.stg
@@ -1,4 +1,4 @@
-group TagDao: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "tags"
 
diff --git a/util/src/main/resources/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.sql.stg b/util/src/main/resources/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.sql.stg
index e14db44..075fa67 100644
--- a/util/src/main/resources/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.sql.stg
+++ b/util/src/main/resources/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.sql.stg
@@ -1,5 +1,3 @@
-group DatabaseSchemaSqlDao;
-
 getSchemaInfo(schemaName) ::= <<
     SELECT TABLE_NAME, COLUMN_NAME, IS_NULLABLE, DATA_TYPE,
     CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE
diff --git a/util/src/test/java/org/killbill/billing/DBTestingHelper.java b/util/src/test/java/org/killbill/billing/DBTestingHelper.java
index 7023039..7046879 100644
--- a/util/src/test/java/org/killbill/billing/DBTestingHelper.java
+++ b/util/src/test/java/org/killbill/billing/DBTestingHelper.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -24,14 +24,13 @@ import java.util.Enumeration;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.killbill.billing.platform.test.PlatformDBTestingHelper;
-import org.killbill.billing.util.dao.AuditLogModelDaoMapper;
-import org.killbill.billing.util.dao.RecordIdIdMappingsMapper;
+import org.killbill.billing.util.glue.IDBISetup;
 import org.killbill.billing.util.io.IOUtils;
-import org.killbill.billing.util.security.shiro.dao.SessionModelDao;
 import org.killbill.commons.embeddeddb.EmbeddedDB;
-import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
 import org.skife.jdbi.v2.DBI;
 import org.skife.jdbi.v2.IDBI;
+import org.skife.jdbi.v2.ResultSetMapperFactory;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
 import com.google.common.base.MoreObjects;
 
@@ -58,9 +57,13 @@ public class DBTestingHelper extends PlatformDBTestingHelper {
         final DBI dbi = (DBI) super.getDBI();
         // Register KB specific mappers
         if (initialized.compareAndSet(false, true)) {
-            dbi.registerMapper(new AuditLogModelDaoMapper());
-            dbi.registerMapper(new RecordIdIdMappingsMapper());
-            dbi.registerMapper(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
+            for (final ResultSetMapperFactory resultSetMapperFactory : IDBISetup.mapperFactoriesToRegister()) {
+                dbi.registerMapper(resultSetMapperFactory);
+            }
+
+            for (final ResultSetMapper resultSetMapper : IDBISetup.mappersToRegister()) {
+                dbi.registerMapper(resultSetMapper);
+            }
         }
         return dbi;
     }
diff --git a/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritance.java b/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritance.java
index a93add6..588d765 100644
--- a/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritance.java
+++ b/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritance.java
@@ -16,123 +16,61 @@
 
 package org.killbill.billing.util.dao;
 
-import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.util.regex.Pattern;
 
-import org.antlr.stringtemplate.StringTemplateGroup;
 import org.killbill.billing.util.UtilTestSuiteNoDB;
+import org.stringtemplate.v4.STGroup;
+import org.stringtemplate.v4.STGroupFile;
 import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableMap;
-
 public class TestStringTemplateInheritance extends UtilTestSuiteNoDB {
 
-    InputStream entityStream;
-    InputStream kombuchaStream;
-
-    @Override
-    @BeforeMethod(groups = "fast")
-    public void beforeMethod() throws Exception {
-        super.beforeMethod();
-        entityStream = this.getClass().getResourceAsStream("/org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg");
-        kombuchaStream = this.getClass().getResourceAsStream("/org/killbill/billing/util/dao/Kombucha.sql.stg");
-    }
-
-    @Override
-    @AfterMethod(groups = "fast")
-    public void afterMethod() throws Exception {
-        super.afterMethod();
-        if (entityStream != null) {
-            entityStream.close();
-        }
-        if (kombuchaStream != null) {
-            kombuchaStream.close();
-        }
-    }
-
     @Test(groups = "fast")
     public void testCheckQueries() throws Exception {
-        // From http://www.antlr.org/wiki/display/ST/ST+condensed+--+Templates+and+groups#STcondensed--Templatesandgroups-Withsupergroupfile:
-        //     there is no mechanism for automatically loading a mentioned super-group file
-        new StringTemplateGroup(new InputStreamReader(entityStream));
-
-        final StringTemplateGroup kombucha = new StringTemplateGroup(new InputStreamReader(kombuchaStream));
+        final STGroup kombucha = new STGroupFile(this.getClass().getResource("/org/killbill/billing/util/dao/Kombucha.sql.stg"), "UTF-8", '<', '>');
 
         // Verify non inherited template
-        Assert.assertEquals(kombucha.getInstanceOf("isIsTimeForKombucha").toString(), "select hour(current_timestamp(0)) = 17 as is_time;");
+        Assert.assertEquals(kombucha.getInstanceOf("isIsTimeForKombucha").render(), "select hour(current_timestamp(0)) = 17 as is_time;");
 
         // Verify inherited templates
-        assertPattern(kombucha.getInstanceOf("getById").toString(), "select\r?\n" +
-                                                                    "  t.record_id\r?\n" +
-                                                                    ", t.id\r?\n" +
-                                                                    ", t.tea\r?\n" +
-                                                                    ", t.mushroom\r?\n" +
-                                                                    ", t.sugar\r?\n" +
-                                                                    ", t.account_record_id\r?\n" +
-                                                                    ", t.tenant_record_id\r?\n" +
-                                                                    "from kombucha t\r?\n" +
-                                                                    "where t.id = :id\r?\n" +
-                                                                    "and t.tenant_record_id = :tenantRecordId\r?\n" +
-                                                                    ";");
-        assertPattern(kombucha.getInstanceOf("getByRecordId").toString(), "select\r?\n" +
-                                                                          "  t.record_id\r?\n" +
-                                                                          ", t.id\r?\n" +
-                                                                          ", t.tea\r?\n" +
-                                                                          ", t.mushroom\r?\n" +
-                                                                          ", t.sugar\r?\n" +
-                                                                          ", t.account_record_id\r?\n" +
-                                                                          ", t.tenant_record_id\r?\n" +
-                                                                          "from kombucha t\r?\n" +
-                                                                          "where t.record_id = :recordId\r?\n" +
-                                                                          "and t.tenant_record_id = :tenantRecordId\r?\n" +
-                                                                          ";");
-        assertPattern(kombucha.getInstanceOf("getRecordId").toString(), "select\r?\n" +
+        assertPattern(kombucha.getInstanceOf("getById").render(), "select\r?\n" +
+                                                                  "  t.record_id\r?\n" +
+                                                                  ", t.id\r?\n" +
+                                                                  ", t.tea\r?\n" +
+                                                                  ", t.mushroom\r?\n" +
+                                                                  ", t.sugar\r?\n" +
+                                                                  ", t.account_record_id\r?\n" +
+                                                                  ", t.tenant_record_id\r?\n" +
+                                                                  "from kombucha t\r?\n" +
+                                                                  "where t.id = :id\r?\n" +
+                                                                  "and t.tenant_record_id = :tenantRecordId\r?\n" +
+                                                                  ";");
+        assertPattern(kombucha.getInstanceOf("getByRecordId").render(), "select\r?\n" +
                                                                         "  t.record_id\r?\n" +
+                                                                        ", t.id\r?\n" +
+                                                                        ", t.tea\r?\n" +
+                                                                        ", t.mushroom\r?\n" +
+                                                                        ", t.sugar\r?\n" +
+                                                                        ", t.account_record_id\r?\n" +
+                                                                        ", t.tenant_record_id\r?\n" +
                                                                         "from kombucha t\r?\n" +
-                                                                        "where t.id = :id\r?\n" +
+                                                                        "where t.record_id = :recordId\r?\n" +
                                                                         "and t.tenant_record_id = :tenantRecordId\r?\n" +
                                                                         ";");
-        assertPattern(kombucha.getInstanceOf("getHistoryRecordId").toString(), "select\r?\n" +
-                                                                               "  max\\(t.record_id\\)\r?\n" +
-                                                                               "from kombucha_history t\r?\n" +
-                                                                               "where t.target_record_id = :targetRecordId\r?\n" +
-                                                                               "and t.tenant_record_id = :tenantRecordId\r?\n" +
-                                                                               ";");
-        assertPattern(kombucha.getInstanceOf("getAll").toString(), "select\r?\n" +
-                                                                   "  t.record_id\r?\n" +
-                                                                   ", t.id\r?\n" +
-                                                                   ", t.tea\r?\n" +
-                                                                   ", t.mushroom\r?\n" +
-                                                                   ", t.sugar\r?\n" +
-                                                                   ", t.account_record_id\r?\n" +
-                                                                   ", t.tenant_record_id\r?\n" +
-                                                                   "from kombucha t\r?\n" +
-                                                                   "where t.tenant_record_id = :tenantRecordId\r?\n" +
-                                                                   "order by t.record_id ASC\r?\n" +
-                                                                   ";");
-        assertPattern(kombucha.getInstanceOf("get", ImmutableMap.<String, String>of("orderBy", "record_id", "offset", "3", "rowCount", "12", "ordering", "ASC")).toString(), "select\r?\n" +
-                                                                                                                                                                             "  t.record_id\r?\n" +
-                                                                                                                                                                             ", t.id\r?\n" +
-                                                                                                                                                                             ", t.tea\r?\n" +
-                                                                                                                                                                             ", t.mushroom\r?\n" +
-                                                                                                                                                                             ", t.sugar\r?\n" +
-                                                                                                                                                                             ", t.account_record_id\r?\n" +
-                                                                                                                                                                             ", t.tenant_record_id\r?\n" +
-                                                                                                                                                                             "from kombucha t\r?\n" +
-                                                                                                                                                                             "join \\(\r?\n" +
-                                                                                                                                                                             "  select record_id\r?\n" +
-                                                                                                                                                                             "  from kombucha\r?\n" +
-                                                                                                                                                                             "  where tenant_record_id = :tenantRecordId\r?\n" +
-                                                                                                                                                                             "  order by record_id ASC\r?\n" +
-                                                                                                                                                                             "  limit :rowCount offset :offset\r?\n" +
-                                                                                                                                                                             "\\) optimization on optimization.record_id = t.record_id\r?\n" +
-                                                                                                                                                                             "order by t.record_id ASC\r?\n" +
-                                                                                                                                                                             ";");
-        assertPattern(kombucha.getInstanceOf("test").toString(), "select\r?\n" +
+        assertPattern(kombucha.getInstanceOf("getRecordId").render(), "select\r?\n" +
+                                                                      "  t.record_id\r?\n" +
+                                                                      "from kombucha t\r?\n" +
+                                                                      "where t.id = :id\r?\n" +
+                                                                      "and t.tenant_record_id = :tenantRecordId\r?\n" +
+                                                                      ";");
+        assertPattern(kombucha.getInstanceOf("getHistoryRecordId").render(), "select\r?\n" +
+                                                                             "  max\\(t.record_id\\)\r?\n" +
+                                                                             "from kombucha_history t\r?\n" +
+                                                                             "where t.target_record_id = :targetRecordId\r?\n" +
+                                                                             "and t.tenant_record_id = :tenantRecordId\r?\n" +
+                                                                             ";");
+        assertPattern(kombucha.getInstanceOf("getAll").render(), "select\r?\n" +
                                                                  "  t.record_id\r?\n" +
                                                                  ", t.id\r?\n" +
                                                                  ", t.tea\r?\n" +
@@ -142,57 +80,92 @@ public class TestStringTemplateInheritance extends UtilTestSuiteNoDB {
                                                                  ", t.tenant_record_id\r?\n" +
                                                                  "from kombucha t\r?\n" +
                                                                  "where t.tenant_record_id = :tenantRecordId\r?\n" +
-                                                                 "limit 1\r?\n" +
+                                                                 "order by t.record_id ASC\r?\n" +
                                                                  ";");
-        assertPattern(kombucha.getInstanceOf("addHistoryFromTransaction").toString(), "insert into kombucha_history \\(\r?\n" +
-                                                                                      "  id\r?\n" +
-                                                                                      ", target_record_id\r?\n" +
-                                                                                      ", change_type\r?\n" +
-                                                                                      ", tea\r?\n" +
-                                                                                      ", mushroom\r?\n" +
-                                                                                      ", sugar\r?\n" +
-                                                                                      ", account_record_id\r?\n" +
-                                                                                      ", tenant_record_id\r?\n" +
-                                                                                      "\\)\r?\n" +
-                                                                                      "values \\(\r?\n" +
-                                                                                      "  :id\r?\n" +
-                                                                                      ", :targetRecordId\r?\n" +
-                                                                                      ", :changeType\r?\n" +
-                                                                                      ",   :tea\r?\n" +
-                                                                                      ", :mushroom\r?\n" +
-                                                                                      ", :sugar\r?\n" +
-                                                                                      ", :accountRecordId\r?\n" +
-                                                                                      ", :tenantRecordId\r?\n" +
-                                                                                      "\\)\r?\n" +
-                                                                                      ";");
+        assertPattern(kombucha.getInstanceOf("get")
+                              .add("orderBy", "record_id")
+                              .add("offset", "3")
+                              .add("rowCount", "12")
+                              .add("ordering", "ASC")
+                              .render(), "select\r?\n" +
+                                         "  t.record_id\r?\n" +
+                                         ", t.id\r?\n" +
+                                         ", t.tea\r?\n" +
+                                         ", t.mushroom\r?\n" +
+                                         ", t.sugar\r?\n" +
+                                         ", t.account_record_id\r?\n" +
+                                         ", t.tenant_record_id\r?\n" +
+                                         "from kombucha t\r?\n" +
+                                         "join \\(\r?\n" +
+                                         "  select record_id\r?\n" +
+                                         "  from kombucha\r?\n" +
+                                         "  where tenant_record_id = :tenantRecordId\r?\n" +
+                                         "  order by record_id ASC\r?\n" +
+                                         "  limit :rowCount offset :offset\r?\n" +
+                                         "\\) optimization on optimization.record_id = t.record_id\r?\n" +
+                                         "order by t.record_id ASC\r?\n" +
+                                         ";");
+        assertPattern(kombucha.getInstanceOf("test").render(), "select\r?\n" +
+                                                               "  t.record_id\r?\n" +
+                                                               ", t.id\r?\n" +
+                                                               ", t.tea\r?\n" +
+                                                               ", t.mushroom\r?\n" +
+                                                               ", t.sugar\r?\n" +
+                                                               ", t.account_record_id\r?\n" +
+                                                               ", t.tenant_record_id\r?\n" +
+                                                               "from kombucha t\r?\n" +
+                                                               "where t.tenant_record_id = :tenantRecordId\r?\n" +
+                                                               "limit 1\r?\n" +
+                                                               ";");
+        assertPattern(kombucha.getInstanceOf("addHistoryFromTransaction").render(), "insert into kombucha_history \\(\r?\n" +
+                                                                                    "  id\r?\n" +
+                                                                                    ", target_record_id\r?\n" +
+                                                                                    ", change_type\r?\n" +
+                                                                                    ", tea\r?\n" +
+                                                                                    ", mushroom\r?\n" +
+                                                                                    ", sugar\r?\n" +
+                                                                                    ", account_record_id\r?\n" +
+                                                                                    ", tenant_record_id\r?\n" +
+                                                                                    "\\)\r?\n" +
+                                                                                    "values \\(\r?\n" +
+                                                                                    "  :id\r?\n" +
+                                                                                    ", :targetRecordId\r?\n" +
+                                                                                    ", :changeType\r?\n" +
+                                                                                    ", :tea\r?\n" +
+                                                                                    ", :mushroom\r?\n" +
+                                                                                    ", :sugar\r?\n" +
+                                                                                    ", :accountRecordId\r?\n" +
+                                                                                    ", :tenantRecordId\r?\n" +
+                                                                                    "\\)\r?\n" +
+                                                                                    ";");
 
-        assertPattern(kombucha.getInstanceOf("insertAuditFromTransaction").toString(), "insert into audit_log \\(\r?\n" +
-                                                                                       "id\r?\n" +
-                                                                                       ", table_name\r?\n" +
-                                                                                       ", target_record_id\r?\n" +
-                                                                                       ", change_type\r?\n" +
-                                                                                       ", created_by\r?\n" +
-                                                                                       ", reason_code\r?\n" +
-                                                                                       ", comments\r?\n" +
-                                                                                       ", user_token\r?\n" +
-                                                                                       ", created_date\r?\n" +
-                                                                                       ", account_record_id\r?\n" +
-                                                                                       ", tenant_record_id\r?\n" +
-                                                                                       "\\)\r?\n" +
-                                                                                       "values \\(\r?\n" +
-                                                                                       "  :id\r?\n" +
-                                                                                       ", :tableName\r?\n" +
-                                                                                       ", :targetRecordId\r?\n" +
-                                                                                       ", :changeType\r?\n" +
-                                                                                       ", :createdBy\r?\n" +
-                                                                                       ", :reasonCode\r?\n" +
-                                                                                       ", :comments\r?\n" +
-                                                                                       ", :userToken\r?\n" +
-                                                                                       ", :createdDate\r?\n" +
-                                                                                       ", :accountRecordId\r?\n" +
-                                                                                       ", :tenantRecordId\r?\n" +
-                                                                                       "\\)\r?\n" +
-                                                                                       ";");
+        assertPattern(kombucha.getInstanceOf("insertAuditFromTransaction").render(), "insert into audit_log \\(\r?\n" +
+                                                                                     "id\r?\n" +
+                                                                                     ", table_name\r?\n" +
+                                                                                     ", target_record_id\r?\n" +
+                                                                                     ", change_type\r?\n" +
+                                                                                     ", created_by\r?\n" +
+                                                                                     ", reason_code\r?\n" +
+                                                                                     ", comments\r?\n" +
+                                                                                     ", user_token\r?\n" +
+                                                                                     ", created_date\r?\n" +
+                                                                                     ", account_record_id\r?\n" +
+                                                                                     ", tenant_record_id\r?\n" +
+                                                                                     "\\)\r?\n" +
+                                                                                     "values \\(\r?\n" +
+                                                                                     "  :id\r?\n" +
+                                                                                     ", :tableName\r?\n" +
+                                                                                     ", :targetRecordId\r?\n" +
+                                                                                     ", :changeType\r?\n" +
+                                                                                     ", :createdBy\r?\n" +
+                                                                                     ", :reasonCode\r?\n" +
+                                                                                     ", :comments\r?\n" +
+                                                                                     ", :userToken\r?\n" +
+                                                                                     ", :createdDate\r?\n" +
+                                                                                     ", :accountRecordId\r?\n" +
+                                                                                     ", :tenantRecordId\r?\n" +
+                                                                                     "\\)\r?\n" +
+                                                                                     ";");
     }
 
     private void assertPattern(final String actual, final String expected) {
diff --git a/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java b/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java
index 02c6361..d2dc3a1 100644
--- a/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java
+++ b/util/src/test/java/org/killbill/billing/util/dao/TestStringTemplateInheritanceWithJdbi.java
@@ -24,7 +24,7 @@ import org.killbill.billing.util.UtilTestSuiteWithEmbeddedDB;
 import org.killbill.billing.util.entity.Entity;
 import org.killbill.billing.util.entity.dao.EntityModelDao;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
-import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.template.KillBillSqlDaoStringTemplate;
 
 public class TestStringTemplateInheritanceWithJdbi extends UtilTestSuiteWithEmbeddedDB {
 
@@ -32,7 +32,7 @@ public class TestStringTemplateInheritanceWithJdbi extends UtilTestSuiteWithEmbe
 
     private static interface KombuchaModelDao extends EntityModelDao<Kombucha> {}
 
-    @EntitySqlDaoStringTemplate("/org/killbill/billing/util/dao/Kombucha.sql.stg")
+    @KillBillSqlDaoStringTemplate("/org/killbill/billing/util/dao/Kombucha.sql.stg")
     private static interface KombuchaSqlDao extends EntitySqlDao<KombuchaModelDao, Kombucha> {
 
         @SqlQuery
diff --git a/util/src/test/resources/org/killbill/billing/util/dao/Kombucha.sql.stg b/util/src/test/resources/org/killbill/billing/util/dao/Kombucha.sql.stg
index cbb4410..52dbbc8 100644
--- a/util/src/test/resources/org/killbill/billing/util/dao/Kombucha.sql.stg
+++ b/util/src/test/resources/org/killbill/billing/util/dao/Kombucha.sql.stg
@@ -1,4 +1,4 @@
-group Kombucha: EntitySqlDao;
+import "org/killbill/billing/util/entity/dao/EntitySqlDao.sql.stg"
 
 tableName() ::= "kombucha"