killbill-aplcache

analytics: more work, saving the current tree Signed-off-by:

4/3/2013 8:39:12 PM

Changes

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/BusinessTagDao.java 154(+0 -154)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/DefaultAnalyticsDao.java 82(+0 -82)

osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/PaymentMethodUtils.java 60(+0 -60)

Details

diff --git a/osgi-bundles/bundles/analytics/pom.xml b/osgi-bundles/bundles/analytics/pom.xml
index fcf710f..bacce02 100644
--- a/osgi-bundles/bundles/analytics/pom.xml
+++ b/osgi-bundles/bundles/analytics/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill-osgi-bundles</artifactId>
-        <version>0.1.62-SNAPSHOT</version>
+        <version>0.1.63-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-osgi-bundles-analytics</artifactId>
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java
index 0f61ebd..f7e5e6b 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/AnalyticsListener.java
@@ -27,19 +27,25 @@ import com.ning.billing.beatrix.bus.api.ExtBusEvent;
 import com.ning.billing.commons.locker.GlobalLock;
 import com.ning.billing.commons.locker.GlobalLocker;
 import com.ning.billing.commons.locker.mysql.MySqlGlobalLocker;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoicePaymentDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessOverdueStatusDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionDao;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
 import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
 import com.ning.killbill.osgi.libs.killbill.OSGIKillbillEventDispatcher.OSGIKillbillEventHandler;
 import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
 
-public class AnalyticsListener extends BusinessAnalyticsBase implements OSGIKillbillEventHandler {
+public class AnalyticsListener implements OSGIKillbillEventHandler {
 
-    private static final int NB_LOCK_TRY = 5;
+    private static final String ANALYTICS_NB_LOCK_TRY_PROPERTY = "killbill.osgi.analytics.lock.count";
+    private static final int NB_LOCK_TRY = Integer.parseInt(System.getProperty(ANALYTICS_NB_LOCK_TRY_PROPERTY, "5"));
 
+    private final LogService logService;
     private final BusinessAccountDao bacDao;
     private final BusinessSubscriptionTransitionDao bstDao;
     private final BusinessInvoiceDao binDao;
@@ -47,8 +53,10 @@ public class AnalyticsListener extends BusinessAnalyticsBase implements OSGIKill
     private final BusinessOverdueStatusDao bosDao;
     private final GlobalLocker locker;
 
-    public AnalyticsListener(final OSGIKillbillLogService logService, final OSGIKillbillAPI osgiKillbillAPI, final OSGIKillbillDataSource osgiKillbillDataSource) {
-        super(logService, osgiKillbillAPI);
+    public AnalyticsListener(final OSGIKillbillLogService logService,
+                             final OSGIKillbillAPI osgiKillbillAPI,
+                             final OSGIKillbillDataSource osgiKillbillDataSource) {
+        this.logService = logService;
 
         this.bacDao = new BusinessAccountDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
         this.bstDao = new BusinessSubscriptionTransitionDao(logService, osgiKillbillAPI, osgiKillbillDataSource);
@@ -106,11 +114,10 @@ public class AnalyticsListener extends BusinessAnalyticsBase implements OSGIKill
     }
 
     private void handleSubscriptionEvent(final ExtBusEvent killbillEvent, final CallContext callContext) throws AnalyticsRefreshException {
-        final UUID bundleId = getBundleIdFromEvent(killbillEvent, callContext);
         updateWithAccountLock(killbillEvent, new Callable<Void>() {
             @Override
             public Void call() throws Exception {
-                bstDao.update(bundleId, callContext);
+                bstDao.update(killbillEvent.getAccountId(), callContext);
                 return null;
             }
         });
@@ -127,11 +134,10 @@ public class AnalyticsListener extends BusinessAnalyticsBase implements OSGIKill
     }
 
     private void handlePaymentEvent(final ExtBusEvent killbillEvent, final CallContext callContext) throws AnalyticsRefreshException {
-        final UUID paymentId = getPaymentIdFromEvent(killbillEvent, callContext);
         updateWithAccountLock(killbillEvent, new Callable<Void>() {
             @Override
             public Void call() throws Exception {
-                bipDao.update(killbillEvent.getAccountId(), paymentId, callContext);
+                bipDao.update(killbillEvent.getAccountId(), callContext);
                 return null;
             }
         });
@@ -147,26 +153,6 @@ public class AnalyticsListener extends BusinessAnalyticsBase implements OSGIKill
         });
     }
 
-    private UUID getBundleIdFromEvent(final ExtBusEvent killbillEvent, final TenantContext tenantContext) throws AnalyticsRefreshException {
-        switch (killbillEvent.getObjectType()) {
-            case BUNDLE:
-                return killbillEvent.getObjectId();
-            case SUBSCRIPTION:
-                return getSubscription(killbillEvent.getObjectId(), tenantContext).getBundleId();
-            default:
-                return null;
-        }
-    }
-
-    private UUID getPaymentIdFromEvent(final ExtBusEvent killbillEvent, final TenantContext tenantContext) {
-        switch (killbillEvent.getObjectType()) {
-            case PAYMENT:
-                return killbillEvent.getObjectId();
-            default:
-                return null;
-        }
-    }
-
     private static final class AnalyticsCallContext implements CallContext {
 
         private static final String USER_NAME = AnalyticsListener.class.getName();
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessAccount.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessAccount.java
index b9fa7c0..594a312 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessAccount.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessAccount.java
@@ -21,7 +21,7 @@ import java.math.BigDecimal;
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
 
 public class BusinessAccount extends BusinessEntityBase {
 
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessField.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessField.java
index f864353..211774d 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessField.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessField.java
@@ -17,10 +17,10 @@
 package com.ning.billing.osgi.bundles.analytics.api;
 
 import com.ning.billing.ObjectType;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountFieldModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessFieldModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceFieldModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoicePaymentFieldModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountFieldModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessFieldModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceFieldModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentFieldModelDao;
 
 public class BusinessField extends BusinessEntityBase {
 
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoice.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoice.java
index 2a2fd6b..80290e1 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoice.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoice.java
@@ -24,8 +24,8 @@ import java.util.UUID;
 
 import org.joda.time.LocalDate;
 
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceItemBaseModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceModelDao;
 
 public class BusinessInvoice extends BusinessEntityBase {
 
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoiceItem.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoiceItem.java
index 8b3674c..25aca32 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoiceItem.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoiceItem.java
@@ -23,7 +23,7 @@ import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceItemBaseModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemBaseModelDao;
 
 public class BusinessInvoiceItem extends BusinessEntityBase {
 
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoicePayment.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoicePayment.java
index 65d5a29..e0bd52a 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoicePayment.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessInvoicePayment.java
@@ -23,7 +23,7 @@ import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoicePaymentBaseModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentBaseModelDao;
 
 public class BusinessInvoicePayment extends BusinessEntityBase {
 
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessOverdueStatus.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessOverdueStatus.java
index 1b8f04b..12b1b65 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessOverdueStatus.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessOverdueStatus.java
@@ -19,7 +19,7 @@ package com.ning.billing.osgi.bundles.analytics.api;
 import org.joda.time.DateTime;
 
 import com.ning.billing.ObjectType;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessOverdueStatusModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessOverdueStatusModelDao;
 
 public class BusinessOverdueStatus extends BusinessEntityBase {
 
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessSubscriptionTransition.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessSubscriptionTransition.java
index ddf25fd..6def0a8 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessSubscriptionTransition.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessSubscriptionTransition.java
@@ -21,7 +21,7 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscriptionTransitionModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
 
 public class BusinessSubscriptionTransition extends BusinessEntityBase {
 
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessTag.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessTag.java
index aad236c..6f5aabd 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessTag.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/BusinessTag.java
@@ -17,10 +17,10 @@
 package com.ning.billing.osgi.bundles.analytics.api;
 
 import com.ning.billing.ObjectType;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountTagModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoicePaymentTagModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceTagModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessTagModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountTagModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentTagModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceTagModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessTagModelDao;
 
 public class BusinessTag extends BusinessEntityBase {
 
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/user/AnalyticsUserApi.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/user/AnalyticsUserApi.java
index 1631771..f6d9d81 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/user/AnalyticsUserApi.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/api/user/AnalyticsUserApi.java
@@ -35,13 +35,8 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.analytics.api.TimeSeriesData;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.Blockable.Type;
-import com.ning.billing.osgi.bundles.analytics.BusinessAccountDao;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
 import com.ning.billing.osgi.bundles.analytics.BusinessAnalyticsBase;
-import com.ning.billing.osgi.bundles.analytics.BusinessInvoiceDao;
-import com.ning.billing.osgi.bundles.analytics.BusinessInvoicePaymentDao;
-import com.ning.billing.osgi.bundles.analytics.BusinessOverdueStatusDao;
-import com.ning.billing.osgi.bundles.analytics.BusinessSubscriptionTransitionDao;
-import com.ning.billing.osgi.bundles.analytics.BusinessTagDao;
 import com.ning.billing.osgi.bundles.analytics.api.BusinessAccount;
 import com.ning.billing.osgi.bundles.analytics.api.BusinessField;
 import com.ning.billing.osgi.bundles.analytics.api.BusinessInvoice;
@@ -51,12 +46,18 @@ import com.ning.billing.osgi.bundles.analytics.api.BusinessSnapshot;
 import com.ning.billing.osgi.bundles.analytics.api.BusinessSubscriptionTransition;
 import com.ning.billing.osgi.bundles.analytics.api.BusinessTag;
 import com.ning.billing.osgi.bundles.analytics.dao.AnalyticsDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountTagModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoicePaymentModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessOverdueStatusModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscriptionTransitionModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoicePaymentDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessOverdueStatusDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessTagDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountTagModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessOverdueStatusModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.util.callcontext.CallContext;
@@ -118,13 +119,11 @@ public class AnalyticsUserApi extends BusinessAnalyticsBase {
     }
 
     public BusinessSnapshot getBusinessSnapshot(final Account account, final TenantContext context) {
-        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
-
         // Find account
         final BusinessAccount businessAccount = getAccountByKey(account.getExternalKey(), context);
 
         // Find all transitions for all bundles for that account, and associated overdue statuses
-        final List<SubscriptionBundle> bundles = entitlementInternalApi.getBundlesForAccount(account.getId(), internalTenantContext);
+        final List<SubscriptionBundle> bundles = entitlementInternalApi.getBundlesForAccount(account.getId(), context);
         final Collection<BusinessSubscriptionTransition> businessSubscriptionTransitions = new ArrayList<BusinessSubscriptionTransition>();
         final Collection<BusinessOverdueStatus> businessOverdueStatuses = new ArrayList<BusinessOverdueStatus>();
         for (final SubscriptionBundle bundle : bundles) {
@@ -150,7 +149,7 @@ public class AnalyticsUserApi extends BusinessAnalyticsBase {
     }
 
     public BusinessAccount getAccountByKey(final String accountKey, final TenantContext context) {
-        final BusinessAccountModelDao accountByKey = analyticsDao.getAccountByKey(accountKey, internalCallContextFactory.createInternalTenantContext(context));
+        final BusinessAccountModelDao accountByKey = analyticsDao.getAccountByKey(accountKey, context);
         if (accountByKey == null) {
             return null;
         } else {
@@ -159,7 +158,7 @@ public class AnalyticsUserApi extends BusinessAnalyticsBase {
     }
 
     public List<BusinessSubscriptionTransition> getTransitionsForBundle(final String externalKey, final TenantContext context) {
-        final List<BusinessSubscriptionTransitionModelDao> transitionsByKey = analyticsDao.getTransitionsByKey(externalKey, internalCallContextFactory.createInternalTenantContext(context));
+        final List<BusinessSubscriptionTransitionModelDao> transitionsByKey = analyticsDao.getSubscriptionTransitionsByBundleExternalKey(externalKey, context);
         return ImmutableList.<BusinessSubscriptionTransition>copyOf(Collections2.transform(transitionsByKey, new Function<BusinessSubscriptionTransitionModelDao, BusinessSubscriptionTransition>() {
 
             public BusinessSubscriptionTransition apply(@Nullable final BusinessSubscriptionTransitionModelDao input) {
@@ -169,7 +168,7 @@ public class AnalyticsUserApi extends BusinessAnalyticsBase {
     }
 
     public List<BusinessInvoice> getInvoicesForAccount(final String accountKey, final TenantContext context) {
-        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
+        final InternalTenantContext internalTenantContext = context;
         final List<BusinessInvoiceModelDao> invoicesByKey = analyticsDao.getInvoicesByKey(accountKey, internalTenantContext);
         return ImmutableList.<BusinessInvoice>copyOf(Collections2.transform(invoicesByKey, new Function<BusinessInvoiceModelDao, BusinessInvoice>() {
 
@@ -180,7 +179,7 @@ public class AnalyticsUserApi extends BusinessAnalyticsBase {
     }
 
     public List<BusinessInvoicePayment> getInvoicePaymentsForAccount(final String accountKey, final TenantContext context) {
-        final List<BusinessInvoicePaymentModelDao> invoicePaymentsForAccountByKey = analyticsDao.getInvoicePaymentsForAccountByKey(accountKey, internalCallContextFactory.createInternalTenantContext(context));
+        final List<BusinessInvoicePaymentModelDao> invoicePaymentsForAccountByKey = analyticsDao.getInvoicePaymentsForAccountByKey(accountKey, context);
         return ImmutableList.<BusinessInvoicePayment>copyOf(Collections2.transform(invoicePaymentsForAccountByKey, new Function<BusinessInvoicePaymentModelDao, BusinessInvoicePayment>() {
 
             public BusinessInvoicePayment apply(@Nullable final BusinessInvoicePaymentModelDao input) {
@@ -190,7 +189,7 @@ public class AnalyticsUserApi extends BusinessAnalyticsBase {
     }
 
     public List<BusinessOverdueStatus> getOverdueStatusesForBundle(final String externalKey, final TenantContext context) {
-        final List<BusinessOverdueStatusModelDao> overdueStatusesForBundleByKey = analyticsDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContextFactory.createInternalTenantContext(context));
+        final List<BusinessOverdueStatusModelDao> overdueStatusesForBundleByKey = analyticsDao.getOverdueStatusesForBundleByKey(externalKey, context);
         return ImmutableList.<BusinessOverdueStatus>copyOf(Collections2.transform(overdueStatusesForBundleByKey, new Function<BusinessOverdueStatusModelDao, BusinessOverdueStatus>() {
 
             public BusinessOverdueStatus apply(@Nullable final BusinessOverdueStatusModelDao input) {
@@ -200,7 +199,7 @@ public class AnalyticsUserApi extends BusinessAnalyticsBase {
     }
 
     public List<BusinessTag> getTagsForAccount(final String accountKey, final TenantContext context) {
-        final List<BusinessAccountTagModelDao> tagsForAccount = analyticsDao.getTagsForAccount(accountKey, internalCallContextFactory.createInternalTenantContext(context));
+        final List<BusinessAccountTagModelDao> tagsForAccount = analyticsDao.getTagsForAccount(accountKey, context);
         return ImmutableList.<BusinessTag>copyOf(Collections2.transform(tagsForAccount, new Function<BusinessAccountTagModelDao, BusinessTag>() {
 
             public BusinessTag apply(@Nullable final BusinessAccountTagModelDao input) {
@@ -210,28 +209,26 @@ public class AnalyticsUserApi extends BusinessAnalyticsBase {
     }
 
     public TimeSeriesData getAccountsCreatedOverTime(final TenantContext context) {
-        return analyticsDao.getAccountsCreatedOverTime(internalCallContextFactory.createInternalTenantContext(context));
+        return analyticsDao.getAccountsCreatedOverTime(context);
     }
 
     public TimeSeriesData getSubscriptionsCreatedOverTime(final String productType, final String slug, final TenantContext context) {
-        return analyticsDao.getSubscriptionsCreatedOverTime(productType, slug, internalCallContextFactory.createInternalTenantContext(context));
+        return analyticsDao.getSubscriptionsCreatedOverTime(productType, slug, context);
     }
 
-    public void rebuildAnalyticsForAccount(final Account account, final CallContext context) {
-        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), context);
-
+    public void rebuildAnalyticsForAccount(final Account account, final CallContext context) throws AnalyticsRefreshException {
         // Update the BAC row
-        bacDao.accountUpdated(account.getId(), internalCallContext);
+        bacDao.update(account.getId(), context);
 
         // Update BST for all bundles
-        final Set<UUID> bundleIds = updateBST(account, internalCallContext);
+        final Set<UUID> bundleIds = updateBST(account, context);
 
-        // Update BIN and BII for all invoices
-        invoiceDao.rebuildInvoicesForAccount(account.getId(), internalCallContext);
+        // Update BIN, BII, ... for all invoices
+        invoiceDao.update(account.getId(), context);
 
         // Update BIP for all invoices
         try {
-            updateBIP(account, internalCallContext);
+            updateBIP(account, context);
         } catch (PaymentApiException e) {
             // Log and ignore
             log.warn(e.toString());
@@ -240,12 +237,12 @@ public class AnalyticsUserApi extends BusinessAnalyticsBase {
         // Update BOS for all bundles (only blockable supported today)
         // TODO: support other blockables
         for (final UUID bundleId : bundleIds) {
-            bosDao.overdueStatusChanged(Type.SUBSCRIPTION_BUNDLE, bundleId, internalCallContext);
+            bosDao.overdueStatusChanged(Type.SUBSCRIPTION_BUNDLE, bundleId, context);
         }
 
         // Update bac_tags
         // TODO: refresh all tags
-        updateTags(account, internalCallContext);
+        updateTags(account, context);
     }
 
     private Set<UUID> updateBST(final Account account, final InternalCallContext internalCallContext) {
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/BusinessAnalyticsBase.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/BusinessAnalyticsBase.java
index 5889dee..f877953 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/BusinessAnalyticsBase.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/BusinessAnalyticsBase.java
@@ -43,20 +43,29 @@ import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.invoice.api.InvoiceUserApi;
+import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.junction.api.JunctionApi;
 import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentMethod;
 import com.ning.billing.util.api.AuditLevel;
 import com.ning.billing.util.api.AuditUserApi;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagDefinitionApiException;
+import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.audit.AuditLog;
 import com.ning.billing.util.audit.AuditLogsForAccount;
 import com.ning.billing.util.audit.ChangeType;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.TenantContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.tag.Tag;
+import com.ning.billing.util.tag.TagDefinition;
 import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
 import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
 
+// Wrapper around Kill Bill APIs
 public abstract class BusinessAnalyticsBase {
 
     protected final OSGIKillbillLogService logService;
@@ -129,6 +138,42 @@ public abstract class BusinessAnalyticsBase {
         }
     }
 
+    protected AuditLog getSubscriptionEventCreationAuditLog(final UUID subscriptionEventId, final TenantContext context) throws AnalyticsRefreshException {
+        final List<AuditLog> auditLogsForSubscriptionEvent = getAuditUserApi().getAuditLogs(subscriptionEventId, ObjectType.SUBSCRIPTION_EVENT, AuditLevel.MINIMAL, context);
+        for (final AuditLog auditLog : auditLogsForSubscriptionEvent) {
+            if (auditLog.getChangeType().equals(ChangeType.INSERT)) {
+                return auditLog;
+            }
+        }
+
+        throw new AnalyticsRefreshException("Unable to find Subscription event creation audit log for id " + subscriptionEventId);
+    }
+
+    //
+    // OVERDUE
+    //
+
+    protected List<BlockingState> getBlockingHistory(final UUID overdueableId, final TenantContext context) throws AnalyticsRefreshException {
+        final JunctionApi junctionUserApi = getJunctionUserApi();
+        return junctionUserApi.getBlockingHistory(overdueableId, context);
+    }
+
+    //
+    // BLOCKING STATES
+    //
+
+    protected AuditLog getBlockingStateCreationAuditLog(final UUID blockingStateId, final TenantContext context) throws AnalyticsRefreshException {
+        // TODO
+        final List<AuditLog> auditLogsForBlockingState = getAuditUserApi().getAuditLogs(blockingStateId, null, AuditLevel.MINIMAL, context);
+        for (final AuditLog auditLog : auditLogsForBlockingState) {
+            if (auditLog.getChangeType().equals(ChangeType.INSERT)) {
+                return auditLog;
+            }
+        }
+
+        throw new AnalyticsRefreshException("Unable to find Blocking state creation audit log for id " + blockingStateId);
+    }
+
     //
     // INVOICE
     //
@@ -284,6 +329,59 @@ public abstract class BusinessAnalyticsBase {
     }
 
     //
+    // FIELD
+    //
+
+    protected Collection<CustomField> getFieldsForAccountAndObjectType(final UUID accountId, final ObjectType objectType, final TenantContext context) throws AnalyticsRefreshException {
+        final CustomFieldUserApi tagUserApi = getCustomFieldUserApi();
+        // TODO
+        return tagUserApi.getCustomFieldsForAccount(accountId, objectType, context);
+    }
+
+    protected AuditLog getFieldCreationAuditLog(final UUID fieldId, final TenantContext context) throws AnalyticsRefreshException {
+        final List<AuditLog> auditLogsForTag = getAuditUserApi().getAuditLogs(fieldId, ObjectType.CUSTOM_FIELD, AuditLevel.MINIMAL, context);
+        for (final AuditLog auditLog : auditLogsForTag) {
+            if (auditLog.getChangeType().equals(ChangeType.INSERT)) {
+                return auditLog;
+            }
+        }
+
+        throw new AnalyticsRefreshException("Unable to find Field creation audit log for id " + fieldId);
+    }
+
+    //
+    // TAG
+    //
+
+    protected Collection<Tag> getTagsForAccountAndObjectType(final UUID accountId, final ObjectType objectType, final TenantContext context) throws AnalyticsRefreshException {
+        final TagUserApi tagUserApi = getTagUserApi();
+        // TODO
+        return tagUserApi.getTagsForAccount(accountId, objectType, context);
+    }
+
+    protected TagDefinition getTagDefinition(final UUID tagDefinitionId, final TenantContext context) throws AnalyticsRefreshException {
+        final TagUserApi tagUserApi = getTagUserApi();
+
+        try {
+            return tagUserApi.getTagDefinition(tagDefinitionId, context);
+        } catch (TagDefinitionApiException e) {
+            logService.log(LogService.LOG_WARNING, "Error retrieving tag definition for id " + tagDefinitionId, e);
+            throw new AnalyticsRefreshException(e);
+        }
+    }
+
+    protected AuditLog getTagCreationAuditLog(final UUID tagId, final TenantContext context) throws AnalyticsRefreshException {
+        final List<AuditLog> auditLogsForTag = getAuditUserApi().getAuditLogs(tagId, ObjectType.TAG, AuditLevel.MINIMAL, context);
+        for (final AuditLog auditLog : auditLogsForTag) {
+            if (auditLog.getChangeType().equals(ChangeType.INSERT)) {
+                return auditLog;
+            }
+        }
+
+        throw new AnalyticsRefreshException("Unable to find Tag creation audit log for id " + tagId);
+    }
+
+    //
     // APIs
     //
 
@@ -311,6 +409,14 @@ public abstract class BusinessAnalyticsBase {
         return entitlementUserApi;
     }
 
+    private JunctionApi getJunctionUserApi() throws AnalyticsRefreshException {
+        final JunctionApi junctionApi = osgiKillbillAPI.getJunctionApi();
+        if (junctionApi == null) {
+            throw new AnalyticsRefreshException("Error retrieving junctionApi");
+        }
+        return junctionApi;
+    }
+
     private InvoiceUserApi getInvoiceUserApi() throws AnalyticsRefreshException {
         final InvoiceUserApi invoiceUserApi = osgiKillbillAPI.getInvoiceUserApi();
         if (invoiceUserApi == null) {
@@ -342,4 +448,20 @@ public abstract class BusinessAnalyticsBase {
         }
         return invoicePaymentApi;
     }
+
+    private CustomFieldUserApi getCustomFieldUserApi() throws AnalyticsRefreshException {
+        final CustomFieldUserApi fieldUserApi = osgiKillbillAPI.getCustomFieldUserApi();
+        if (fieldUserApi == null) {
+            throw new AnalyticsRefreshException("Error retrieving fieldUserApi");
+        }
+        return fieldUserApi;
+    }
+
+    private TagUserApi getTagUserApi() throws AnalyticsRefreshException {
+        final TagUserApi tagUserApi = osgiKillbillAPI.getTagUserApi();
+        if (tagUserApi == null) {
+            throw new AnalyticsRefreshException("Error retrieving tagUserApi");
+        }
+        return tagUserApi;
+    }
 }
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/AnalyticsDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/AnalyticsDao.java
index 0541d46..f5c8333 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/AnalyticsDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/AnalyticsDao.java
@@ -2,7 +2,7 @@
  * Copyright 2010-2013 Ning, Inc.
  *
  * Ning 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
+ * (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
@@ -14,39 +14,45 @@
  * under the License.
  */
 
-package com.ning.billing.osgi.bundles.analytics.dao;
+package com.ning.billing.osgi.bundles.analytics.dao
 
 import java.util.List;
 
-import com.ning.billing.analytics.api.TimeSeriesData;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountTagModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceItemModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoicePaymentModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessOverdueStatusModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscriptionTransitionModelDao;
-import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountTagModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessOverdueStatusModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
+import com.ning.billing.util.callcontext.TenantContext;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
 
-public interface AnalyticsDao {
+public class AnalyticsDao extends BusinessAnalyticsDaoBase {
 
-    TimeSeriesData getAccountsCreatedOverTime(InternalTenantContext context);
+    public AnalyticsDao(final OSGIKillbillLogService logService,
+                        final OSGIKillbillAPI osgiKillbillAPI,
+                        final OSGIKillbillDataSource osgiKillbillDataSource) {
+        super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+    }
 
-    TimeSeriesData getSubscriptionsCreatedOverTime(String productType, String slug, InternalTenantContext context);
+    public BusinessAccountModelDao getAccountByKey(final String accountExternalKey, final TenantContext context) {
+    }
 
-    BusinessAccountModelDao getAccountByKey(String accountKey, InternalTenantContext context);
+    public List<BusinessSubscriptionTransitionModelDao> getSubscriptionTransitionsByBundleExternalKey(final String bundleExternalKey, final TenantContext context) {
+    }
 
-    List<BusinessSubscriptionTransitionModelDao> getTransitionsByKey(String externalKey, InternalTenantContext context);
+    public List<BusinessSubscriptionTransitionModelDao> getTransitionsForAccount(String accountKey, TenantContext context) {}
 
-    List<BusinessSubscriptionTransitionModelDao> getTransitionsForAccount(String accountKey, InternalTenantContext context);
+    public List<BusinessInvoiceModelDao> getInvoicesByAccountKey(String accountExternalKey, TenantContext context) {}
 
-    List<BusinessInvoiceModelDao> getInvoicesByKey(String accountKey, InternalTenantContext context);
+    public List<BusinessInvoiceItemModelDao> getInvoiceItemsForAccountKey(String accountExternalKey, TenantContext context) {}
 
-    List<BusinessInvoiceItemModelDao> getInvoiceItemsForInvoice(String invoiceId, InternalTenantContext context);
+    public List<BusinessInvoicePaymentModelDao> getInvoicePaymentsForAccountByKey(String accountExternalKey, TenantContext context) {}
 
-    List<BusinessInvoicePaymentModelDao> getInvoicePaymentsForAccountByKey(String accountKey, InternalTenantContext context);
+    public List<BusinessOverdueStatusModelDao> getOverdueStatusesForBundleByExternalKey(String bundleExternalKey, TenantContext context) {}
 
-    List<BusinessOverdueStatusModelDao> getOverdueStatusesForBundleByKey(String externalKey, InternalTenantContext context);
-
-    List<BusinessAccountTagModelDao> getTagsForAccount(String accountKey, InternalTenantContext context);
+    public List<BusinessAccountTagModelDao> getTagsForAccount(String accountKey, TenantContext context) {}
 }
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsSqlDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsSqlDao.java
index 8506cf7..ed577e3 100644
--- a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessAnalyticsSqlDao.java
@@ -18,12 +18,14 @@ package com.ning.billing.osgi.bundles.analytics.dao;
 
 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.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.UseStringTemplate3StatementLocator;
 
-import com.ning.billing.osgi.bundles.analytics.model.BusinessModelDaoBase;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessModelDaoBase;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 @UseStringTemplate3StatementLocator
 public interface BusinessAnalyticsSqlDao extends Transactional<BusinessAnalyticsSqlDao> {
@@ -38,4 +40,9 @@ public interface BusinessAnalyticsSqlDao extends Transactional<BusinessAnalytics
                                         @Bind("accountRecordId") final Long accountRecordId,
                                         @Bind("tenantRecordId") final Long tenantRecordId,
                                         @BindBean final CallContext callContext);
+
+    @SqlQuery
+    public Iterable findByAccountRecordId(@Bind("tableName") final String tableName,
+                                          @Bind("accountRecordId") final Long accountRecordId,
+                                          @BindBean final TenantContext callContext);
 }
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessFieldDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessFieldDao.java
new file mode 100644
index 0000000..391cd5e
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessFieldDao.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.osgi.bundles.analytics.dao;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessFieldModelDao;
+import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+public class BusinessFieldDao extends BusinessAnalyticsDaoBase {
+
+    public BusinessFieldDao(final OSGIKillbillLogService logService,
+                            final OSGIKillbillAPI osgiKillbillAPI,
+                            final OSGIKillbillDataSource osgiKillbillDataSource) {
+        super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+    }
+
+    public void update(final UUID accountId, final ObjectType objectType, final CallContext context) throws AnalyticsRefreshException {
+        final Account account = getAccount(accountId, context);
+
+        final Collection<BusinessFieldModelDao> fieldModelDaos = createBusinessFields(account, objectType, context);
+
+        sqlDao.inTransaction(new Transaction<Void, BusinessAnalyticsSqlDao>() {
+            @Override
+            public Void inTransaction(final BusinessAnalyticsSqlDao transactional, final TransactionStatus status) throws Exception {
+                updateInTransaction(fieldModelDaos, transactional, context);
+                return null;
+            }
+        });
+    }
+
+    private void updateInTransaction(final Collection<BusinessFieldModelDao> fieldModelDaos, final BusinessAnalyticsSqlDao transactional, final CallContext context) {
+        if (fieldModelDaos.size() == 0) {
+            return;
+        }
+
+        // We assume all fieldModelDaos are for a single type
+        final BusinessFieldModelDao firstFieldModelDao = fieldModelDaos.iterator().next();
+        transactional.deleteByAccountRecordId(firstFieldModelDao.getTableName(), firstFieldModelDao.getAccountRecordId(), firstFieldModelDao.getTenantRecordId(), context);
+
+        for (final BusinessFieldModelDao fieldModelDao : fieldModelDaos) {
+            transactional.create(fieldModelDao.getTableName(), fieldModelDao, context);
+        }
+    }
+
+    private Collection<BusinessFieldModelDao> createBusinessFields(final Account account, final ObjectType objectType, final CallContext context) throws AnalyticsRefreshException {
+        final Collection<CustomField> fields = getFieldsForAccountAndObjectType(account.getId(), objectType, context);
+
+        final Collection<BusinessFieldModelDao> fieldModelDaos = new LinkedList<BusinessFieldModelDao>();
+        for (final CustomField field : fields) {
+            final AuditLog creationAuditLog = getFieldCreationAuditLog(field.getId(), context);
+            final BusinessFieldModelDao fieldModelDao = BusinessFieldModelDao.create(account, field, creationAuditLog);
+            fieldModelDaos.add(fieldModelDao);
+        }
+
+        return fieldModelDaos;
+    }
+}
diff --git a/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessTagDao.java b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessTagDao.java
new file mode 100644
index 0000000..c35c23a
--- /dev/null
+++ b/osgi-bundles/bundles/analytics/src/main/java/com/ning/billing/osgi/bundles/analytics/dao/BusinessTagDao.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.osgi.bundles.analytics.dao;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.osgi.bundles.analytics.AnalyticsRefreshException;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessTagModelDao;
+import com.ning.billing.util.audit.AuditLog;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.tag.Tag;
+import com.ning.billing.util.tag.TagDefinition;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillAPI;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillDataSource;
+import com.ning.killbill.osgi.libs.killbill.OSGIKillbillLogService;
+
+public class BusinessTagDao extends BusinessAnalyticsDaoBase {
+
+    public BusinessTagDao(final OSGIKillbillLogService logService,
+                          final OSGIKillbillAPI osgiKillbillAPI,
+                          final OSGIKillbillDataSource osgiKillbillDataSource) {
+        super(logService, osgiKillbillAPI, osgiKillbillDataSource);
+    }
+
+    public void update(final UUID accountId, final ObjectType objectType, final CallContext context) throws AnalyticsRefreshException {
+        final Account account = getAccount(accountId, context);
+
+        final Collection<BusinessTagModelDao> tagModelDaos = createBusinessTags(account, objectType, context);
+
+        sqlDao.inTransaction(new Transaction<Void, BusinessAnalyticsSqlDao>() {
+            @Override
+            public Void inTransaction(final BusinessAnalyticsSqlDao transactional, final TransactionStatus status) throws Exception {
+                updateInTransaction(tagModelDaos, transactional, context);
+                return null;
+            }
+        });
+    }
+
+    private void updateInTransaction(final Collection<BusinessTagModelDao> tagModelDaos, final BusinessAnalyticsSqlDao transactional, final CallContext context) {
+        if (tagModelDaos.size() == 0) {
+            return;
+        }
+
+        // We assume all tagModelDaos are for a single type
+        final BusinessTagModelDao firstTagModelDao = tagModelDaos.iterator().next();
+        transactional.deleteByAccountRecordId(firstTagModelDao.getTableName(), firstTagModelDao.getAccountRecordId(), firstTagModelDao.getTenantRecordId(), context);
+
+        for (final BusinessTagModelDao tagModelDao : tagModelDaos) {
+            transactional.create(tagModelDao.getTableName(), tagModelDao, context);
+        }
+    }
+
+    private Collection<BusinessTagModelDao> createBusinessTags(final Account account, final ObjectType objectType, final CallContext context) throws AnalyticsRefreshException {
+        final Collection<Tag> tags = getTagsForAccountAndObjectType(account.getId(), objectType, context);
+
+        final Collection<BusinessTagModelDao> tagModelDaos = new LinkedList<BusinessTagModelDao>();
+        for (final Tag tag : tags) {
+            final TagDefinition tagDefinition = getTagDefinition(tag.getTagDefinitionId(), context);
+            final AuditLog creationAuditLog = getTagCreationAuditLog(tag.getId(), context);
+            final BusinessTagModelDao tagModelDao = BusinessTagModelDao.create(account, tag, tagDefinition, creationAuditLog);
+            tagModelDaos.add(tagModelDao);
+        }
+
+        return tagModelDaos;
+    }
+}
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteNoDB.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteNoDB.java
index dd2bba8..d9dd13a 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteNoDB.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteNoDB.java
@@ -27,9 +27,11 @@ import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.invoice.dao.InvoiceDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountFieldSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountTagSqlDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceFieldSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceItemSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoicePaymentFieldSqlDao;
@@ -37,10 +39,13 @@ import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoicePaymentSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoicePaymentTagSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceTagSqlDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessOverdueStatusDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessOverdueStatusSqlDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionFieldSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionTagSqlDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessTagDao;
 import com.ning.billing.osgi.bundles.analytics.glue.TestAnalyticsModuleNoDB;
 import com.ning.billing.payment.dao.PaymentDao;
 import com.ning.billing.util.glue.RealImplementation;
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteWithEmbeddedDB.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteWithEmbeddedDB.java
index 974e701..a8d3596 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteWithEmbeddedDB.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/AnalyticsTestSuiteWithEmbeddedDB.java
@@ -28,9 +28,11 @@ import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.invoice.dao.InvoiceDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountFieldSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessAccountTagSqlDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceFieldSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceItemSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoicePaymentFieldSqlDao;
@@ -38,10 +40,13 @@ import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoicePaymentSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoicePaymentTagSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessInvoiceTagSqlDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessOverdueStatusDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessOverdueStatusSqlDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionFieldSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionTagSqlDao;
+import com.ning.billing.osgi.bundles.analytics.dao.BusinessTagDao;
 import com.ning.billing.osgi.bundles.analytics.glue.TestAnalyticsModuleWithEmbeddedDB;
 import com.ning.billing.payment.dao.PaymentDao;
 import com.ning.billing.util.glue.RealImplementation;
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/user/TestDefaultAnalyticsUserApi.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/user/TestDefaultAnalyticsUserApi.java
index c7cb17d..cfc56ce 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/user/TestDefaultAnalyticsUserApi.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/api/user/TestDefaultAnalyticsUserApi.java
@@ -38,10 +38,10 @@ import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
 import com.ning.billing.osgi.bundles.analytics.MockDuration;
 import com.ning.billing.osgi.bundles.analytics.MockPhase;
 import com.ning.billing.osgi.bundles.analytics.MockProduct;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscription;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscriptionEvent;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscriptionTransitionModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscription;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionEvent;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
 
 public class TestDefaultAnalyticsUserApi extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestAnalyticsDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestAnalyticsDao.java
index 07aa037..9e179c1 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestAnalyticsDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestAnalyticsDao.java
@@ -39,10 +39,10 @@ import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
 import com.ning.billing.osgi.bundles.analytics.MockDuration;
 import com.ning.billing.osgi.bundles.analytics.MockPhase;
 import com.ning.billing.osgi.bundles.analytics.MockProduct;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountModelDao;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscription;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscriptionEvent;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscriptionTransitionModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscription;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionEvent;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.osgi.bundles.analytics.utils.Rounder;
 
 public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessAccountFieldSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessAccountFieldSqlDao.java
index c664b30..4365eef 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessAccountFieldSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessAccountFieldSqlDao.java
@@ -23,7 +23,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountFieldModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountFieldModelDao;
 
 public class TestBusinessAccountFieldSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessAccountTagSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessAccountTagSqlDao.java
index 597adcc..7a68821 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessAccountTagSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessAccountTagSqlDao.java
@@ -23,7 +23,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessAccountTagModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountTagModelDao;
 
 public class TestBusinessAccountTagSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceFieldSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
index 234a7c9..0c25c1d 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
@@ -23,7 +23,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceFieldModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceFieldModelDao;
 
 public class TestBusinessInvoiceFieldSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceItemSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceItemSqlDao.java
index d6997fb..bfd1f5d 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceItemSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceItemSqlDao.java
@@ -26,7 +26,7 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceItemModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemModelDao;
 
 public class TestBusinessInvoiceItemSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
index 0c4b38d..26227c9 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
@@ -23,7 +23,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoicePaymentFieldModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentFieldModelDao;
 
 public class TestBusinessInvoicePaymentFieldSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
index c8445c4..c241c19 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
@@ -26,7 +26,7 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoicePaymentModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentModelDao;
 
 public class TestBusinessInvoicePaymentSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
index 6ef7ab5..71a4a99 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
@@ -23,7 +23,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoicePaymentTagModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentTagModelDao;
 
 public class TestBusinessInvoicePaymentTagSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceSqlDao.java
index 61a7b44..114a2a1 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceSqlDao.java
@@ -26,7 +26,7 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceModelDao;
 
 public class TestBusinessInvoiceSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceTagSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceTagSqlDao.java
index 06118ba..85bddfd 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceTagSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessInvoiceTagSqlDao.java
@@ -23,7 +23,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceTagModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceTagModelDao;
 
 public class TestBusinessInvoiceTagSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessOverdueStatusSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessOverdueStatusSqlDao.java
index 880fc49..e3f4a9a 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessOverdueStatusSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/dao/TestBusinessOverdueStatusSqlDao.java
@@ -24,7 +24,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessOverdueStatusModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessOverdueStatusModelDao;
 
 public class TestBusinessOverdueStatusSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/MockBusinessSubscriptionTransitionSqlDao.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/MockBusinessSubscriptionTransitionSqlDao.java
index f9ee7bc..95ca97b 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/MockBusinessSubscriptionTransitionSqlDao.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/MockBusinessSubscriptionTransitionSqlDao.java
@@ -29,7 +29,7 @@ import org.testng.Assert;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionBinder;
 import com.ning.billing.osgi.bundles.analytics.dao.BusinessSubscriptionTransitionSqlDao;
 import com.ning.billing.osgi.bundles.analytics.dao.TimeSeriesTuple;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscriptionTransitionModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccount.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccount.java
index 1e99805..8944eef 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccount.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccount.java
@@ -26,6 +26,7 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.account.api.Account;
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountModelDao;
 
 public class TestBusinessAccount extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccountField.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccountField.java
index 5fd381a..dd85fcf 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccountField.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccountField.java
@@ -22,6 +22,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountFieldModelDao;
 
 public class TestBusinessAccountField extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccountTag.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccountTag.java
index 2691132..54c744e 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccountTag.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessAccountTag.java
@@ -22,6 +22,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessAccountTagModelDao;
 
 public class TestBusinessAccountTag extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoice.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoice.java
index c2cb8c7..6ea1f5e 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoice.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoice.java
@@ -26,6 +26,7 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceModelDao;
 
 public class TestBusinessInvoice extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceField.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceField.java
index 6287f82..2886b04 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceField.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceField.java
@@ -22,6 +22,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceFieldModelDao;
 
 public class TestBusinessInvoiceField extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceItem.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceItem.java
index 5c7663e..174f07d 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceItem.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceItem.java
@@ -26,6 +26,7 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemModelDao;
 
 public class TestBusinessInvoiceItem extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePayment.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePayment.java
index b609d54..4a53754 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePayment.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePayment.java
@@ -26,6 +26,7 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentModelDao;
 
 public class TestBusinessInvoicePayment extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePaymentField.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePaymentField.java
index 5db7895..5aba6b8 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePaymentField.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePaymentField.java
@@ -22,6 +22,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentFieldModelDao;
 
 public class TestBusinessInvoicePaymentField extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePaymentTag.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePaymentTag.java
index 9336ffe..69f8042 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePaymentTag.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoicePaymentTag.java
@@ -22,6 +22,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoicePaymentTagModelDao;
 
 public class TestBusinessInvoicePaymentTag extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceTag.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceTag.java
index 91fc4d3..4cf9fe3 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceTag.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessInvoiceTag.java
@@ -22,6 +22,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceTagModelDao;
 
 public class TestBusinessInvoiceTag extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessOverdueStatus.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessOverdueStatus.java
index c813681..9e58be8 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessOverdueStatus.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessOverdueStatus.java
@@ -24,6 +24,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessOverdueStatusModelDao;
 
 public class TestBusinessOverdueStatus extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscription.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscription.java
index 869b3d4..9a7afe8 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscription.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscription.java
@@ -38,6 +38,7 @@ import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
 import com.ning.billing.osgi.bundles.analytics.MockDuration;
 import com.ning.billing.osgi.bundles.analytics.MockPhase;
 import com.ning.billing.osgi.bundles.analytics.MockProduct;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscription;
 
 import static com.ning.billing.catalog.api.Currency.USD;
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscriptionEvent.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscriptionEvent.java
index 1dbf626..6df40d3 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscriptionEvent.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscriptionEvent.java
@@ -35,6 +35,7 @@ import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
 import com.ning.billing.osgi.bundles.analytics.MockDuration;
 import com.ning.billing.osgi.bundles.analytics.MockPhase;
 import com.ning.billing.osgi.bundles.analytics.MockProduct;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionEvent;
 
 public class TestBusinessSubscriptionEvent extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscriptionTransition.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscriptionTransition.java
index 9bc0d4a..1f8366f 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscriptionTransition.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/model/TestBusinessSubscriptionTransition.java
@@ -38,6 +38,9 @@ import com.ning.billing.osgi.bundles.analytics.AnalyticsTestSuiteNoDB;
 import com.ning.billing.osgi.bundles.analytics.MockDuration;
 import com.ning.billing.osgi.bundles.analytics.MockPhase;
 import com.ning.billing.osgi.bundles.analytics.MockProduct;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscription;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionEvent;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
 
 import static com.ning.billing.catalog.api.Currency.USD;
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestBusinessInvoiceRecorder.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestBusinessInvoiceRecorder.java
index 37c7ebd..ba733ec 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestBusinessInvoiceRecorder.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestBusinessInvoiceRecorder.java
@@ -27,7 +27,7 @@ import org.testng.annotations.Test;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessInvoiceItemModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessInvoiceItemModelDao;
 
 public class TestBusinessInvoiceRecorder extends AnalyticsTestSuiteNoDB {
 
diff --git a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestBusinessSubscriptionTransitionRecorder.java b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestBusinessSubscriptionTransitionRecorder.java
index 4beae31..fd2d65e 100644
--- a/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestBusinessSubscriptionTransitionRecorder.java
+++ b/osgi-bundles/bundles/analytics/src/test/java/com/ning/billing/osgi/bundles/analytics/TestBusinessSubscriptionTransitionRecorder.java
@@ -29,7 +29,7 @@ import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
-import com.ning.billing.osgi.bundles.analytics.model.BusinessSubscriptionTransitionModelDao;
+import com.ning.billing.osgi.bundles.analytics.dao.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.events.EffectiveSubscriptionInternalEvent;