killbill-aplcache

Changes

Details

diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/DefaultAnalyticsService.java b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultAnalyticsService.java
index 3a54f5b..caf05e1 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/api/DefaultAnalyticsService.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultAnalyticsService.java
@@ -19,12 +19,14 @@ package com.ning.billing.analytics.api;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.inject.Inject;
 import com.ning.billing.analytics.AnalyticsListener;
 import com.ning.billing.lifecycle.LifecycleHandlerType;
 import com.ning.billing.util.svcsapi.bus.InternalBus;
 
+import com.google.inject.Inject;
+
 public class DefaultAnalyticsService implements AnalyticsService {
+
     private static final Logger log = LoggerFactory.getLogger(DefaultAnalyticsService.class);
 
     private static final String ANALYTICS_SERVICE = "analytics-service";
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessAccount.java b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessAccount.java
new file mode 100644
index 0000000..938456a
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessAccount.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import java.math.BigDecimal;
+
+import org.joda.time.LocalDate;
+
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
+import com.ning.billing.util.entity.EntityBase;
+
+public class DefaultBusinessAccount extends EntityBase implements BusinessAccount {
+
+    private final String externalKey;
+    private final String name;
+    private final String currency;
+    private final BigDecimal balance;
+    private final LocalDate lastInvoiceDate;
+    private final BigDecimal totalInvoiceBalance;
+    private final String lastPaymentStatus;
+    private final String defaultPaymentMethodType;
+    private final String defaultCreditCardType;
+    private final String defaultBillingAddressCountry;
+
+    public DefaultBusinessAccount(final BusinessAccountModelDao businessAccountModelDao) {
+        this.externalKey = businessAccountModelDao.getKey();
+        this.name = businessAccountModelDao.getName();
+        this.currency = businessAccountModelDao.getCurrency();
+        this.balance = businessAccountModelDao.getBalance();
+        this.lastInvoiceDate = businessAccountModelDao.getLastInvoiceDate();
+        this.totalInvoiceBalance = businessAccountModelDao.getTotalInvoiceBalance();
+        this.lastPaymentStatus = businessAccountModelDao.getLastPaymentStatus();
+        this.defaultPaymentMethodType = businessAccountModelDao.getPaymentMethod();
+        this.defaultCreditCardType = businessAccountModelDao.getCreditCardType();
+        this.defaultBillingAddressCountry = businessAccountModelDao.getBillingAddressCountry();
+    }
+
+    @Override
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getCurrency() {
+        return currency;
+    }
+
+    @Override
+    public BigDecimal getBalance() {
+        return balance;
+    }
+
+    @Override
+    public LocalDate getLastInvoiceDate() {
+        return lastInvoiceDate;
+    }
+
+    @Override
+    public BigDecimal getTotalInvoiceBalance() {
+        return totalInvoiceBalance;
+    }
+
+    @Override
+    public String getLastPaymentStatus() {
+        return lastPaymentStatus;
+    }
+
+    @Override
+    public String getDefaultPaymentMethodType() {
+        return defaultPaymentMethodType;
+    }
+
+    @Override
+    public String getDefaultCreditCardType() {
+        return defaultCreditCardType;
+    }
+
+    @Override
+    public String getDefaultBillingAddressCountry() {
+        return defaultBillingAddressCountry;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultBusinessAccount");
+        sb.append("{externalKey='").append(externalKey).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append(", currency='").append(currency).append('\'');
+        sb.append(", balance=").append(balance);
+        sb.append(", lastInvoiceDate=").append(lastInvoiceDate);
+        sb.append(", totalInvoiceBalance=").append(totalInvoiceBalance);
+        sb.append(", lastPaymentStatus='").append(lastPaymentStatus).append('\'');
+        sb.append(", defaultPaymentMethodType='").append(defaultPaymentMethodType).append('\'');
+        sb.append(", defaultCreditCardType='").append(defaultCreditCardType).append('\'');
+        sb.append(", defaultBillingAddressCountry='").append(defaultBillingAddressCountry).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultBusinessAccount that = (DefaultBusinessAccount) o;
+
+        if (balance != null ? !balance.equals(that.balance) : that.balance != null) {
+            return false;
+        }
+        if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
+            return false;
+        }
+        if (defaultBillingAddressCountry != null ? !defaultBillingAddressCountry.equals(that.defaultBillingAddressCountry) : that.defaultBillingAddressCountry != null) {
+            return false;
+        }
+        if (defaultCreditCardType != null ? !defaultCreditCardType.equals(that.defaultCreditCardType) : that.defaultCreditCardType != null) {
+            return false;
+        }
+        if (defaultPaymentMethodType != null ? !defaultPaymentMethodType.equals(that.defaultPaymentMethodType) : that.defaultPaymentMethodType != null) {
+            return false;
+        }
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+            return false;
+        }
+        if (lastInvoiceDate != null ? !lastInvoiceDate.equals(that.lastInvoiceDate) : that.lastInvoiceDate != null) {
+            return false;
+        }
+        if (lastPaymentStatus != null ? !lastPaymentStatus.equals(that.lastPaymentStatus) : that.lastPaymentStatus != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        if (totalInvoiceBalance != null ? !totalInvoiceBalance.equals(that.totalInvoiceBalance) : that.totalInvoiceBalance != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = externalKey != null ? externalKey.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (balance != null ? balance.hashCode() : 0);
+        result = 31 * result + (lastInvoiceDate != null ? lastInvoiceDate.hashCode() : 0);
+        result = 31 * result + (totalInvoiceBalance != null ? totalInvoiceBalance.hashCode() : 0);
+        result = 31 * result + (lastPaymentStatus != null ? lastPaymentStatus.hashCode() : 0);
+        result = 31 * result + (defaultPaymentMethodType != null ? defaultPaymentMethodType.hashCode() : 0);
+        result = 31 * result + (defaultCreditCardType != null ? defaultCreditCardType.hashCode() : 0);
+        result = 31 * result + (defaultBillingAddressCountry != null ? defaultBillingAddressCountry.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessField.java b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessField.java
new file mode 100644
index 0000000..c047a7e
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessField.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.analytics.model.BusinessAccountFieldModelDao;
+import com.ning.billing.analytics.model.BusinessFieldModelDao;
+import com.ning.billing.analytics.model.BusinessInvoiceFieldModelDao;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentFieldModelDao;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionFieldModelDao;
+import com.ning.billing.util.entity.EntityBase;
+
+public class DefaultBusinessField extends EntityBase implements BusinessField {
+
+    private final ObjectType objectType;
+    private final String name;
+    private final String value;
+
+    DefaultBusinessField(final ObjectType objectType, final BusinessFieldModelDao businessFieldModelDao) {
+        super(businessFieldModelDao.getId());
+        this.objectType = objectType;
+        this.name = businessFieldModelDao.getName();
+        this.value = businessFieldModelDao.getValue();
+    }
+
+    public DefaultBusinessField(final BusinessAccountFieldModelDao businessAccountFieldModelDao) {
+        this(ObjectType.ACCOUNT, businessAccountFieldModelDao);
+    }
+
+    public DefaultBusinessField(final BusinessInvoiceFieldModelDao businessInvoiceFieldModelDao) {
+        this(ObjectType.INVOICE, businessInvoiceFieldModelDao);
+    }
+
+    public DefaultBusinessField(final BusinessInvoicePaymentFieldModelDao businessInvoicePaymentFieldModelDao) {
+        this(ObjectType.PAYMENT, businessInvoicePaymentFieldModelDao);
+    }
+
+    public DefaultBusinessField(final BusinessSubscriptionTransitionFieldModelDao businessSubscriptionTransitionFieldModelDao) {
+        this(ObjectType.BUNDLE, businessSubscriptionTransitionFieldModelDao);
+    }
+
+    @Override
+    public ObjectType getObjectType() {
+        return objectType;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultBusinessField");
+        sb.append("{objectType=").append(objectType);
+        sb.append(", name='").append(name).append('\'');
+        sb.append(", value='").append(value).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultBusinessField that = (DefaultBusinessField) o;
+
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        if (objectType != that.objectType) {
+            return false;
+        }
+        if (value != null ? !value.equals(that.value) : that.value != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = objectType != null ? objectType.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (value != null ? value.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessInvoice.java b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessInvoice.java
new file mode 100644
index 0000000..dcc3ed9
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessInvoice.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.LocalDate;
+
+import com.ning.billing.analytics.model.BusinessInvoiceItemModelDao;
+import com.ning.billing.analytics.model.BusinessInvoiceModelDao;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.entity.EntityBase;
+
+public class DefaultBusinessInvoice extends EntityBase implements BusinessInvoice {
+
+    private final UUID invoiceId;
+    private final Integer invoiceNumber;
+    private final UUID accountId;
+    private final String accountKey;
+    private final LocalDate invoiceDate;
+    private final LocalDate targetDate;
+    private final Currency currency;
+    private final BigDecimal balance;
+    private final BigDecimal amountPaid;
+    private final BigDecimal amountCharged;
+    private final BigDecimal amountCredited;
+    private final List<BusinessInvoiceItem> invoiceItems;
+
+    public DefaultBusinessInvoice(final BusinessInvoiceModelDao businessInvoiceModelDao,
+                                  final Collection<BusinessInvoiceItemModelDao> businessInvoiceItemModelDaos) {
+        super(businessInvoiceModelDao.getInvoiceId(), businessInvoiceModelDao.getCreatedDate(), businessInvoiceModelDao.getUpdatedDate());
+        this.accountId = businessInvoiceModelDao.getAccountId();
+        this.accountKey = businessInvoiceModelDao.getAccountKey();
+        this.amountCharged = businessInvoiceModelDao.getAmountCharged();
+        this.amountCredited = businessInvoiceModelDao.getAmountCredited();
+        this.amountPaid = businessInvoiceModelDao.getAmountPaid();
+        this.balance = businessInvoiceModelDao.getBalance();
+        this.currency = businessInvoiceModelDao.getCurrency();
+        this.invoiceDate = businessInvoiceModelDao.getInvoiceDate();
+        this.invoiceId = businessInvoiceModelDao.getInvoiceId();
+        this.invoiceNumber = businessInvoiceModelDao.getInvoiceNumber();
+        this.targetDate = businessInvoiceModelDao.getTargetDate();
+        this.invoiceItems = toInvoiceItems(businessInvoiceItemModelDaos);
+    }
+
+    private List<BusinessInvoiceItem> toInvoiceItems(final Collection<BusinessInvoiceItemModelDao> businessInvoiceItemModelDaos) {
+        final List<BusinessInvoiceItem> businessInvoiceItems = new ArrayList<BusinessInvoiceItem>();
+        for (final BusinessInvoiceItemModelDao businessInvoiceItemModelDao : businessInvoiceItemModelDaos) {
+            businessInvoiceItems.add(new BusinessInvoiceItem() {
+                @Override
+                public UUID getItemId() {
+                    return businessInvoiceItemModelDao.getItemId();
+                }
+
+                @Override
+                public UUID getInvoiceId() {
+                    return businessInvoiceItemModelDao.getInvoiceId();
+                }
+
+                @Override
+                public String getItemType() {
+                    return businessInvoiceItemModelDao.getItemType();
+                }
+
+                @Override
+                public String getExternalKey() {
+                    return businessInvoiceItemModelDao.getExternalKey();
+                }
+
+                @Override
+                public String getProductName() {
+                    return businessInvoiceItemModelDao.getProductName();
+                }
+
+                @Override
+                public String getProductType() {
+                    return businessInvoiceItemModelDao.getProductType();
+                }
+
+                @Override
+                public String getProductCategory() {
+                    return businessInvoiceItemModelDao.getProductCategory();
+                }
+
+                @Override
+                public String getSlug() {
+                    return businessInvoiceItemModelDao.getSlug();
+                }
+
+                @Override
+                public String getPhase() {
+                    return businessInvoiceItemModelDao.getPhase();
+                }
+
+                @Override
+                public String getBillingPeriod() {
+                    return businessInvoiceItemModelDao.getBillingPeriod();
+                }
+
+                @Override
+                public LocalDate getStartDate() {
+                    return businessInvoiceItemModelDao.getStartDate();
+                }
+
+                @Override
+                public LocalDate getEndDate() {
+                    return businessInvoiceItemModelDao.getEndDate();
+                }
+
+                @Override
+                public BigDecimal getAmount() {
+                    return businessInvoiceItemModelDao.getAmount();
+                }
+
+                @Override
+                public Currency getCurrency() {
+                    return businessInvoiceItemModelDao.getCurrency();
+                }
+
+                @Override
+                public UUID getLinkedItemId() {
+                    return businessInvoiceItemModelDao.getLinkedItemId();
+                }
+            });
+        }
+
+        return businessInvoiceItems;
+    }
+
+    @Override
+    public UUID getInvoiceId() {
+        return invoiceId;
+    }
+
+    @Override
+    public Integer getInvoiceNumber() {
+        return invoiceNumber;
+    }
+
+    @Override
+    public UUID getAccountId() {
+        return accountId;
+    }
+
+    @Override
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    @Override
+    public LocalDate getInvoiceDate() {
+        return invoiceDate;
+    }
+
+    @Override
+    public LocalDate getTargetDate() {
+        return targetDate;
+    }
+
+    @Override
+    public Currency getCurrency() {
+        return currency;
+    }
+
+    @Override
+    public BigDecimal getBalance() {
+        return balance;
+    }
+
+    @Override
+    public BigDecimal getAmountPaid() {
+        return amountPaid;
+    }
+
+    @Override
+    public BigDecimal getAmountCharged() {
+        return amountCharged;
+    }
+
+    @Override
+    public BigDecimal getAmountCredited() {
+        return amountCredited;
+    }
+
+    @Override
+    public List<BusinessInvoiceItem> getInvoiceItems() {
+        return invoiceItems;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultBusinessInvoice");
+        sb.append("{invoiceId=").append(invoiceId);
+        sb.append(", invoiceNumber=").append(invoiceNumber);
+        sb.append(", accountId=").append(accountId);
+        sb.append(", accountKey='").append(accountKey).append('\'');
+        sb.append(", invoiceDate=").append(invoiceDate);
+        sb.append(", targetDate=").append(targetDate);
+        sb.append(", currency=").append(currency);
+        sb.append(", balance=").append(balance);
+        sb.append(", amountPaid=").append(amountPaid);
+        sb.append(", amountCharged=").append(amountCharged);
+        sb.append(", amountCredited=").append(amountCredited);
+        sb.append(", invoiceItemsSize=").append(invoiceItems.size());
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultBusinessInvoice that = (DefaultBusinessInvoice) o;
+
+        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+            return false;
+        }
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (amountCharged != null ? !amountCharged.equals(that.amountCharged) : that.amountCharged != null) {
+            return false;
+        }
+        if (amountCredited != null ? !amountCredited.equals(that.amountCredited) : that.amountCredited != null) {
+            return false;
+        }
+        if (amountPaid != null ? !amountPaid.equals(that.amountPaid) : that.amountPaid != null) {
+            return false;
+        }
+        if (balance != null ? !balance.equals(that.balance) : that.balance != null) {
+            return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (invoiceDate != null ? !invoiceDate.equals(that.invoiceDate) : that.invoiceDate != null) {
+            return false;
+        }
+        if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
+            return false;
+        }
+        if (invoiceItems != null ? invoiceItems.size() != that.invoiceItems.size() : that.invoiceItems != null) {
+            return false;
+        }
+        if (invoiceNumber != null ? !invoiceNumber.equals(that.invoiceNumber) : that.invoiceNumber != null) {
+            return false;
+        }
+        if (targetDate != null ? !targetDate.equals(that.targetDate) : that.targetDate != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = invoiceId != null ? invoiceId.hashCode() : 0;
+        result = 31 * result + (invoiceNumber != null ? invoiceNumber.hashCode() : 0);
+        result = 31 * result + (accountId != null ? accountId.hashCode() : 0);
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
+        result = 31 * result + (invoiceDate != null ? invoiceDate.hashCode() : 0);
+        result = 31 * result + (targetDate != null ? targetDate.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (balance != null ? balance.hashCode() : 0);
+        result = 31 * result + (amountPaid != null ? amountPaid.hashCode() : 0);
+        result = 31 * result + (amountCharged != null ? amountCharged.hashCode() : 0);
+        result = 31 * result + (amountCredited != null ? amountCredited.hashCode() : 0);
+        result = 31 * result + (invoiceItems != null ? invoiceItems.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessInvoicePayment.java b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessInvoicePayment.java
new file mode 100644
index 0000000..77897b7
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessInvoicePayment.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.analytics.model.BusinessInvoicePaymentModelDao;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.entity.EntityBase;
+
+public class DefaultBusinessInvoicePayment extends EntityBase implements BusinessInvoicePayment {
+
+    private final UUID paymentId;
+    private final String extFirstPaymentRefId;
+    private final String extSecondPaymentRefId;
+    private final String accountKey;
+    private final UUID invoiceId;
+    private final DateTime effectiveDate;
+    private final BigDecimal amount;
+    private final Currency currency;
+    private final String paymentError;
+    private final String processingStatus;
+    private final BigDecimal requestedAmount;
+    private final String pluginName;
+    private final String paymentType;
+    private final String paymentMethod;
+    private final String cardType;
+    private final String cardCountry;
+    private final String invoicePaymentType;
+    private final UUID linkedInvoicePaymentId;
+
+    public DefaultBusinessInvoicePayment(final BusinessInvoicePaymentModelDao businessInvoicePaymentModelDao) {
+        this.paymentId = businessInvoicePaymentModelDao.getPaymentId();
+        this.extFirstPaymentRefId = businessInvoicePaymentModelDao.getExtFirstPaymentRefId();
+        this.extSecondPaymentRefId = businessInvoicePaymentModelDao.getExtSecondPaymentRefId();
+        this.accountKey = businessInvoicePaymentModelDao.getAccountKey();
+        this.invoiceId = businessInvoicePaymentModelDao.getInvoiceId();
+        this.effectiveDate = businessInvoicePaymentModelDao.getEffectiveDate();
+        this.amount = businessInvoicePaymentModelDao.getAmount();
+        this.currency = businessInvoicePaymentModelDao.getCurrency();
+        this.paymentError = businessInvoicePaymentModelDao.getPaymentError();
+        this.processingStatus = businessInvoicePaymentModelDao.getProcessingStatus();
+        this.requestedAmount = businessInvoicePaymentModelDao.getRequestedAmount();
+        this.pluginName = businessInvoicePaymentModelDao.getPluginName();
+        this.paymentType = businessInvoicePaymentModelDao.getPaymentType();
+        this.paymentMethod = businessInvoicePaymentModelDao.getPaymentMethod();
+        this.cardType = businessInvoicePaymentModelDao.getCardType();
+        this.cardCountry = businessInvoicePaymentModelDao.getCardCountry();
+        this.invoicePaymentType = businessInvoicePaymentModelDao.getInvoicePaymentType();
+        this.linkedInvoicePaymentId = businessInvoicePaymentModelDao.getLinkedInvoicePaymentId();
+    }
+
+    @Override
+    public UUID getPaymentId() {
+        return paymentId;
+    }
+
+    @Override
+    public String getExtFirstPaymentRefId() {
+        return extFirstPaymentRefId;
+    }
+
+    @Override
+    public String getExtSecondPaymentRefId() {
+        return extSecondPaymentRefId;
+    }
+
+    @Override
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    @Override
+    public UUID getInvoiceId() {
+        return invoiceId;
+    }
+
+    @Override
+    public DateTime getEffectiveDate() {
+        return effectiveDate;
+    }
+
+    @Override
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    @Override
+    public Currency getCurrency() {
+        return currency;
+    }
+
+    @Override
+    public String getPaymentError() {
+        return paymentError;
+    }
+
+    @Override
+    public String getProcessingStatus() {
+        return processingStatus;
+    }
+
+    @Override
+    public BigDecimal getRequestedAmount() {
+        return requestedAmount;
+    }
+
+    @Override
+    public String getPluginName() {
+        return pluginName;
+    }
+
+    @Override
+    public String getPaymentType() {
+        return paymentType;
+    }
+
+    @Override
+    public String getPaymentMethod() {
+        return paymentMethod;
+    }
+
+    @Override
+    public String getCardType() {
+        return cardType;
+    }
+
+    @Override
+    public String getCardCountry() {
+        return cardCountry;
+    }
+
+    @Override
+    public String getInvoicePaymentType() {
+        return invoicePaymentType;
+    }
+
+    @Override
+    public UUID getLinkedInvoicePaymentId() {
+        return linkedInvoicePaymentId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultBusinessInvoicePayment");
+        sb.append("{paymentId=").append(paymentId);
+        sb.append(", extFirstPaymentRefId='").append(extFirstPaymentRefId).append('\'');
+        sb.append(", extSecondPaymentRefId='").append(extSecondPaymentRefId).append('\'');
+        sb.append(", accountKey='").append(accountKey).append('\'');
+        sb.append(", invoiceId=").append(invoiceId);
+        sb.append(", effectiveDate=").append(effectiveDate);
+        sb.append(", amount=").append(amount);
+        sb.append(", currency=").append(currency);
+        sb.append(", paymentError='").append(paymentError).append('\'');
+        sb.append(", processingStatus='").append(processingStatus).append('\'');
+        sb.append(", requestedAmount=").append(requestedAmount);
+        sb.append(", pluginName='").append(pluginName).append('\'');
+        sb.append(", paymentType='").append(paymentType).append('\'');
+        sb.append(", paymentMethod='").append(paymentMethod).append('\'');
+        sb.append(", cardType='").append(cardType).append('\'');
+        sb.append(", cardCountry='").append(cardCountry).append('\'');
+        sb.append(", invoicePaymentType='").append(invoicePaymentType).append('\'');
+        sb.append(", linkedInvoicePaymentId=").append(linkedInvoicePaymentId);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultBusinessInvoicePayment that = (DefaultBusinessInvoicePayment) o;
+
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (amount != null ? !amount.equals(that.amount) : that.amount != null) {
+            return false;
+        }
+        if (cardCountry != null ? !cardCountry.equals(that.cardCountry) : that.cardCountry != null) {
+            return false;
+        }
+        if (cardType != null ? !cardType.equals(that.cardType) : that.cardType != null) {
+            return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (effectiveDate != null ? !effectiveDate.equals(that.effectiveDate) : that.effectiveDate != null) {
+            return false;
+        }
+        if (extFirstPaymentRefId != null ? !extFirstPaymentRefId.equals(that.extFirstPaymentRefId) : that.extFirstPaymentRefId != null) {
+            return false;
+        }
+        if (extSecondPaymentRefId != null ? !extSecondPaymentRefId.equals(that.extSecondPaymentRefId) : that.extSecondPaymentRefId != null) {
+            return false;
+        }
+        if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
+            return false;
+        }
+        if (invoicePaymentType != null ? !invoicePaymentType.equals(that.invoicePaymentType) : that.invoicePaymentType != null) {
+            return false;
+        }
+        if (linkedInvoicePaymentId != null ? !linkedInvoicePaymentId.equals(that.linkedInvoicePaymentId) : that.linkedInvoicePaymentId != null) {
+            return false;
+        }
+        if (paymentError != null ? !paymentError.equals(that.paymentError) : that.paymentError != null) {
+            return false;
+        }
+        if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
+            return false;
+        }
+        if (paymentMethod != null ? !paymentMethod.equals(that.paymentMethod) : that.paymentMethod != null) {
+            return false;
+        }
+        if (paymentType != null ? !paymentType.equals(that.paymentType) : that.paymentType != null) {
+            return false;
+        }
+        if (pluginName != null ? !pluginName.equals(that.pluginName) : that.pluginName != null) {
+            return false;
+        }
+        if (processingStatus != null ? !processingStatus.equals(that.processingStatus) : that.processingStatus != null) {
+            return false;
+        }
+        if (requestedAmount != null ? !requestedAmount.equals(that.requestedAmount) : that.requestedAmount != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = paymentId != null ? paymentId.hashCode() : 0;
+        result = 31 * result + (extFirstPaymentRefId != null ? extFirstPaymentRefId.hashCode() : 0);
+        result = 31 * result + (extSecondPaymentRefId != null ? extSecondPaymentRefId.hashCode() : 0);
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
+        result = 31 * result + (invoiceId != null ? invoiceId.hashCode() : 0);
+        result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
+        result = 31 * result + (amount != null ? amount.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (paymentError != null ? paymentError.hashCode() : 0);
+        result = 31 * result + (processingStatus != null ? processingStatus.hashCode() : 0);
+        result = 31 * result + (requestedAmount != null ? requestedAmount.hashCode() : 0);
+        result = 31 * result + (pluginName != null ? pluginName.hashCode() : 0);
+        result = 31 * result + (paymentType != null ? paymentType.hashCode() : 0);
+        result = 31 * result + (paymentMethod != null ? paymentMethod.hashCode() : 0);
+        result = 31 * result + (cardType != null ? cardType.hashCode() : 0);
+        result = 31 * result + (cardCountry != null ? cardCountry.hashCode() : 0);
+        result = 31 * result + (invoicePaymentType != null ? invoicePaymentType.hashCode() : 0);
+        result = 31 * result + (linkedInvoicePaymentId != null ? linkedInvoicePaymentId.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessOverdueStatus.java b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessOverdueStatus.java
new file mode 100644
index 0000000..68c0a33
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessOverdueStatus.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.analytics.model.BusinessOverdueStatusModelDao;
+import com.ning.billing.util.entity.EntityBase;
+
+public class DefaultBusinessOverdueStatus extends EntityBase implements BusinessOverdueStatus {
+
+    private final ObjectType objectType;
+    private final String accountKey;
+    private final String status;
+    private final DateTime startDate;
+    private final DateTime endDate;
+
+    public DefaultBusinessOverdueStatus(final BusinessOverdueStatusModelDao businessOverdueStatusModelDao) {
+        // TODO
+        super(businessOverdueStatusModelDao.getBundleId());
+        this.objectType = ObjectType.BUNDLE;
+
+        this.accountKey = businessOverdueStatusModelDao.getAccountKey();
+        this.status = businessOverdueStatusModelDao.getStatus();
+        this.startDate = businessOverdueStatusModelDao.getStartDate();
+        this.endDate = businessOverdueStatusModelDao.getEndDate();
+    }
+
+    @Override
+    public ObjectType getObjectType() {
+        return objectType;
+    }
+
+    @Override
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    @Override
+    public String getStatus() {
+        return status;
+    }
+
+    @Override
+    public DateTime getStartDate() {
+        return startDate;
+    }
+
+    @Override
+    public DateTime getEndDate() {
+        return endDate;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultBusinessOverdueStatus");
+        sb.append("{objectType=").append(objectType);
+        sb.append(", id='").append(id).append('\'');
+        sb.append(", accountKey='").append(accountKey).append('\'');
+        sb.append(", status='").append(status).append('\'');
+        sb.append(", startDate=").append(startDate);
+        sb.append(", endDate=").append(endDate);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultBusinessOverdueStatus that = (DefaultBusinessOverdueStatus) o;
+
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (endDate != null ? !endDate.equals(that.endDate) : that.endDate != null) {
+            return false;
+        }
+        if (objectType != that.objectType) {
+            return false;
+        }
+        if (startDate != null ? !startDate.equals(that.startDate) : that.startDate != null) {
+            return false;
+        }
+        if (status != null ? !status.equals(that.status) : that.status != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = objectType != null ? objectType.hashCode() : 0;
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
+        result = 31 * result + (status != null ? status.hashCode() : 0);
+        result = 31 * result + (startDate != null ? startDate.hashCode() : 0);
+        result = 31 * result + (endDate != null ? endDate.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessSnapshot.java b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessSnapshot.java
new file mode 100644
index 0000000..fcfb50a
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessSnapshot.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import java.util.Collection;
+
+public class DefaultBusinessSnapshot implements BusinessSnapshot {
+
+    private final BusinessAccount businessAccount;
+    private final Collection<BusinessSubscriptionTransition> businessSubscriptionTransitions;
+    private final Collection<BusinessInvoice> businessInvoices;
+    private final Collection<BusinessInvoicePayment> businessInvoicePayments;
+    private final Collection<BusinessOverdueStatus> businessOverdueStatuses;
+    private final Collection<BusinessTag> businessTags;
+    private final Collection<BusinessField> businessFields;
+
+    public DefaultBusinessSnapshot(final BusinessAccount businessAccount,
+                                   final Collection<BusinessSubscriptionTransition> businessSubscriptionTransitions,
+                                   final Collection<BusinessInvoice> businessInvoices,
+                                   final Collection<BusinessInvoicePayment> businessInvoicePayments,
+                                   final Collection<BusinessOverdueStatus> businessOverdueStatuses,
+                                   final Collection<BusinessTag> businessTags,
+                                   final Collection<BusinessField> businessFields) {
+        this.businessAccount = businessAccount;
+        this.businessSubscriptionTransitions = businessSubscriptionTransitions;
+        this.businessInvoices = businessInvoices;
+        this.businessInvoicePayments = businessInvoicePayments;
+        this.businessOverdueStatuses = businessOverdueStatuses;
+        this.businessTags = businessTags;
+        this.businessFields = businessFields;
+    }
+
+    @Override
+    public BusinessAccount getBusinessAccount() {
+        return businessAccount;
+    }
+
+    @Override
+    public Collection<BusinessSubscriptionTransition> getBusinessSubscriptionTransitions() {
+        return businessSubscriptionTransitions;
+    }
+
+    @Override
+    public Collection<BusinessInvoice> getBusinessInvoices() {
+        return businessInvoices;
+    }
+
+    @Override
+    public Collection<BusinessInvoicePayment> getBusinessInvoicePayments() {
+        return businessInvoicePayments;
+    }
+
+    @Override
+    public Collection<BusinessOverdueStatus> getBusinessOverdueStatuses() {
+        return businessOverdueStatuses;
+    }
+
+    @Override
+    public Collection<BusinessTag> getBusinessTags() {
+        return businessTags;
+    }
+
+    @Override
+    public Collection<BusinessField> getBusinessFields() {
+        return businessFields;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultBusinessSnapshot");
+        sb.append("{businessAccount=").append(businessAccount);
+        sb.append(", businessSubscriptionTransitions=").append(businessSubscriptionTransitions);
+        sb.append(", businessInvoices=").append(businessInvoices);
+        sb.append(", businessInvoicePayments=").append(businessInvoicePayments);
+        sb.append(", businessOverdueStatuses=").append(businessOverdueStatuses);
+        sb.append(", businessTags=").append(businessTags);
+        sb.append(", businessFields=").append(businessFields);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultBusinessSnapshot that = (DefaultBusinessSnapshot) o;
+
+        if (businessAccount != null ? !businessAccount.equals(that.businessAccount) : that.businessAccount != null) {
+            return false;
+        }
+        if (businessFields != null ? !businessFields.equals(that.businessFields) : that.businessFields != null) {
+            return false;
+        }
+        if (businessInvoicePayments != null ? !businessInvoicePayments.equals(that.businessInvoicePayments) : that.businessInvoicePayments != null) {
+            return false;
+        }
+        if (businessInvoices != null ? !businessInvoices.equals(that.businessInvoices) : that.businessInvoices != null) {
+            return false;
+        }
+        if (businessOverdueStatuses != null ? !businessOverdueStatuses.equals(that.businessOverdueStatuses) : that.businessOverdueStatuses != null) {
+            return false;
+        }
+        if (businessSubscriptionTransitions != null ? !businessSubscriptionTransitions.equals(that.businessSubscriptionTransitions) : that.businessSubscriptionTransitions != null) {
+            return false;
+        }
+        if (businessTags != null ? !businessTags.equals(that.businessTags) : that.businessTags != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = businessAccount != null ? businessAccount.hashCode() : 0;
+        result = 31 * result + (businessSubscriptionTransitions != null ? businessSubscriptionTransitions.hashCode() : 0);
+        result = 31 * result + (businessInvoices != null ? businessInvoices.hashCode() : 0);
+        result = 31 * result + (businessInvoicePayments != null ? businessInvoicePayments.hashCode() : 0);
+        result = 31 * result + (businessOverdueStatuses != null ? businessOverdueStatuses.hashCode() : 0);
+        result = 31 * result + (businessTags != null ? businessTags.hashCode() : 0);
+        result = 31 * result + (businessFields != null ? businessFields.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessSubscriptionTransition.java b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessSubscriptionTransition.java
new file mode 100644
index 0000000..0931a2b
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessSubscriptionTransition.java
@@ -0,0 +1,496 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
+import com.ning.billing.util.entity.EntityBase;
+
+public class DefaultBusinessSubscriptionTransition extends EntityBase implements BusinessSubscriptionTransition {
+
+    private final long totalOrdering;
+    private final UUID bundleId;
+    private final String externalKey;
+    private final UUID accountId;
+    private final String accountKey;
+    private final UUID subscriptionId;
+
+    private final DateTime requestedTimestamp;
+    private final String eventType;
+    private final String category;
+
+    private final String prevProductName;
+    private final String prevProductType;
+    private final String prevProductCategory;
+    private final String prevSlug;
+    private final String prevPhase;
+    private final String prevBillingPeriod;
+    private final BigDecimal prevPrice;
+    private final String prevPriceList;
+    private final BigDecimal prevMrr;
+    private final String prevCurrency;
+    private final DateTime prevStartDate;
+    private final String prevState;
+
+    private final String nextProductName;
+    private final String nextProductType;
+    private final String nextProductCategory;
+    private final String nextSlug;
+    private final String nextPhase;
+    private final String nextBillingPeriod;
+    private final BigDecimal nextPrice;
+    private final String nextPriceList;
+    private final BigDecimal nextMrr;
+    private final String nextCurrency;
+    private final DateTime nextStartDate;
+    private final String nextState;
+
+    public DefaultBusinessSubscriptionTransition(final BusinessSubscriptionTransitionModelDao bstModelDao) {
+        this.totalOrdering = bstModelDao.getTotalOrdering();
+        this.bundleId = bstModelDao.getBundleId();
+        this.externalKey = bstModelDao.getExternalKey();
+        this.accountId = bstModelDao.getAccountId();
+        this.accountKey = bstModelDao.getAccountKey();
+        this.subscriptionId = bstModelDao.getSubscriptionId();
+
+        this.requestedTimestamp = bstModelDao.getRequestedTimestamp();
+        this.eventType = bstModelDao.getEvent().getEventType().toString();
+        if (bstModelDao.getEvent().getCategory() != null) {
+            this.category = bstModelDao.getEvent().getCategory().toString();
+        } else {
+            this.category = null;
+        }
+
+        if (bstModelDao.getPreviousSubscription() != null) {
+            this.prevProductName = bstModelDao.getPreviousSubscription().getProductName();
+            this.prevProductType = bstModelDao.getPreviousSubscription().getProductType();
+            this.prevProductCategory = bstModelDao.getPreviousSubscription().getProductCategory().toString();
+            this.prevSlug = bstModelDao.getPreviousSubscription().getSlug();
+            this.prevPhase = bstModelDao.getPreviousSubscription().getPhase();
+            this.prevBillingPeriod = bstModelDao.getPreviousSubscription().getBillingPeriod();
+            this.prevPrice = bstModelDao.getPreviousSubscription().getPrice();
+            this.prevPriceList = bstModelDao.getPreviousSubscription().getPriceList();
+            this.prevMrr = bstModelDao.getPreviousSubscription().getMrr();
+            this.prevCurrency = bstModelDao.getPreviousSubscription().getCurrency();
+            this.prevStartDate = bstModelDao.getPreviousSubscription().getStartDate();
+            this.prevState = bstModelDao.getPreviousSubscription().getState().toString();
+        } else {
+            this.prevProductName = null;
+            this.prevProductType = null;
+            this.prevProductCategory = null;
+            this.prevSlug = null;
+            this.prevPhase = null;
+            this.prevBillingPeriod = null;
+            this.prevPrice = null;
+            this.prevPriceList = null;
+            this.prevMrr = null;
+            this.prevCurrency = null;
+            this.prevStartDate = null;
+            this.prevState = null;
+        }
+
+        if (bstModelDao.getNextSubscription() != null) {
+            this.nextProductName = bstModelDao.getNextSubscription().getProductName();
+            this.nextProductType = bstModelDao.getNextSubscription().getProductType();
+            this.nextProductCategory = bstModelDao.getNextSubscription().getProductCategory().toString();
+            this.nextSlug = bstModelDao.getNextSubscription().getSlug();
+            this.nextPhase = bstModelDao.getNextSubscription().getPhase();
+            this.nextBillingPeriod = bstModelDao.getNextSubscription().getBillingPeriod();
+            this.nextPrice = bstModelDao.getNextSubscription().getPrice();
+            this.nextPriceList = bstModelDao.getNextSubscription().getPriceList();
+            this.nextMrr = bstModelDao.getNextSubscription().getMrr();
+            this.nextCurrency = bstModelDao.getNextSubscription().getCurrency();
+            this.nextStartDate = bstModelDao.getNextSubscription().getStartDate();
+            this.nextState = bstModelDao.getNextSubscription().getState().toString();
+        } else {
+            this.nextProductName = null;
+            this.nextProductType = null;
+            this.nextProductCategory = null;
+            this.nextSlug = null;
+            this.nextPhase = null;
+            this.nextBillingPeriod = null;
+            this.nextPrice = null;
+            this.nextPriceList = null;
+            this.nextMrr = null;
+            this.nextCurrency = null;
+            this.nextStartDate = null;
+            this.nextState = null;
+        }
+    }
+
+    @Override
+    public long getTotalOrdering() {
+        return totalOrdering;
+    }
+
+    @Override
+    public UUID getBundleId() {
+        return bundleId;
+    }
+
+    @Override
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    @Override
+    public UUID getAccountId() {
+        return accountId;
+    }
+
+    @Override
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    @Override
+    public UUID getSubscriptionId() {
+        return subscriptionId;
+    }
+
+    @Override
+    public DateTime getRequestedTimestamp() {
+        return requestedTimestamp;
+    }
+
+    @Override
+    public String getEventType() {
+        return eventType;
+    }
+
+    @Override
+    public String getCategory() {
+        return category;
+    }
+
+    @Override
+    public String getPrevProductName() {
+        return prevProductName;
+    }
+
+    @Override
+    public String getPrevProductType() {
+        return prevProductType;
+    }
+
+    @Override
+    public String getPrevProductCategory() {
+        return prevProductCategory;
+    }
+
+    @Override
+    public String getPrevSlug() {
+        return prevSlug;
+    }
+
+    @Override
+    public String getPrevPhase() {
+        return prevPhase;
+    }
+
+    @Override
+    public String getPrevBillingPeriod() {
+        return prevBillingPeriod;
+    }
+
+    @Override
+    public BigDecimal getPrevPrice() {
+        return prevPrice;
+    }
+
+    @Override
+    public String getPrevPriceList() {
+        return prevPriceList;
+    }
+
+    @Override
+    public BigDecimal getPrevMrr() {
+        return prevMrr;
+    }
+
+    @Override
+    public String getPrevCurrency() {
+        return prevCurrency;
+    }
+
+    @Override
+    public DateTime getPrevStartDate() {
+        return prevStartDate;
+    }
+
+    @Override
+    public String getPrevState() {
+        return prevState;
+    }
+
+    @Override
+    public String getNextProductName() {
+        return nextProductName;
+    }
+
+    @Override
+    public String getNextProductType() {
+        return nextProductType;
+    }
+
+    @Override
+    public String getNextProductCategory() {
+        return nextProductCategory;
+    }
+
+    @Override
+    public String getNextSlug() {
+        return nextSlug;
+    }
+
+    @Override
+    public String getNextPhase() {
+        return nextPhase;
+    }
+
+    @Override
+    public String getNextBillingPeriod() {
+        return nextBillingPeriod;
+    }
+
+    @Override
+    public BigDecimal getNextPrice() {
+        return nextPrice;
+    }
+
+    @Override
+    public String getNextPriceList() {
+        return nextPriceList;
+    }
+
+    @Override
+    public BigDecimal getNextMrr() {
+        return nextMrr;
+    }
+
+    @Override
+    public String getNextCurrency() {
+        return nextCurrency;
+    }
+
+    @Override
+    public DateTime getNextStartDate() {
+        return nextStartDate;
+    }
+
+    @Override
+    public String getNextState() {
+        return nextState;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultBusinessSubscriptionTransition");
+        sb.append("{totalOrdering=").append(totalOrdering);
+        sb.append(", bundleId=").append(bundleId);
+        sb.append(", externalKey='").append(externalKey).append('\'');
+        sb.append(", accountId=").append(accountId);
+        sb.append(", accountKey='").append(accountKey).append('\'');
+        sb.append(", subscriptionId=").append(subscriptionId);
+        sb.append(", requestedTimestamp=").append(requestedTimestamp);
+        sb.append(", eventType='").append(eventType).append('\'');
+        sb.append(", category='").append(category).append('\'');
+        sb.append(", prevProductName='").append(prevProductName).append('\'');
+        sb.append(", prevProductType='").append(prevProductType).append('\'');
+        sb.append(", prevProductCategory='").append(prevProductCategory).append('\'');
+        sb.append(", prevSlug='").append(prevSlug).append('\'');
+        sb.append(", prevPhase='").append(prevPhase).append('\'');
+        sb.append(", prevBillingPeriod='").append(prevBillingPeriod).append('\'');
+        sb.append(", prevPrice=").append(prevPrice);
+        sb.append(", prevPriceList='").append(prevPriceList).append('\'');
+        sb.append(", prevMrr=").append(prevMrr);
+        sb.append(", prevCurrency='").append(prevCurrency).append('\'');
+        sb.append(", prevStartDate=").append(prevStartDate);
+        sb.append(", prevState='").append(prevState).append('\'');
+        sb.append(", nextProductName='").append(nextProductName).append('\'');
+        sb.append(", nextProductType='").append(nextProductType).append('\'');
+        sb.append(", nextProductCategory='").append(nextProductCategory).append('\'');
+        sb.append(", nextSlug='").append(nextSlug).append('\'');
+        sb.append(", nextPhase='").append(nextPhase).append('\'');
+        sb.append(", nextBillingPeriod='").append(nextBillingPeriod).append('\'');
+        sb.append(", nextPrice=").append(nextPrice);
+        sb.append(", nextPriceList='").append(nextPriceList).append('\'');
+        sb.append(", nextMrr=").append(nextMrr);
+        sb.append(", nextCurrency='").append(nextCurrency).append('\'');
+        sb.append(", nextStartDate=").append(nextStartDate);
+        sb.append(", nextState='").append(nextState).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultBusinessSubscriptionTransition that = (DefaultBusinessSubscriptionTransition) o;
+
+        if (totalOrdering != that.totalOrdering) {
+            return false;
+        }
+        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+            return false;
+        }
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (bundleId != null ? !bundleId.equals(that.bundleId) : that.bundleId != null) {
+            return false;
+        }
+        if (category != null ? !category.equals(that.category) : that.category != null) {
+            return false;
+        }
+        if (eventType != null ? !eventType.equals(that.eventType) : that.eventType != null) {
+            return false;
+        }
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+            return false;
+        }
+        if (nextBillingPeriod != null ? !nextBillingPeriod.equals(that.nextBillingPeriod) : that.nextBillingPeriod != null) {
+            return false;
+        }
+        if (nextCurrency != null ? !nextCurrency.equals(that.nextCurrency) : that.nextCurrency != null) {
+            return false;
+        }
+        if (nextMrr != null ? !nextMrr.equals(that.nextMrr) : that.nextMrr != null) {
+            return false;
+        }
+        if (nextPhase != null ? !nextPhase.equals(that.nextPhase) : that.nextPhase != null) {
+            return false;
+        }
+        if (nextPrice != null ? !nextPrice.equals(that.nextPrice) : that.nextPrice != null) {
+            return false;
+        }
+        if (nextPriceList != null ? !nextPriceList.equals(that.nextPriceList) : that.nextPriceList != null) {
+            return false;
+        }
+        if (nextProductCategory != null ? !nextProductCategory.equals(that.nextProductCategory) : that.nextProductCategory != null) {
+            return false;
+        }
+        if (nextProductName != null ? !nextProductName.equals(that.nextProductName) : that.nextProductName != null) {
+            return false;
+        }
+        if (nextProductType != null ? !nextProductType.equals(that.nextProductType) : that.nextProductType != null) {
+            return false;
+        }
+        if (nextSlug != null ? !nextSlug.equals(that.nextSlug) : that.nextSlug != null) {
+            return false;
+        }
+        if (nextStartDate != null ? !nextStartDate.equals(that.nextStartDate) : that.nextStartDate != null) {
+            return false;
+        }
+        if (nextState != null ? !nextState.equals(that.nextState) : that.nextState != null) {
+            return false;
+        }
+        if (prevBillingPeriod != null ? !prevBillingPeriod.equals(that.prevBillingPeriod) : that.prevBillingPeriod != null) {
+            return false;
+        }
+        if (prevCurrency != null ? !prevCurrency.equals(that.prevCurrency) : that.prevCurrency != null) {
+            return false;
+        }
+        if (prevMrr != null ? !prevMrr.equals(that.prevMrr) : that.prevMrr != null) {
+            return false;
+        }
+        if (prevPhase != null ? !prevPhase.equals(that.prevPhase) : that.prevPhase != null) {
+            return false;
+        }
+        if (prevPrice != null ? !prevPrice.equals(that.prevPrice) : that.prevPrice != null) {
+            return false;
+        }
+        if (prevPriceList != null ? !prevPriceList.equals(that.prevPriceList) : that.prevPriceList != null) {
+            return false;
+        }
+        if (prevProductCategory != null ? !prevProductCategory.equals(that.prevProductCategory) : that.prevProductCategory != null) {
+            return false;
+        }
+        if (prevProductName != null ? !prevProductName.equals(that.prevProductName) : that.prevProductName != null) {
+            return false;
+        }
+        if (prevProductType != null ? !prevProductType.equals(that.prevProductType) : that.prevProductType != null) {
+            return false;
+        }
+        if (prevSlug != null ? !prevSlug.equals(that.prevSlug) : that.prevSlug != null) {
+            return false;
+        }
+        if (prevStartDate != null ? !prevStartDate.equals(that.prevStartDate) : that.prevStartDate != null) {
+            return false;
+        }
+        if (prevState != null ? !prevState.equals(that.prevState) : that.prevState != null) {
+            return false;
+        }
+        if (requestedTimestamp != null ? !requestedTimestamp.equals(that.requestedTimestamp) : that.requestedTimestamp != null) {
+            return false;
+        }
+        if (subscriptionId != null ? !subscriptionId.equals(that.subscriptionId) : that.subscriptionId != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = (int) (totalOrdering ^ (totalOrdering >>> 32));
+        result = 31 * result + (bundleId != null ? bundleId.hashCode() : 0);
+        result = 31 * result + (externalKey != null ? externalKey.hashCode() : 0);
+        result = 31 * result + (accountId != null ? accountId.hashCode() : 0);
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
+        result = 31 * result + (subscriptionId != null ? subscriptionId.hashCode() : 0);
+        result = 31 * result + (requestedTimestamp != null ? requestedTimestamp.hashCode() : 0);
+        result = 31 * result + (eventType != null ? eventType.hashCode() : 0);
+        result = 31 * result + (category != null ? category.hashCode() : 0);
+        result = 31 * result + (prevProductName != null ? prevProductName.hashCode() : 0);
+        result = 31 * result + (prevProductType != null ? prevProductType.hashCode() : 0);
+        result = 31 * result + (prevProductCategory != null ? prevProductCategory.hashCode() : 0);
+        result = 31 * result + (prevSlug != null ? prevSlug.hashCode() : 0);
+        result = 31 * result + (prevPhase != null ? prevPhase.hashCode() : 0);
+        result = 31 * result + (prevBillingPeriod != null ? prevBillingPeriod.hashCode() : 0);
+        result = 31 * result + (prevPrice != null ? prevPrice.hashCode() : 0);
+        result = 31 * result + (prevPriceList != null ? prevPriceList.hashCode() : 0);
+        result = 31 * result + (prevMrr != null ? prevMrr.hashCode() : 0);
+        result = 31 * result + (prevCurrency != null ? prevCurrency.hashCode() : 0);
+        result = 31 * result + (prevStartDate != null ? prevStartDate.hashCode() : 0);
+        result = 31 * result + (prevState != null ? prevState.hashCode() : 0);
+        result = 31 * result + (nextProductName != null ? nextProductName.hashCode() : 0);
+        result = 31 * result + (nextProductType != null ? nextProductType.hashCode() : 0);
+        result = 31 * result + (nextProductCategory != null ? nextProductCategory.hashCode() : 0);
+        result = 31 * result + (nextSlug != null ? nextSlug.hashCode() : 0);
+        result = 31 * result + (nextPhase != null ? nextPhase.hashCode() : 0);
+        result = 31 * result + (nextBillingPeriod != null ? nextBillingPeriod.hashCode() : 0);
+        result = 31 * result + (nextPrice != null ? nextPrice.hashCode() : 0);
+        result = 31 * result + (nextPriceList != null ? nextPriceList.hashCode() : 0);
+        result = 31 * result + (nextMrr != null ? nextMrr.hashCode() : 0);
+        result = 31 * result + (nextCurrency != null ? nextCurrency.hashCode() : 0);
+        result = 31 * result + (nextStartDate != null ? nextStartDate.hashCode() : 0);
+        result = 31 * result + (nextState != null ? nextState.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessTag.java b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessTag.java
new file mode 100644
index 0000000..436ad49
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessTag.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.analytics.model.BusinessAccountTagModelDao;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentTagModelDao;
+import com.ning.billing.analytics.model.BusinessInvoiceTagModelDao;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionTagModelDao;
+import com.ning.billing.analytics.model.BusinessTagModelDao;
+import com.ning.billing.util.entity.EntityBase;
+
+public class DefaultBusinessTag extends EntityBase implements BusinessTag {
+
+    private final ObjectType objectType;
+    private final String name;
+
+    DefaultBusinessTag(final ObjectType objectType, final BusinessTagModelDao businessTagModelDao) {
+        super(businessTagModelDao.getId());
+        this.objectType = objectType;
+        this.name = businessTagModelDao.getName();
+    }
+
+    public DefaultBusinessTag(final BusinessAccountTagModelDao businessAccountTagModelDao) {
+        this(ObjectType.ACCOUNT, businessAccountTagModelDao);
+    }
+
+    public DefaultBusinessTag(final BusinessInvoiceTagModelDao businessInvoiceTagModelDao) {
+        this(ObjectType.INVOICE, businessInvoiceTagModelDao);
+    }
+
+    public DefaultBusinessTag(final BusinessInvoicePaymentTagModelDao businessInvoicePaymentTagModelDao) {
+        this(ObjectType.PAYMENT, businessInvoicePaymentTagModelDao);
+    }
+
+    public DefaultBusinessTag(final BusinessSubscriptionTransitionTagModelDao businessSubscriptionTransitionTagModelDao) {
+        this(ObjectType.BUNDLE, businessSubscriptionTransitionTagModelDao);
+    }
+
+    @Override
+    public ObjectType getObjectType() {
+        return objectType;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultBusinessTag");
+        sb.append("{objectType=").append(objectType);
+        sb.append(", name='").append(name).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultBusinessTag that = (DefaultBusinessTag) o;
+
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        if (objectType != that.objectType) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = objectType != null ? objectType.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/sanity/DefaultAnalyticsSanityApi.java b/analytics/src/main/java/com/ning/billing/analytics/api/sanity/DefaultAnalyticsSanityApi.java
new file mode 100644
index 0000000..11c82ff
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/sanity/DefaultAnalyticsSanityApi.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010-2012 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.analytics.api.sanity;
+
+import java.util.Collection;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import com.ning.billing.analytics.dao.AnalyticsSanityDao;
+import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.TenantContext;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+public class DefaultAnalyticsSanityApi implements AnalyticsSanityApi {
+
+    private final AnalyticsSanityDao dao;
+    private final InternalCallContextFactory internalCallContextFactory;
+
+    @Inject
+    public DefaultAnalyticsSanityApi(final AnalyticsSanityDao dao,
+                                     final InternalCallContextFactory internalCallContextFactory) {
+        this.dao = dao;
+        this.internalCallContextFactory = internalCallContextFactory;
+    }
+
+    @Override
+    public Collection<UUID> checkAnalyticsInSyncWithEntitlement(final TenantContext context) {
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
+        return dao.checkBstMatchesSubscriptionEvents(internalTenantContext);
+    }
+
+    @Override
+    public Collection<UUID> checkAnalyticsInSyncWithInvoice(final TenantContext context) {
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
+        return dao.checkBiiMatchesInvoiceItems(internalTenantContext);
+    }
+
+    @Override
+    public Collection<UUID> checkAnalyticsInSyncWithPayment(final TenantContext context) {
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
+        final Collection<UUID> check1 = dao.checkBipMatchesInvoicePayments(internalTenantContext);
+        final Collection<UUID> check2 = dao.checkBinAmountPaidMatchesInvoicePayments(internalTenantContext);
+        final Collection<UUID> check3 = dao.checkBinAmountChargedMatchesInvoicePayments(internalTenantContext);
+
+        return ImmutableSet.<UUID>copyOf(Iterables.<UUID>concat(check1, check2, check3));
+    }
+
+    @Override
+    public Collection<UUID> checkAnalyticsInSyncWithTag(final TenantContext context) {
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
+        return dao.checkBacTagsMatchesTags(internalTenantContext);
+    }
+
+    @Override
+    public Collection<UUID> checkAnalyticsConsistency(final TenantContext context) {
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
+        final Collection<UUID> check1 = dao.checkBinBiiBalanceConsistency(internalTenantContext);
+        final Collection<UUID> check2 = dao.checkBinBiiAmountCreditedConsistency(internalTenantContext);
+        final Collection<UUID> check3 = dao.checkBacBinBiiConsistency(internalTenantContext);
+
+        return ImmutableSet.<UUID>copyOf(Iterables.<UUID>concat(check1, check2, check3));
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java b/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
index 8f1fa10..cc434c9 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.analytics.api.user;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -38,15 +39,29 @@ import com.ning.billing.analytics.BusinessInvoicePaymentDao;
 import com.ning.billing.analytics.BusinessOverdueStatusDao;
 import com.ning.billing.analytics.BusinessSubscriptionTransitionDao;
 import com.ning.billing.analytics.BusinessTagDao;
+import com.ning.billing.analytics.api.BusinessAccount;
+import com.ning.billing.analytics.api.BusinessField;
+import com.ning.billing.analytics.api.BusinessInvoice;
+import com.ning.billing.analytics.api.BusinessInvoicePayment;
+import com.ning.billing.analytics.api.BusinessOverdueStatus;
+import com.ning.billing.analytics.api.BusinessSnapshot;
+import com.ning.billing.analytics.api.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.api.BusinessTag;
+import com.ning.billing.analytics.api.DefaultBusinessAccount;
+import com.ning.billing.analytics.api.DefaultBusinessInvoice;
+import com.ning.billing.analytics.api.DefaultBusinessInvoicePayment;
+import com.ning.billing.analytics.api.DefaultBusinessOverdueStatus;
+import com.ning.billing.analytics.api.DefaultBusinessSnapshot;
+import com.ning.billing.analytics.api.DefaultBusinessSubscriptionTransition;
+import com.ning.billing.analytics.api.DefaultBusinessTag;
 import com.ning.billing.analytics.api.TimeSeriesData;
 import com.ning.billing.analytics.dao.AnalyticsDao;
-import com.ning.billing.analytics.model.BusinessAccount;
-import com.ning.billing.analytics.model.BusinessAccountTag;
-import com.ning.billing.analytics.model.BusinessInvoice;
-import com.ning.billing.analytics.model.BusinessInvoiceItem;
-import com.ning.billing.analytics.model.BusinessInvoicePayment;
-import com.ning.billing.analytics.model.BusinessOverdueStatus;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
+import com.ning.billing.analytics.model.BusinessAccountTagModelDao;
+import com.ning.billing.analytics.model.BusinessInvoiceModelDao;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentModelDao;
+import com.ning.billing.analytics.model.BusinessOverdueStatusModelDao;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.Blockable.Type;
 import com.ning.billing.payment.api.Payment;
@@ -54,6 +69,7 @@ import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalCallContextFactory;
+import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.svcapi.payment.PaymentInternalApi;
 import com.ning.billing.util.svcapi.entitlement.EntitlementInternalApi;
@@ -63,6 +79,7 @@ import com.ning.billing.util.tag.TagDefinition;
 
 import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
 
 public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
@@ -107,6 +124,105 @@ public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
     }
 
     @Override
+    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 Collection<BusinessSubscriptionTransition> businessSubscriptionTransitions = new ArrayList<BusinessSubscriptionTransition>();
+        final Collection<BusinessOverdueStatus> businessOverdueStatuses = new ArrayList<BusinessOverdueStatus>();
+        for (final SubscriptionBundle bundle : bundles) {
+            businessSubscriptionTransitions.addAll(getTransitionsForBundle(bundle.getKey(), context));
+            businessOverdueStatuses.addAll(getOverdueStatusesForBundle(bundle.getKey(), context));
+        }
+
+        // Find all invoices for that account
+        final Collection<BusinessInvoice> businessInvoices = getInvoicesForAccount(account.getExternalKey(), context);
+
+        // Find all payments for that account
+        final Collection<BusinessInvoicePayment> businessInvoicePayments = getInvoicePaymentsForAccount(account.getExternalKey(), context);
+
+        // Find all tags for that account
+        // TODO add other tag types
+        final Collection<BusinessTag> businessTags = getTagsForAccount(account.getExternalKey(), context);
+
+        // TODO find custom fields
+        final Collection<BusinessField> businessFields = ImmutableList.<BusinessField>of();
+
+        return new DefaultBusinessSnapshot(businessAccount, businessSubscriptionTransitions, businessInvoices, businessInvoicePayments,
+                                           businessOverdueStatuses, businessTags, businessFields);
+    }
+
+    @Override
+    public BusinessAccount getAccountByKey(final String accountKey, final TenantContext context) {
+        final BusinessAccountModelDao accountByKey = analyticsDao.getAccountByKey(accountKey, internalCallContextFactory.createInternalTenantContext(context));
+        if (accountByKey == null) {
+            return null;
+        } else {
+            return new DefaultBusinessAccount(accountByKey);
+        }
+    }
+
+    @Override
+    public List<BusinessSubscriptionTransition> getTransitionsForBundle(final String externalKey, final TenantContext context) {
+        final List<BusinessSubscriptionTransitionModelDao> transitionsByKey = analyticsDao.getTransitionsByKey(externalKey, internalCallContextFactory.createInternalTenantContext(context));
+        return ImmutableList.<BusinessSubscriptionTransition>copyOf(Collections2.transform(transitionsByKey, new Function<BusinessSubscriptionTransitionModelDao, BusinessSubscriptionTransition>() {
+            @Override
+            public BusinessSubscriptionTransition apply(@Nullable final BusinessSubscriptionTransitionModelDao input) {
+                return new DefaultBusinessSubscriptionTransition(input);
+            }
+        }));
+    }
+
+    @Override
+    public List<BusinessInvoice> getInvoicesForAccount(final String accountKey, final TenantContext context) {
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
+        final List<BusinessInvoiceModelDao> invoicesByKey = analyticsDao.getInvoicesByKey(accountKey, internalTenantContext);
+        return ImmutableList.<BusinessInvoice>copyOf(Collections2.transform(invoicesByKey, new Function<BusinessInvoiceModelDao, BusinessInvoice>() {
+            @Override
+            public BusinessInvoice apply(@Nullable final BusinessInvoiceModelDao input) {
+                return new DefaultBusinessInvoice(input, input == null ? null : analyticsDao.getInvoiceItemsForInvoice(input.getInvoiceId().toString(), internalTenantContext));
+            }
+        }));
+    }
+
+    @Override
+    public List<BusinessInvoicePayment> getInvoicePaymentsForAccount(final String accountKey, final TenantContext context) {
+        final List<BusinessInvoicePaymentModelDao> invoicePaymentsForAccountByKey = analyticsDao.getInvoicePaymentsForAccountByKey(accountKey, internalCallContextFactory.createInternalTenantContext(context));
+        return ImmutableList.<BusinessInvoicePayment>copyOf(Collections2.transform(invoicePaymentsForAccountByKey, new Function<BusinessInvoicePaymentModelDao, BusinessInvoicePayment>() {
+            @Override
+            public BusinessInvoicePayment apply(@Nullable final BusinessInvoicePaymentModelDao input) {
+                return new DefaultBusinessInvoicePayment(input);
+            }
+        }));
+    }
+
+    @Override
+    public List<BusinessOverdueStatus> getOverdueStatusesForBundle(final String externalKey, final TenantContext context) {
+        final List<BusinessOverdueStatusModelDao> overdueStatusesForBundleByKey = analyticsDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContextFactory.createInternalTenantContext(context));
+        return ImmutableList.<BusinessOverdueStatus>copyOf(Collections2.transform(overdueStatusesForBundleByKey, new Function<BusinessOverdueStatusModelDao, BusinessOverdueStatus>() {
+            @Override
+            public BusinessOverdueStatus apply(@Nullable final BusinessOverdueStatusModelDao input) {
+                return new DefaultBusinessOverdueStatus(input);
+            }
+        }));
+    }
+
+    @Override
+    public List<BusinessTag> getTagsForAccount(final String accountKey, final TenantContext context) {
+        final List<BusinessAccountTagModelDao> tagsForAccount = analyticsDao.getTagsForAccount(accountKey, internalCallContextFactory.createInternalTenantContext(context));
+        return ImmutableList.<BusinessTag>copyOf(Collections2.transform(tagsForAccount, new Function<BusinessAccountTagModelDao, BusinessTag>() {
+            @Override
+            public BusinessTag apply(@Nullable final BusinessAccountTagModelDao input) {
+                return new DefaultBusinessTag(input);
+            }
+        }));
+    }
+
+    @Override
     public TimeSeriesData getAccountsCreatedOverTime(final TenantContext context) {
         return analyticsDao.getAccountsCreatedOverTime(internalCallContextFactory.createInternalTenantContext(context));
     }
@@ -164,9 +280,9 @@ public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
 
         // Find the current state of bundles in analytics
         final Collection<UUID> analyticsBundlesId = Collections2.transform(analyticsDao.getTransitionsForAccount(account.getExternalKey(), internalCallContext),
-                                                                           new Function<BusinessSubscriptionTransition, UUID>() {
+                                                                           new Function<BusinessSubscriptionTransitionModelDao, UUID>() {
                                                                                @Override
-                                                                               public UUID apply(@Nullable final BusinessSubscriptionTransition input) {
+                                                                               public UUID apply(@Nullable final BusinessSubscriptionTransitionModelDao input) {
                                                                                    if (input == null) {
                                                                                        return null;
                                                                                    } else {
@@ -208,9 +324,9 @@ public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
 
         // Find the current state of payments in analytics
         final Collection<UUID> analyticsPaymentsId = Collections2.transform(analyticsDao.getInvoicePaymentsForAccountByKey(account.getExternalKey(), internalCallContext),
-                                                                            new Function<BusinessInvoicePayment, UUID>() {
+                                                                            new Function<BusinessInvoicePaymentModelDao, UUID>() {
                                                                                 @Override
-                                                                                public UUID apply(@Nullable final BusinessInvoicePayment input) {
+                                                                                public UUID apply(@Nullable final BusinessInvoicePaymentModelDao input) {
                                                                                     if (input == null) {
                                                                                         return null;
                                                                                     } else {
@@ -256,9 +372,9 @@ public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
 
         // Find the current state of tags in analytics
         final Collection<String> analyticsTags = Collections2.transform(analyticsDao.getTagsForAccount(account.getExternalKey(), internalCallContext),
-                                                                        new Function<BusinessAccountTag, String>() {
+                                                                        new Function<BusinessAccountTagModelDao, String>() {
                                                                             @Override
-                                                                            public String apply(@Nullable final BusinessAccountTag input) {
+                                                                            public String apply(@Nullable final BusinessAccountTagModelDao input) {
                                                                                 if (input == null) {
                                                                                     return null;
                                                                                 } else {
@@ -277,34 +393,4 @@ public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
             tagDao.tagAdded(ObjectType.ACCOUNT, account.getId(), tag, internalCallContext);
         }
     }
-
-    // Note: the following is not exposed in api yet, as the models need to be extracted first
-
-    public BusinessAccount getAccountByKey(final String accountKey, final TenantContext context) {
-        return analyticsDao.getAccountByKey(accountKey, internalCallContextFactory.createInternalTenantContext(context));
-    }
-
-    public List<BusinessSubscriptionTransition> getTransitionsForBundle(final String externalKey, final TenantContext context) {
-        return analyticsDao.getTransitionsByKey(externalKey, internalCallContextFactory.createInternalTenantContext(context));
-    }
-
-    public List<BusinessInvoice> getInvoicesForAccount(final String accountKey, final TenantContext context) {
-        return analyticsDao.getInvoicesByKey(accountKey, internalCallContextFactory.createInternalTenantContext(context));
-    }
-
-    public List<BusinessAccountTag> getTagsForAccount(final String accountKey, final TenantContext context) {
-        return analyticsDao.getTagsForAccount(accountKey, internalCallContextFactory.createInternalTenantContext(context));
-    }
-
-    public List<BusinessOverdueStatus> getOverdueStatusesForBundle(final String externalKey, final TenantContext context) {
-        return analyticsDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContextFactory.createInternalTenantContext(context));
-    }
-
-    public List<BusinessInvoiceItem> getInvoiceItemsForInvoice(final UUID invoiceId, final TenantContext context) {
-        return analyticsDao.getInvoiceItemsForInvoice(invoiceId.toString(), internalCallContextFactory.createInternalTenantContext(context));
-    }
-
-    public List<BusinessInvoicePayment> getInvoicePaymentsForAccount(final String accountKey, final TenantContext context) {
-        return analyticsDao.getInvoicePaymentsForAccountByKey(accountKey, internalCallContextFactory.createInternalTenantContext(context));
-    }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java
index 584e817..cc8fcf7 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java
@@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
-import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.PaymentApiException;
@@ -67,11 +67,11 @@ public class BusinessAccountDao {
         try {
             account = accountApi.getAccountById(accountId, context);
         } catch (AccountApiException e) {
-            log.warn("Error encountered creating BusinessAccount", e);
+            log.warn("Error encountered creating BusinessAccountModelDao", e);
             return;
         }
 
-        final BusinessAccount bac = createBusinessAccountFromAccount(account, context);
+        final BusinessAccountModelDao bac = createBusinessAccountFromAccount(account, context);
         sqlDao.inTransaction(new Transaction<Void, BusinessAccountSqlDao>() {
             @Override
             public Void inTransaction(final BusinessAccountSqlDao transactional, final TransactionStatus status) throws Exception {
@@ -82,16 +82,16 @@ public class BusinessAccountDao {
     }
 
     // Called also from BusinessInvoiceDao and BusinessInvoicePaymentDao.
-    // Note: computing the BusinessAccount object is fairly expensive, hence should be done outside of the transaction
-    public void updateAccountInTransaction(final BusinessAccount bac, final BusinessAccountSqlDao transactional, final InternalCallContext context) {
+    // Note: computing the BusinessAccountModelDao object is fairly expensive, hence should be done outside of the transaction
+    public void updateAccountInTransaction(final BusinessAccountModelDao bac, final BusinessAccountSqlDao transactional, final InternalCallContext context) {
         log.info("ACCOUNT UPDATE " + bac);
         transactional.deleteAccount(bac.getAccountId().toString(), context);
         // Note! There is a window of doom here since we use read committed transactional level by default
         transactional.createAccount(bac, context);
     }
 
-    public BusinessAccount createBusinessAccountFromAccount(final Account account, final InternalTenantContext context) {
-        final BusinessAccount bac = new BusinessAccount(account);
+    public BusinessAccountModelDao createBusinessAccountFromAccount(final Account account, final InternalTenantContext context) {
+        final BusinessAccountModelDao bac = new BusinessAccountModelDao(account);
 
         try {
             LocalDate lastInvoiceDate = bac.getLastInvoiceDate();
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceDao.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceDao.java
index 6d59d8c..2f09a66 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceDao.java
@@ -35,9 +35,9 @@ import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
 import com.ning.billing.analytics.dao.BusinessInvoiceItemSqlDao;
 import com.ning.billing.analytics.dao.BusinessInvoiceSqlDao;
-import com.ning.billing.analytics.model.BusinessAccount;
-import com.ning.billing.analytics.model.BusinessInvoice;
-import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
+import com.ning.billing.analytics.model.BusinessInvoiceItemModelDao;
+import com.ning.billing.analytics.model.BusinessInvoiceModelDao;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Plan;
@@ -95,13 +95,13 @@ public class BusinessInvoiceDao {
         final Collection<Invoice> invoices = invoiceApi.getInvoicesByAccountId(account.getId(), context);
 
         // Create the business invoice and associated business invoice items
-        final Map<BusinessInvoice, Collection<BusinessInvoiceItem>> businessInvoices = new HashMap<BusinessInvoice, Collection<BusinessInvoiceItem>>();
+        final Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemModelDao>> businessInvoices = new HashMap<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemModelDao>>();
         for (final Invoice invoice : invoices) {
-            final BusinessInvoice businessInvoice = new BusinessInvoice(account.getExternalKey(), invoice);
+            final BusinessInvoiceModelDao businessInvoice = new BusinessInvoiceModelDao(account.getExternalKey(), invoice);
 
-            final List<BusinessInvoiceItem> businessInvoiceItems = new ArrayList<BusinessInvoiceItem>();
+            final List<BusinessInvoiceItemModelDao> businessInvoiceItems = new ArrayList<BusinessInvoiceItemModelDao>();
             for (final InvoiceItem invoiceItem : invoice.getInvoiceItems()) {
-                final BusinessInvoiceItem businessInvoiceItem = createBusinessInvoiceItem(invoiceItem, context);
+                final BusinessInvoiceItemModelDao businessInvoiceItem = createBusinessInvoiceItem(invoiceItem, context);
                 if (businessInvoiceItem != null) {
                     businessInvoiceItems.add(businessInvoiceItem);
                 }
@@ -111,7 +111,7 @@ public class BusinessInvoiceDao {
         }
 
         // Update the account record
-        final BusinessAccount bac = businessAccountDao.createBusinessAccountFromAccount(account, context);
+        final BusinessAccountModelDao bac = businessAccountDao.createBusinessAccountFromAccount(account, context);
 
         // Delete and recreate invoice and invoice items in the transaction
         sqlDao.inTransaction(new Transaction<Void, BusinessInvoiceSqlDao>() {
@@ -134,15 +134,15 @@ public class BusinessInvoiceDao {
         transactional.deleteInvoice(invoice.getId().toString(), context);
 
         // Re-create it - this will update the various amounts
-        transactional.createInvoice(new BusinessInvoice(accountKey, invoice), context);
+        transactional.createInvoice(new BusinessInvoiceModelDao(accountKey, invoice), context);
     }
 
-    private void rebuildInvoicesForAccountInTransaction(final Account account, final Map<BusinessInvoice, Collection<BusinessInvoiceItem>> businessInvoices,
+    private void rebuildInvoicesForAccountInTransaction(final Account account, final Map<BusinessInvoiceModelDao, Collection<BusinessInvoiceItemModelDao>> businessInvoices,
                                                         final BusinessInvoiceSqlDao transactional, final InternalCallContext context) {
         log.info("Started rebuilding invoices for account id {}", account.getId());
         deleteInvoicesAndInvoiceItemsForAccountInTransaction(transactional, account.getId(), context);
 
-        for (final BusinessInvoice businessInvoice : businessInvoices.keySet()) {
+        for (final BusinessInvoiceModelDao businessInvoice : businessInvoices.keySet()) {
             createInvoiceInTransaction(transactional, businessInvoice, businessInvoices.get(businessInvoice), context);
         }
 
@@ -162,22 +162,22 @@ public class BusinessInvoiceDao {
         transactional.deleteInvoicesForAccount(accountId.toString(), context);
     }
 
-    private void createInvoiceInTransaction(final BusinessInvoiceSqlDao transactional, final BusinessInvoice invoice,
-                                            final Iterable<BusinessInvoiceItem> invoiceItems, final InternalCallContext context) {
+    private void createInvoiceInTransaction(final BusinessInvoiceSqlDao transactional, final BusinessInvoiceModelDao invoice,
+                                            final Iterable<BusinessInvoiceItemModelDao> invoiceItems, final InternalCallContext context) {
         // Create the invoice
         log.info("Adding invoice {}", invoice);
         transactional.createInvoice(invoice, context);
 
         // Add associated invoice items
         final BusinessInvoiceItemSqlDao invoiceItemSqlDao = transactional.become(BusinessInvoiceItemSqlDao.class);
-        for (final BusinessInvoiceItem invoiceItem : invoiceItems) {
+        for (final BusinessInvoiceItemModelDao invoiceItem : invoiceItems) {
             log.info("Adding invoice item {}", invoiceItem);
             invoiceItemSqlDao.createInvoiceItem(invoiceItem, context);
         }
     }
 
     @VisibleForTesting
-    BusinessInvoiceItem createBusinessInvoiceItem(final InvoiceItem invoiceItem, final InternalTenantContext context) {
+    BusinessInvoiceItemModelDao createBusinessInvoiceItem(final InvoiceItem invoiceItem, final InternalTenantContext context) {
         String externalKey = null;
         Plan plan = null;
         PlanPhase planPhase = null;
@@ -216,6 +216,6 @@ public class BusinessInvoiceDao {
             }
         }
 
-        return new BusinessInvoiceItem(externalKey, invoiceItem, plan, planPhase);
+        return new BusinessInvoiceItemModelDao(externalKey, invoiceItem, plan, planPhase);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java
index 2ae6900..3592502 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java
@@ -32,8 +32,8 @@ import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
 import com.ning.billing.analytics.dao.BusinessInvoicePaymentSqlDao;
 import com.ning.billing.analytics.dao.BusinessInvoiceSqlDao;
-import com.ning.billing.analytics.model.BusinessAccount;
-import com.ning.billing.analytics.model.BusinessInvoicePayment;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentModelDao;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoicePayment;
@@ -143,7 +143,7 @@ public class BusinessInvoicePaymentDao {
             updatedDate = createdDate;
         }
 
-        final BusinessInvoicePayment businessInvoicePayment = new BusinessInvoicePayment(
+        final BusinessInvoicePaymentModelDao businessInvoicePayment = new BusinessInvoicePaymentModelDao(
                 account.getExternalKey(),
                 payment.getAmount(),
                 extFirstPaymentRefId,
@@ -166,7 +166,7 @@ public class BusinessInvoicePaymentDao {
                 linkedInvoicePaymentId);
 
         // Update the account record
-        final BusinessAccount bac = accountDao.createBusinessAccountFromAccount(account, context);
+        final BusinessAccountModelDao bac = accountDao.createBusinessAccountFromAccount(account, context);
 
         // Make sure to limit the scope of the transaction to avoid InnoDB deadlocks
         invoicePaymentSqlDao.inTransaction(new Transaction<Void, BusinessInvoicePaymentSqlDao>() {
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessOverdueStatusDao.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessOverdueStatusDao.java
index 05683f9..b0b30fd 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessOverdueStatusDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessOverdueStatusDao.java
@@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.analytics.dao.BusinessOverdueStatusSqlDao;
-import com.ning.billing.analytics.model.BusinessOverdueStatus;
+import com.ning.billing.analytics.model.BusinessOverdueStatusModelDao;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.Blockable;
@@ -103,8 +103,8 @@ public class BusinessOverdueStatusDao {
 
                     DateTime previousStartDate = null;
                     for (final BlockingState state : overdueStatesReversed) {
-                        final BusinessOverdueStatus overdueStatus = new BusinessOverdueStatus(accountKey, bundleId, previousStartDate,
-                                                                                              externalKey, state.getTimestamp(), state.getStateName());
+                        final BusinessOverdueStatusModelDao overdueStatus = new BusinessOverdueStatusModelDao(accountKey, bundleId, previousStartDate,
+                                                                                                              externalKey, state.getTimestamp(), state.getStateName());
                         log.info("Adding overdue state {}", overdueStatus);
                         overdueStatusSqlDao.createOverdueStatus(overdueStatus, context);
 
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionDao.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionDao.java
index 5afe9a9..c8ebb65 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionDao.java
@@ -30,7 +30,7 @@ import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
 import com.ning.billing.analytics.model.BusinessSubscription;
 import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
@@ -96,7 +96,7 @@ public class BusinessSubscriptionTransitionDao {
                 log.info("Started rebuilding transitions for bundle id {}", bundleId);
                 transactional.deleteTransitionsForBundle(bundleId.toString(), context);
 
-                final ArrayList<BusinessSubscriptionTransition> transitions = new ArrayList<BusinessSubscriptionTransition>();
+                final ArrayList<BusinessSubscriptionTransitionModelDao> transitions = new ArrayList<BusinessSubscriptionTransitionModelDao>();
                 for (final Subscription subscription : subscriptions) {
                     // TODO remove API call from within transaction, although this is NOT a real issue as this call wil not hit the DB
                     for (final EffectiveSubscriptionInternalEvent event : entitlementApi.getAllTransitions(subscription, context)) {
@@ -107,7 +107,7 @@ public class BusinessSubscriptionTransitionDao {
 
                         final BusinessSubscription prevSubscription = createPreviousBusinessSubscription(event, businessEvent, transitions, currency);
                         final BusinessSubscription nextSubscription = createNextBusinessSubscription(event, businessEvent, currency);
-                        final BusinessSubscriptionTransition transition = new BusinessSubscriptionTransition(
+                        final BusinessSubscriptionTransitionModelDao transition = new BusinessSubscriptionTransitionModelDao(
                                 event.getTotalOrdering(),
                                 bundleId,
                                 bundle.getKey(),
@@ -127,7 +127,7 @@ public class BusinessSubscriptionTransitionDao {
                         // We need to manually add the system cancel event
                         if (SubscriptionTransitionType.CANCEL.equals(event.getTransitionType()) &&
                             clock.getUTCNow().isAfter(event.getEffectiveTransitionTime())) {
-                            final BusinessSubscriptionTransition systemCancelTransition = new BusinessSubscriptionTransition(
+                            final BusinessSubscriptionTransitionModelDao systemCancelTransition = new BusinessSubscriptionTransitionModelDao(
                                     event.getTotalOrdering(),
                                     bundleId,
                                     bundle.getKey(),
@@ -226,7 +226,7 @@ public class BusinessSubscriptionTransitionDao {
 
     private BusinessSubscription createPreviousBusinessSubscription(final EffectiveSubscriptionInternalEvent event,
                                                                     final BusinessSubscriptionEvent businessEvent,
-                                                                    final ArrayList<BusinessSubscriptionTransition> transitions,
+                                                                    final ArrayList<BusinessSubscriptionTransitionModelDao> transitions,
                                                                     final Currency currency) {
         if (BusinessSubscriptionEvent.EventType.MIGRATE.equals(businessEvent.getEventType()) ||
             BusinessSubscriptionEvent.EventType.ADD.equals(businessEvent.getEventType()) ||
@@ -235,16 +235,16 @@ public class BusinessSubscriptionTransitionDao {
             return null;
         }
 
-        final BusinessSubscriptionTransition prevTransition = getPreviousBusinessSubscriptionTransitionForEvent(event, transitions);
+        final BusinessSubscriptionTransitionModelDao prevTransition = getPreviousBusinessSubscriptionTransitionForEvent(event, transitions);
         return new BusinessSubscription(event.getPreviousPriceList(), event.getPreviousPlan(), event.getPreviousPhase(),
                                         currency, prevTransition.getNextSubscription().getStartDate(), event.getPreviousState(),
                                         catalogService.getFullCatalog());
     }
 
-    private BusinessSubscriptionTransition getPreviousBusinessSubscriptionTransitionForEvent(final EffectiveSubscriptionInternalEvent event,
-                                                                                             final ArrayList<BusinessSubscriptionTransition> transitions) {
-        BusinessSubscriptionTransition transition = null;
-        for (final BusinessSubscriptionTransition candidate : transitions) {
+    private BusinessSubscriptionTransitionModelDao getPreviousBusinessSubscriptionTransitionForEvent(final EffectiveSubscriptionInternalEvent event,
+                                                                                                     final ArrayList<BusinessSubscriptionTransitionModelDao> transitions) {
+        BusinessSubscriptionTransitionModelDao transition = null;
+        for (final BusinessSubscriptionTransitionModelDao candidate : transitions) {
             final BusinessSubscription nextSubscription = candidate.getNextSubscription();
             if (nextSubscription == null || !nextSubscription.getStartDate().isBefore(event.getEffectiveTransitionTime())) {
                 continue;
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java
index 7c4ab6c..910d806 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java
@@ -19,13 +19,13 @@ package com.ning.billing.analytics.dao;
 import java.util.List;
 
 import com.ning.billing.analytics.api.TimeSeriesData;
-import com.ning.billing.analytics.model.BusinessAccount;
-import com.ning.billing.analytics.model.BusinessAccountTag;
-import com.ning.billing.analytics.model.BusinessInvoice;
-import com.ning.billing.analytics.model.BusinessInvoiceItem;
-import com.ning.billing.analytics.model.BusinessInvoicePayment;
-import com.ning.billing.analytics.model.BusinessOverdueStatus;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
+import com.ning.billing.analytics.model.BusinessAccountTagModelDao;
+import com.ning.billing.analytics.model.BusinessInvoiceItemModelDao;
+import com.ning.billing.analytics.model.BusinessInvoiceModelDao;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentModelDao;
+import com.ning.billing.analytics.model.BusinessOverdueStatusModelDao;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public interface AnalyticsDao {
@@ -34,19 +34,19 @@ public interface AnalyticsDao {
 
     TimeSeriesData getSubscriptionsCreatedOverTime(String productType, String slug, InternalTenantContext context);
 
-    BusinessAccount getAccountByKey(String accountKey, InternalTenantContext context);
+    BusinessAccountModelDao getAccountByKey(String accountKey, InternalTenantContext context);
 
-    List<BusinessSubscriptionTransition> getTransitionsByKey(String externalKey, InternalTenantContext context);
+    List<BusinessSubscriptionTransitionModelDao> getTransitionsByKey(String externalKey, InternalTenantContext context);
 
-    List<BusinessSubscriptionTransition> getTransitionsForAccount(String accountKey, InternalTenantContext context);
+    List<BusinessSubscriptionTransitionModelDao> getTransitionsForAccount(String accountKey, InternalTenantContext context);
 
-    List<BusinessInvoice> getInvoicesByKey(String accountKey, InternalTenantContext context);
+    List<BusinessInvoiceModelDao> getInvoicesByKey(String accountKey, InternalTenantContext context);
 
-    List<BusinessAccountTag> getTagsForAccount(String accountKey, InternalTenantContext context);
+    List<BusinessInvoiceItemModelDao> getInvoiceItemsForInvoice(String invoiceId, InternalTenantContext context);
 
-    List<BusinessInvoiceItem> getInvoiceItemsForInvoice(String invoiceId, InternalTenantContext context);
+    List<BusinessInvoicePaymentModelDao> getInvoicePaymentsForAccountByKey(String accountKey, InternalTenantContext context);
 
-    List<BusinessOverdueStatus> getOverdueStatusesForBundleByKey(String externalKey, InternalTenantContext context);
+    List<BusinessOverdueStatusModelDao> getOverdueStatusesForBundleByKey(String externalKey, InternalTenantContext context);
 
-    List<BusinessInvoicePayment> getInvoicePaymentsForAccountByKey(String accountKey, InternalTenantContext context);
+    List<BusinessAccountTagModelDao> getTagsForAccount(String accountKey, InternalTenantContext context);
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsSanityDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsSanityDao.java
new file mode 100644
index 0000000..9a689ab
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsSanityDao.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2012 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.analytics.dao;
+
+import java.util.Collection;
+import java.util.UUID;
+
+import com.ning.billing.util.callcontext.InternalTenantContext;
+
+public interface AnalyticsSanityDao {
+
+    public Collection<UUID> checkBstMatchesSubscriptionEvents(InternalTenantContext context);
+
+    public Collection<UUID> checkBiiMatchesInvoiceItems(InternalTenantContext context);
+
+    public Collection<UUID> checkBipMatchesInvoicePayments(InternalTenantContext context);
+
+    public Collection<UUID> checkBinAmountPaidMatchesInvoicePayments(InternalTenantContext context);
+
+    public Collection<UUID> checkBinAmountChargedMatchesInvoicePayments(InternalTenantContext context);
+
+    public Collection<UUID> checkBinBiiBalanceConsistency(InternalTenantContext context);
+
+    public Collection<UUID> checkBinBiiAmountCreditedConsistency(InternalTenantContext context);
+
+    public Collection<UUID> checkBacBinBiiConsistency(InternalTenantContext context);
+
+    public Collection<UUID> checkBacTagsMatchesTags(InternalTenantContext context);
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsSanitySqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsSanitySqlDao.java
new file mode 100644
index 0000000..fe9931f
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsSanitySqlDao.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010-2012 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.analytics.dao;
+
+import java.util.Collection;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.callcontext.InternalTenantContextBinder;
+import com.ning.billing.util.dao.UuidMapper;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(UuidMapper.class)
+public interface AnalyticsSanitySqlDao extends Transactional<AnalyticsSanitySqlDao>, Transmogrifier {
+
+    @SqlQuery
+    public Collection<UUID> checkBstMatchesSubscriptionEvents(@InternalTenantContextBinder final InternalTenantContext context);
+
+    @SqlQuery
+    public Collection<UUID> checkBiiMatchesInvoiceItems(@InternalTenantContextBinder final InternalTenantContext context);
+
+    @SqlQuery
+    public Collection<UUID> checkBipMatchesInvoicePayments(@InternalTenantContextBinder final InternalTenantContext context);
+
+    @SqlQuery
+    public Collection<UUID> checkBinAmountPaidMatchesInvoicePayments(@InternalTenantContextBinder final InternalTenantContext context);
+
+    @SqlQuery
+    public Collection<UUID> checkBinAmountChargedMatchesInvoicePayments(@InternalTenantContextBinder final InternalTenantContext context);
+
+    @SqlQuery
+    public Collection<UUID> checkBinBiiBalanceConsistency(@InternalTenantContextBinder final InternalTenantContext context);
+
+    @SqlQuery
+    public Collection<UUID> checkBinBiiAmountCreditedConsistency(@InternalTenantContextBinder final InternalTenantContext context);
+
+    @SqlQuery
+    public Collection<UUID> checkBacBinBiiConsistency(@InternalTenantContextBinder final InternalTenantContext context);
+
+    @SqlQuery
+    public Collection<UUID> checkBacTagsMatchesTags(@InternalTenantContextBinder final InternalTenantContext context);
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
index 5f062fa..7a7e22d 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
@@ -30,26 +30,28 @@ import org.skife.jdbi.v2.sqlobject.Binder;
 import org.skife.jdbi.v2.sqlobject.BinderFactory;
 import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
 
-import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
 
 @BindingAnnotation(BusinessAccountBinder.BacBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface BusinessAccountBinder {
+
     public static class BacBinderFactory implements BinderFactory {
+
         public Binder build(final Annotation annotation) {
-            return new Binder<BusinessAccountBinder, BusinessAccount>() {
-                public void bind(final SQLStatement q, final BusinessAccountBinder bind, final BusinessAccount account) {
+            return new Binder<BusinessAccountBinder, BusinessAccountModelDao>() {
+                public void bind(final SQLStatement q, final BusinessAccountBinder bind, final BusinessAccountModelDao account) {
                     final DateTime dateTimeNow = new DateTime(DateTimeZone.UTC);
 
-                    if (account.getCreatedDt() != null) {
-                        q.bind("created_date", account.getCreatedDt().getMillis());
+                    if (account.getCreatedDate() != null) {
+                        q.bind("created_date", account.getCreatedDate().getMillis());
                     } else {
                         q.bind("created_date", dateTimeNow.getMillis());
                     }
 
-                    if (account.getUpdatedDt() != null) {
-                        q.bind("updated_date", account.getUpdatedDt().getMillis());
+                    if (account.getUpdatedDate() != null) {
+                        q.bind("updated_date", account.getUpdatedDate().getMillis());
                     } else {
                         q.bind("updated_date", dateTimeNow.getMillis());
                     }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldMapper.java
index 411af1a..2928ac4 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldMapper.java
@@ -23,15 +23,16 @@ import java.util.UUID;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessAccountField;
+import com.ning.billing.analytics.model.BusinessAccountFieldModelDao;
+
+public class BusinessAccountFieldMapper implements ResultSetMapper<BusinessAccountFieldModelDao> {
 
-public class BusinessAccountFieldMapper implements ResultSetMapper<BusinessAccountField> {
     @Override
-    public BusinessAccountField map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+    public BusinessAccountFieldModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
         final UUID accountId = UUID.fromString(r.getString(1));
         final String accountKey = r.getString(2);
         final String name = r.getString(3);
         final String value = r.getString(4);
-        return new BusinessAccountField(accountId, accountKey, name, value);
+        return new BusinessAccountFieldModelDao(accountId, accountKey, name, value);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java
index f8e00fc..f8ac268 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java
@@ -24,7 +24,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessAccountField;
+import com.ning.billing.analytics.model.BusinessAccountFieldModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -34,8 +34,8 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessAccountFieldSqlDao {
 
     @SqlQuery
-    List<BusinessAccountField> getFieldsForAccountByKey(@Bind("account_key") final String accountKey,
-                                                        @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessAccountFieldModelDao> getFieldsForAccountByKey(@Bind("account_key") final String accountKey,
+                                                                @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
     int addField(@Bind("account_id") final String accountId,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java
index 4c48746..0fe0cdc 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java
@@ -26,14 +26,14 @@ import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
 import com.ning.billing.util.dao.MapperBase;
 
-public class BusinessAccountMapper extends MapperBase implements ResultSetMapper<BusinessAccount> {
+public class BusinessAccountMapper extends MapperBase implements ResultSetMapper<BusinessAccountModelDao> {
 
     @Override
-    public BusinessAccount map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
-        return new BusinessAccount(
+    public BusinessAccountModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessAccountModelDao(
                 UUID.fromString(r.getString(1)),
                 r.getString(2),
                 r.getString(6),
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java
index f223626..193b84f 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountSqlDao.java
@@ -26,7 +26,7 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -39,19 +39,19 @@ public interface BusinessAccountSqlDao extends Transactional<BusinessAccountSqlD
     List<TimeSeriesTuple> getAccountsCreatedOverTime(@InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    BusinessAccount getAccount(@Bind("account_id") final String accountId,
-                               @InternalTenantContextBinder final InternalTenantContext context);
+    BusinessAccountModelDao getAccount(@Bind("account_id") final String accountId,
+                                       @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    BusinessAccount getAccountByKey(@Bind("account_key") String accountKey,
-                                    @InternalTenantContextBinder final InternalTenantContext context);
+    BusinessAccountModelDao getAccountByKey(@Bind("account_key") String accountKey,
+                                            @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createAccount(@BusinessAccountBinder final BusinessAccount account,
+    int createAccount(@BusinessAccountBinder final BusinessAccountModelDao account,
                       @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
-    int saveAccount(@BusinessAccountBinder final BusinessAccount account,
+    int saveAccount(@BusinessAccountBinder final BusinessAccountModelDao account,
                     @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagMapper.java
index e8897d7..32654ff 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagMapper.java
@@ -23,14 +23,15 @@ import java.util.UUID;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessAccountTag;
+import com.ning.billing.analytics.model.BusinessAccountTagModelDao;
+
+public class BusinessAccountTagMapper implements ResultSetMapper<BusinessAccountTagModelDao> {
 
-public class BusinessAccountTagMapper implements ResultSetMapper<BusinessAccountTag> {
     @Override
-    public BusinessAccountTag map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+    public BusinessAccountTagModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
         final UUID accountId = UUID.fromString(r.getString(1));
         final String accountKey = r.getString(2);
         final String name = r.getString(3);
-        return new BusinessAccountTag(accountId, accountKey, name);
+        return new BusinessAccountTagModelDao(accountId, accountKey, name);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java
index f197c84..dd39791 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java
@@ -24,7 +24,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessAccountTag;
+import com.ning.billing.analytics.model.BusinessAccountTagModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -34,8 +34,8 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessAccountTagSqlDao {
 
     @SqlQuery
-    List<BusinessAccountTag> getTagsForAccountByKey(@Bind("account_key") final String accountKey,
-                                                    @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessAccountTagModelDao> getTagsForAccountByKey(@Bind("account_key") final String accountKey,
+                                                            @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
     int addTag(@Bind("account_id") final String accountId,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceBinder.java
index c1cdd5b..1b0db33 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceBinder.java
@@ -30,17 +30,19 @@ import org.skife.jdbi.v2.sqlobject.Binder;
 import org.skife.jdbi.v2.sqlobject.BinderFactory;
 import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
 
-import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.model.BusinessInvoiceModelDao;
 import com.ning.billing.analytics.utils.Rounder;
 
 @BindingAnnotation(BusinessInvoiceBinder.BinBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface BusinessInvoiceBinder {
+
     public static class BinBinderFactory implements BinderFactory {
+
         public Binder build(final Annotation annotation) {
-            return new Binder<BusinessInvoiceBinder, BusinessInvoice>() {
-                public void bind(final SQLStatement q, final BusinessInvoiceBinder bind, final BusinessInvoice invoice) {
+            return new Binder<BusinessInvoiceBinder, BusinessInvoiceModelDao>() {
+                public void bind(final SQLStatement q, final BusinessInvoiceBinder bind, final BusinessInvoiceModelDao invoice) {
                     q.bind("invoice_id", invoice.getInvoiceId().toString());
 
                     if (invoice.getInvoiceNumber() != null) {
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldMapper.java
index d75dffc..dcb1f61 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldMapper.java
@@ -23,11 +23,12 @@ import java.util.UUID;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessInvoiceField;
+import com.ning.billing.analytics.model.BusinessInvoiceFieldModelDao;
+
+public class BusinessInvoiceFieldMapper implements ResultSetMapper<BusinessInvoiceFieldModelDao> {
 
-public class BusinessInvoiceFieldMapper implements ResultSetMapper<BusinessInvoiceField> {
     @Override
-    public BusinessInvoiceField map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
-        return new BusinessInvoiceField(UUID.fromString(r.getString(1)), r.getString(2), r.getString(3));
+    public BusinessInvoiceFieldModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessInvoiceFieldModelDao(UUID.fromString(r.getString(1)), r.getString(2), r.getString(3));
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java
index 96e69d1..6cbec80 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java
@@ -24,7 +24,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessInvoiceField;
+import com.ning.billing.analytics.model.BusinessInvoiceFieldModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -34,8 +34,8 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessInvoiceFieldSqlDao {
 
     @SqlQuery
-    List<BusinessInvoiceField> getFieldsForInvoice(@Bind("invoice_id") final String invoiceId,
-                                                   @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessInvoiceFieldModelDao> getFieldsForInvoice(@Bind("invoice_id") final String invoiceId,
+                                                           @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
     int addField(@Bind("invoice_id") final String invoiceId,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemBinder.java
index 19e97c5..1aee24c 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemBinder.java
@@ -30,7 +30,7 @@ import org.skife.jdbi.v2.sqlobject.Binder;
 import org.skife.jdbi.v2.sqlobject.BinderFactory;
 import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
 
-import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessInvoiceItemModelDao;
 import com.ning.billing.analytics.utils.Rounder;
 
 @BindingAnnotation(BusinessInvoiceItemBinder.BiiBinderFactory.class)
@@ -41,8 +41,8 @@ public @interface BusinessInvoiceItemBinder {
     public static class BiiBinderFactory implements BinderFactory {
 
         public Binder build(final Annotation annotation) {
-            return new Binder<BusinessInvoiceItemBinder, BusinessInvoiceItem>() {
-                public void bind(final SQLStatement q, final BusinessInvoiceItemBinder bind, final BusinessInvoiceItem invoiceItem) {
+            return new Binder<BusinessInvoiceItemBinder, BusinessInvoiceItemModelDao>() {
+                public void bind(final SQLStatement q, final BusinessInvoiceItemBinder bind, final BusinessInvoiceItemModelDao invoiceItem) {
                     q.bind("item_id", invoiceItem.getItemId().toString());
                     if (invoiceItem.getLinkedItemId() != null) {
                         q.bind("linked_item_id", invoiceItem.getLinkedItemId().toString());
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemMapper.java
index eb36155..4927546 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemMapper.java
@@ -27,14 +27,14 @@ import org.joda.time.LocalDate;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessInvoiceItemModelDao;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.dao.MapperBase;
 
-public class BusinessInvoiceItemMapper extends MapperBase implements ResultSetMapper<BusinessInvoiceItem> {
+public class BusinessInvoiceItemMapper extends MapperBase implements ResultSetMapper<BusinessInvoiceItemModelDao> {
 
     @Override
-    public BusinessInvoiceItem map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+    public BusinessInvoiceItemModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
         final UUID itemId = getUUID(r, "item_id");
         final UUID linkedItemId = getUUID(r, "linked_item_id");
         final DateTime createdDate = new DateTime(r.getLong("created_date"), DateTimeZone.UTC);
@@ -53,8 +53,8 @@ public class BusinessInvoiceItemMapper extends MapperBase implements ResultSetMa
         final BigDecimal amount = BigDecimal.valueOf(r.getDouble("amount"));
         final Currency currency = Currency.valueOf(r.getString("currency"));
 
-        return new BusinessInvoiceItem(amount, billingPeriod, createdDate, currency, endDate, externalKey, invoiceId,
-                                       itemId, linkedItemId, itemType, phase, productCategory, productName, productType, slug,
-                                       startDate, updatedDate);
+        return new BusinessInvoiceItemModelDao(amount, billingPeriod, createdDate, currency, endDate, externalKey, invoiceId,
+                                               itemId, linkedItemId, itemType, phase, productCategory, productName, productType, slug,
+                                               startDate, updatedDate);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java
index c464094..041eb21 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java
@@ -26,7 +26,7 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessInvoiceItemModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -36,19 +36,19 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessInvoiceItemSqlDao extends Transactional<BusinessInvoiceItemSqlDao>, Transmogrifier {
 
     @SqlQuery
-    BusinessInvoiceItem getInvoiceItem(@Bind("item_id") final String itemId,
-                                       @InternalTenantContextBinder final InternalTenantContext context);
+    BusinessInvoiceItemModelDao getInvoiceItem(@Bind("item_id") final String itemId,
+                                               @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessInvoiceItem> getInvoiceItemsForInvoice(@Bind("invoice_id") final String invoiceId,
-                                                        @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessInvoiceItemModelDao> getInvoiceItemsForInvoice(@Bind("invoice_id") final String invoiceId,
+                                                                @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessInvoiceItem> getInvoiceItemsForBundleByKey(@Bind("external_key") final String externalKey,
-                                                            @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessInvoiceItemModelDao> getInvoiceItemsForBundleByKey(@Bind("external_key") final String externalKey,
+                                                                    @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createInvoiceItem(@BusinessInvoiceItemBinder final BusinessInvoiceItem invoiceItem,
+    int createInvoiceItem(@BusinessInvoiceItemBinder final BusinessInvoiceItemModelDao invoiceItem,
                           @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceMapper.java
index 9c9f730..ac16b5b 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceMapper.java
@@ -27,13 +27,14 @@ import org.joda.time.LocalDate;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.model.BusinessInvoiceModelDao;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.dao.MapperBase;
 
-public class BusinessInvoiceMapper extends MapperBase implements ResultSetMapper<BusinessInvoice> {
+public class BusinessInvoiceMapper extends MapperBase implements ResultSetMapper<BusinessInvoiceModelDao> {
+
     @Override
-    public BusinessInvoice map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+    public BusinessInvoiceModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
         final UUID invoiceId = UUID.fromString(r.getString(1));
         final Integer invoiceNumber = r.getInt(2);
         final DateTime createdDate = new DateTime(r.getLong(3), DateTimeZone.UTC);
@@ -48,7 +49,7 @@ public class BusinessInvoiceMapper extends MapperBase implements ResultSetMapper
         final BigDecimal amountCharged = BigDecimal.valueOf(r.getDouble(12));
         final BigDecimal amountCredited = BigDecimal.valueOf(r.getDouble(13));
 
-        return new BusinessInvoice(accountId, accountKey, amountCharged, amountCredited, amountPaid, balance, createdDate, currency,
-                                   invoiceDate, invoiceId, invoiceNumber, targetDate, updatedDate);
+        return new BusinessInvoiceModelDao(accountId, accountKey, amountCharged, amountCredited, amountPaid, balance, createdDate, currency,
+                                           invoiceDate, invoiceId, invoiceNumber, targetDate, updatedDate);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentBinder.java
index b67e0ea..6bb75f1 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentBinder.java
@@ -31,19 +31,21 @@ import org.skife.jdbi.v2.sqlobject.Binder;
 import org.skife.jdbi.v2.sqlobject.BinderFactory;
 import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
 
-import com.ning.billing.analytics.model.BusinessInvoicePayment;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentModelDao;
 import com.ning.billing.analytics.utils.Rounder;
 
 @BindingAnnotation(BusinessInvoicePaymentBinder.BipBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface BusinessInvoicePaymentBinder {
+
     public static class BipBinderFactory implements BinderFactory {
+
         @Override
         public Binder build(final Annotation annotation) {
-            return new Binder<BusinessInvoicePaymentBinder, BusinessInvoicePayment>() {
+            return new Binder<BusinessInvoicePaymentBinder, BusinessInvoicePaymentModelDao>() {
                 @Override
-                public void bind(final SQLStatement q, final BusinessInvoicePaymentBinder bind, final BusinessInvoicePayment invoicePayment) {
+                public void bind(final SQLStatement q, final BusinessInvoicePaymentBinder bind, final BusinessInvoicePaymentModelDao invoicePayment) {
                     q.bind("payment_id", invoicePayment.getPaymentId().toString());
 
                     final DateTime dateTimeNow = new DateTime(DateTimeZone.UTC);
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldMapper.java
index ac391e1..3418e7f 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldMapper.java
@@ -23,11 +23,12 @@ import java.util.UUID;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessInvoicePaymentField;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentFieldModelDao;
+
+public class BusinessInvoicePaymentFieldMapper implements ResultSetMapper<BusinessInvoicePaymentFieldModelDao> {
 
-public class BusinessInvoicePaymentFieldMapper implements ResultSetMapper<BusinessInvoicePaymentField> {
     @Override
-    public BusinessInvoicePaymentField map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
-        return new BusinessInvoicePaymentField(UUID.fromString(r.getString(1)), r.getString(2), r.getString(3));
+    public BusinessInvoicePaymentFieldModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessInvoicePaymentFieldModelDao(UUID.fromString(r.getString(1)), r.getString(2), r.getString(3));
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java
index c7964f4..7c7bfa9 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java
@@ -24,7 +24,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessInvoicePaymentField;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentFieldModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -34,8 +34,8 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessInvoicePaymentFieldSqlDao {
 
     @SqlQuery
-    List<BusinessInvoicePaymentField> getFieldsForInvoicePayment(@Bind("payment_id") final String paymentId,
-                                                                 @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessInvoicePaymentFieldModelDao> getFieldsForInvoicePayment(@Bind("payment_id") final String paymentId,
+                                                                         @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
     int addField(@Bind("payment_id") final String paymentId,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentMapper.java
index e9dee70..2a7be16 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentMapper.java
@@ -26,12 +26,13 @@ import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessInvoicePayment;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentModelDao;
 import com.ning.billing.catalog.api.Currency;
 
-public class BusinessInvoicePaymentMapper implements ResultSetMapper<BusinessInvoicePayment> {
+public class BusinessInvoicePaymentMapper implements ResultSetMapper<BusinessInvoicePaymentModelDao> {
+
     @Override
-    public BusinessInvoicePayment map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+    public BusinessInvoicePaymentModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
         final UUID paymentId = UUID.fromString(r.getString(1));
         final DateTime createdDate = new DateTime(r.getLong(2), DateTimeZone.UTC);
         final DateTime updatedDate = new DateTime(r.getLong(3), DateTimeZone.UTC);
@@ -60,9 +61,9 @@ public class BusinessInvoicePaymentMapper implements ResultSetMapper<BusinessInv
             linkedInvoicePaymentId = null;
         }
 
-        return new BusinessInvoicePayment(accountKey, amount, extFirstPaymentRefId, extSecondPaymentRefId, cardCountry, cardType, createdDate, currency,
-                                          effectiveDate, invoiceId, paymentError, paymentId, paymentMethod, paymentType,
-                                          pluginName, processingStatus, requestedAmount, updatedDate, invoicePaymentType,
-                                          linkedInvoicePaymentId);
+        return new BusinessInvoicePaymentModelDao(accountKey, amount, extFirstPaymentRefId, extSecondPaymentRefId, cardCountry, cardType, createdDate, currency,
+                                                  effectiveDate, invoiceId, paymentError, paymentId, paymentMethod, paymentType,
+                                                  pluginName, processingStatus, requestedAmount, updatedDate, invoicePaymentType,
+                                                  linkedInvoicePaymentId);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java
index b3fdd5b..3215556 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java
@@ -26,7 +26,7 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessInvoicePayment;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -36,15 +36,15 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessInvoicePaymentSqlDao extends Transactional<BusinessInvoicePaymentSqlDao>, Transmogrifier {
 
     @SqlQuery
-    BusinessInvoicePayment getInvoicePayment(@Bind("payment_id") final String paymentId,
-                                             @InternalTenantContextBinder final InternalTenantContext context);
+    BusinessInvoicePaymentModelDao getInvoicePayment(@Bind("payment_id") final String paymentId,
+                                                     @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessInvoicePayment> getInvoicePaymentsForAccountByKey(@Bind("account_key") final String accountKey,
-                                                                   @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessInvoicePaymentModelDao> getInvoicePaymentsForAccountByKey(@Bind("account_key") final String accountKey,
+                                                                           @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createInvoicePayment(@BusinessInvoicePaymentBinder final BusinessInvoicePayment payment,
+    int createInvoicePayment(@BusinessInvoicePaymentBinder final BusinessInvoicePaymentModelDao payment,
                              @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagMapper.java
index c81c532..d1310bc 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagMapper.java
@@ -23,11 +23,12 @@ import java.util.UUID;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessInvoicePaymentTag;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentTagModelDao;
+
+public class BusinessInvoicePaymentTagMapper implements ResultSetMapper<BusinessInvoicePaymentTagModelDao> {
 
-public class BusinessInvoicePaymentTagMapper implements ResultSetMapper<BusinessInvoicePaymentTag> {
     @Override
-    public BusinessInvoicePaymentTag map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
-        return new BusinessInvoicePaymentTag(UUID.fromString(r.getString(1)), r.getString(2));
+    public BusinessInvoicePaymentTagModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessInvoicePaymentTagModelDao(UUID.fromString(r.getString(1)), r.getString(2));
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java
index 20af667..5a10eec 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java
@@ -24,7 +24,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessInvoicePaymentTag;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentTagModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -34,8 +34,8 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessInvoicePaymentTagSqlDao {
 
     @SqlQuery
-    List<BusinessInvoicePaymentTag> getTagsForInvoicePayment(@Bind("payment_id") final String paymentId,
-                                                             @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessInvoicePaymentTagModelDao> getTagsForInvoicePayment(@Bind("payment_id") final String paymentId,
+                                                                     @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
     int addTag(@Bind("payment_id") final String paymentId,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java
index 3f22fcc..eed6999 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java
@@ -26,7 +26,7 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.model.BusinessInvoiceModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -36,19 +36,19 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessInvoiceSqlDao extends Transactional<BusinessInvoiceSqlDao>, Transmogrifier {
 
     @SqlQuery
-    BusinessInvoice getInvoice(@Bind("invoice_id") final String invoiceId,
-                               @InternalTenantContextBinder final InternalTenantContext context);
+    BusinessInvoiceModelDao getInvoice(@Bind("invoice_id") final String invoiceId,
+                                       @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessInvoice> getInvoicesForAccount(@Bind("account_id") final String accountId,
-                                                @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessInvoiceModelDao> getInvoicesForAccount(@Bind("account_id") final String accountId,
+                                                        @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessInvoice> getInvoicesForAccountByKey(@Bind("account_key") final String accountKey,
-                                                     @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessInvoiceModelDao> getInvoicesForAccountByKey(@Bind("account_key") final String accountKey,
+                                                             @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createInvoice(@BusinessInvoiceBinder final BusinessInvoice invoice,
+    int createInvoice(@BusinessInvoiceBinder final BusinessInvoiceModelDao invoice,
                       @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagMapper.java
index c812143..8a6c850 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagMapper.java
@@ -23,11 +23,12 @@ import java.util.UUID;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessInvoiceTag;
+import com.ning.billing.analytics.model.BusinessInvoiceTagModelDao;
+
+public class BusinessInvoiceTagMapper implements ResultSetMapper<BusinessInvoiceTagModelDao> {
 
-public class BusinessInvoiceTagMapper implements ResultSetMapper<BusinessInvoiceTag> {
     @Override
-    public BusinessInvoiceTag map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
-        return new BusinessInvoiceTag(UUID.fromString(r.getString(1)), r.getString(2));
+    public BusinessInvoiceTagModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessInvoiceTagModelDao(UUID.fromString(r.getString(1)), r.getString(2));
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java
index 9e3e6f7..1eb83ae 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java
@@ -24,7 +24,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessInvoiceTag;
+import com.ning.billing.analytics.model.BusinessInvoiceTagModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -34,8 +34,8 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessInvoiceTagSqlDao {
 
     @SqlQuery
-    List<BusinessInvoiceTag> getTagsForInvoice(@Bind("invoice_id") final String invoiceId,
-                                               @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessInvoiceTagModelDao> getTagsForInvoice(@Bind("invoice_id") final String invoiceId,
+                                                       @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
     int addTag(@Bind("invoice_id") final String invoiceId,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusBinder.java
index 879b2ee..43adbde 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusBinder.java
@@ -28,16 +28,18 @@ import org.skife.jdbi.v2.sqlobject.Binder;
 import org.skife.jdbi.v2.sqlobject.BinderFactory;
 import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
 
-import com.ning.billing.analytics.model.BusinessOverdueStatus;
+import com.ning.billing.analytics.model.BusinessOverdueStatusModelDao;
 
 @BindingAnnotation(BusinessOverdueStatusBinder.BosBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface BusinessOverdueStatusBinder {
+
     public static class BosBinderFactory implements BinderFactory {
+
         public Binder build(final Annotation annotation) {
-            return new Binder<BusinessOverdueStatusBinder, BusinessOverdueStatus>() {
-                public void bind(final SQLStatement q, final BusinessOverdueStatusBinder bind, final BusinessOverdueStatus overdueStatus) {
+            return new Binder<BusinessOverdueStatusBinder, BusinessOverdueStatusModelDao>() {
+                public void bind(final SQLStatement q, final BusinessOverdueStatusBinder bind, final BusinessOverdueStatusModelDao overdueStatus) {
                     q.bind("account_key", overdueStatus.getAccountKey());
                     q.bind("bundle_id", overdueStatus.getBundleId().toString());
                     q.bind("external_key", overdueStatus.getExternalKey());
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusMapper.java
index 35ef90e..02a963d 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusMapper.java
@@ -25,11 +25,12 @@ import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessOverdueStatus;
+import com.ning.billing.analytics.model.BusinessOverdueStatusModelDao;
+
+public class BusinessOverdueStatusMapper implements ResultSetMapper<BusinessOverdueStatusModelDao> {
 
-public class BusinessOverdueStatusMapper implements ResultSetMapper<BusinessOverdueStatus> {
     @Override
-    public BusinessOverdueStatus map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+    public BusinessOverdueStatusModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
         final UUID bundleId = UUID.fromString(r.getString(1));
         final String externalKey = r.getString(2);
         final String accountKey = r.getString(3);
@@ -37,6 +38,6 @@ public class BusinessOverdueStatusMapper implements ResultSetMapper<BusinessOver
         final DateTime startDate = new DateTime(r.getLong(5), DateTimeZone.UTC);
         final DateTime endDate = new DateTime(r.getLong(6), DateTimeZone.UTC);
 
-        return new BusinessOverdueStatus(accountKey, bundleId, endDate, externalKey, startDate, status);
+        return new BusinessOverdueStatusModelDao(accountKey, bundleId, endDate, externalKey, startDate, status);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java
index 0936c0b..3a7a76f 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java
@@ -26,7 +26,7 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessOverdueStatus;
+import com.ning.billing.analytics.model.BusinessOverdueStatusModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -36,11 +36,11 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessOverdueStatusSqlDao extends Transactional<BusinessOverdueStatusSqlDao>, Transmogrifier {
 
     @SqlQuery
-    List<BusinessOverdueStatus> getOverdueStatusesForBundleByKey(@Bind("external_key") final String externalKey,
-                                                                 @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessOverdueStatusModelDao> getOverdueStatusesForBundleByKey(@Bind("external_key") final String externalKey,
+                                                                         @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createOverdueStatus(@BusinessOverdueStatusBinder final BusinessOverdueStatus status,
+    int createOverdueStatus(@BusinessOverdueStatusBinder final BusinessOverdueStatusModelDao status,
                             @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSqlProvider.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSqlProvider.java
index 4e28ee4..6d086e0 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSqlProvider.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSqlProvider.java
@@ -22,6 +22,7 @@ import com.google.inject.Inject;
 import com.google.inject.Provider;
 
 public class BusinessSqlProvider<T> implements Provider<T> {
+
     @Inject
     private IDBI dbi;
 
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
index 73804a3..83a5524 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
@@ -29,16 +29,18 @@ import org.skife.jdbi.v2.sqlobject.BinderFactory;
 import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
 
 import com.ning.billing.analytics.model.BusinessSubscription;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 
 @BindingAnnotation(BusinessSubscriptionTransitionBinder.BstBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface BusinessSubscriptionTransitionBinder {
+
     public static class BstBinderFactory implements BinderFactory {
+
         public Binder build(final Annotation annotation) {
-            return new Binder<BusinessSubscriptionTransitionBinder, BusinessSubscriptionTransition>() {
-                public void bind(final SQLStatement q, final BusinessSubscriptionTransitionBinder bind, final BusinessSubscriptionTransition arg) {
+            return new Binder<BusinessSubscriptionTransitionBinder, BusinessSubscriptionTransitionModelDao>() {
+                public void bind(final SQLStatement q, final BusinessSubscriptionTransitionBinder bind, final BusinessSubscriptionTransitionModelDao arg) {
                     q.bind("total_ordering", arg.getTotalOrdering());
                     q.bind("bundle_id", arg.getBundleId().toString());
                     q.bind("external_key", arg.getExternalKey());
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldMapper.java
index 56540b8..f3e9b43 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldMapper.java
@@ -23,16 +23,17 @@ import java.util.UUID;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessSubscriptionTransitionField;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionFieldModelDao;
+
+public class BusinessSubscriptionTransitionFieldMapper implements ResultSetMapper<BusinessSubscriptionTransitionFieldModelDao> {
 
-public class BusinessSubscriptionTransitionFieldMapper implements ResultSetMapper<BusinessSubscriptionTransitionField> {
     @Override
-    public BusinessSubscriptionTransitionField map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+    public BusinessSubscriptionTransitionFieldModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
         final UUID bundleId = UUID.fromString(r.getString(1));
         final String externalKey = r.getString(2);
         final String accountKey = r.getString(3);
         final String name = r.getString(4);
         final String value = r.getString(5);
-        return new BusinessSubscriptionTransitionField(accountKey, bundleId, externalKey, name, value);
+        return new BusinessSubscriptionTransitionFieldModelDao(accountKey, bundleId, externalKey, name, value);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java
index 7bdfec1..0abf75d 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java
@@ -24,7 +24,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessSubscriptionTransitionField;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionFieldModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -34,8 +34,8 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessSubscriptionTransitionFieldSqlDao {
 
     @SqlQuery
-    List<BusinessSubscriptionTransitionField> getFieldsForBusinessSubscriptionTransitionByKey(@Bind("external_key") final String externalKey,
-                                                                                              @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessSubscriptionTransitionFieldModelDao> getFieldsForBusinessSubscriptionTransitionByKey(@Bind("external_key") final String externalKey,
+                                                                                                      @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
     int addField(@Bind("account_key") final String accountKey,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
index 97ecc5b..dce4638 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
@@ -28,14 +28,15 @@ import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
 import com.ning.billing.analytics.model.BusinessSubscription;
 import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.catalog.api.ProductCategory;
 
 import static com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 
-public class BusinessSubscriptionTransitionMapper implements ResultSetMapper<BusinessSubscriptionTransition> {
+public class BusinessSubscriptionTransitionMapper implements ResultSetMapper<BusinessSubscriptionTransitionModelDao> {
+
     @Override
-    public BusinessSubscriptionTransition map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+    public BusinessSubscriptionTransitionModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
         BusinessSubscription prev = new BusinessSubscription(
                 r.getString(9), // productName
                 r.getString(10), // productType
@@ -78,7 +79,7 @@ public class BusinessSubscriptionTransitionMapper implements ResultSetMapper<Bus
 
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.valueOf(r.getString(8));
 
-        return new BusinessSubscriptionTransition(
+        return new BusinessSubscriptionTransitionModelDao(
                 r.getLong(1),
                 UUID.fromString(r.getString(2)),
                 r.getString(3),
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.java
index 0e65c7b..873c51a 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionSqlDao.java
@@ -25,7 +25,7 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -40,19 +40,19 @@ public interface BusinessSubscriptionTransitionSqlDao extends Transactional<Busi
                                                           @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessSubscriptionTransition> getTransitionsByKey(@Bind("external_key") final String externalKey,
-                                                             @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessSubscriptionTransitionModelDao> getTransitionsByKey(@Bind("external_key") final String externalKey,
+                                                                     @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessSubscriptionTransition> getTransitionForSubscription(@Bind("subscription_id") final String subscriptionId,
-                                                                      @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessSubscriptionTransitionModelDao> getTransitionForSubscription(@Bind("subscription_id") final String subscriptionId,
+                                                                              @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlQuery
-    List<BusinessSubscriptionTransition> getTransitionsForAccount(@Bind("account_key") final String accountKey,
-                                                                  @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessSubscriptionTransitionModelDao> getTransitionsForAccount(@Bind("account_key") final String accountKey,
+                                                                          @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
-    int createTransition(@BusinessSubscriptionTransitionBinder final BusinessSubscriptionTransition transition,
+    int createTransition(@BusinessSubscriptionTransitionBinder final BusinessSubscriptionTransitionModelDao transition,
                          @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagMapper.java
index 25ae0be..b3f9bf9 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagMapper.java
@@ -23,15 +23,16 @@ import java.util.UUID;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.model.BusinessSubscriptionTransitionTag;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionTagModelDao;
+
+public class BusinessSubscriptionTransitionTagMapper implements ResultSetMapper<BusinessSubscriptionTransitionTagModelDao> {
 
-public class BusinessSubscriptionTransitionTagMapper implements ResultSetMapper<BusinessSubscriptionTransitionTag> {
     @Override
-    public BusinessSubscriptionTransitionTag map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+    public BusinessSubscriptionTransitionTagModelDao map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
         final UUID bundleId = UUID.fromString(r.getString(1));
         final String externalKey = r.getString(2);
         final String accountKey = r.getString(3);
         final String name = r.getString(4);
-        return new BusinessSubscriptionTransitionTag(accountKey, bundleId, externalKey, name);
+        return new BusinessSubscriptionTransitionTagModelDao(accountKey, bundleId, externalKey, name);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java
index 75c1bf5..dbf1231 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java
@@ -24,7 +24,7 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
-import com.ning.billing.analytics.model.BusinessSubscriptionTransitionTag;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionTagModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -34,8 +34,8 @@ import com.ning.billing.util.callcontext.InternalTenantContextBinder;
 public interface BusinessSubscriptionTransitionTagSqlDao {
 
     @SqlQuery
-    List<BusinessSubscriptionTransitionTag> getTagsForBusinessSubscriptionTransitionByKey(@Bind("external_key") final String externalKey,
-                                                                                          @InternalTenantContextBinder final InternalTenantContext context);
+    List<BusinessSubscriptionTransitionTagModelDao> getTagsForBusinessSubscriptionTransitionByKey(@Bind("external_key") final String externalKey,
+                                                                                                  @InternalTenantContextBinder final InternalTenantContext context);
 
     @SqlUpdate
     int addTag(@Bind("account_key") final String accountKey,
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java
index e91c988..293218a 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java
@@ -22,13 +22,13 @@ import javax.inject.Inject;
 
 import com.ning.billing.analytics.api.DefaultTimeSeriesData;
 import com.ning.billing.analytics.api.TimeSeriesData;
-import com.ning.billing.analytics.model.BusinessAccount;
-import com.ning.billing.analytics.model.BusinessAccountTag;
-import com.ning.billing.analytics.model.BusinessInvoice;
-import com.ning.billing.analytics.model.BusinessInvoiceItem;
-import com.ning.billing.analytics.model.BusinessInvoicePayment;
-import com.ning.billing.analytics.model.BusinessOverdueStatus;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
+import com.ning.billing.analytics.model.BusinessAccountTagModelDao;
+import com.ning.billing.analytics.model.BusinessInvoiceItemModelDao;
+import com.ning.billing.analytics.model.BusinessInvoiceModelDao;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentModelDao;
+import com.ning.billing.analytics.model.BusinessOverdueStatusModelDao;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public class DefaultAnalyticsDao implements AnalyticsDao {
@@ -69,42 +69,42 @@ public class DefaultAnalyticsDao implements AnalyticsDao {
     }
 
     @Override
-    public BusinessAccount getAccountByKey(final String accountKey, final InternalTenantContext context) {
+    public BusinessAccountModelDao getAccountByKey(final String accountKey, final InternalTenantContext context) {
         return accountSqlDao.getAccountByKey(accountKey, context);
     }
 
     @Override
-    public List<BusinessSubscriptionTransition> getTransitionsByKey(final String externalKey, final InternalTenantContext context) {
+    public List<BusinessSubscriptionTransitionModelDao> getTransitionsByKey(final String externalKey, final InternalTenantContext context) {
         return subscriptionTransitionSqlDao.getTransitionsByKey(externalKey, context);
     }
 
     @Override
-    public List<BusinessSubscriptionTransition> getTransitionsForAccount(final String accountKey, final InternalTenantContext context) {
+    public List<BusinessSubscriptionTransitionModelDao> getTransitionsForAccount(final String accountKey, final InternalTenantContext context) {
         return subscriptionTransitionSqlDao.getTransitionsForAccount(accountKey, context);
     }
 
     @Override
-    public List<BusinessInvoice> getInvoicesByKey(final String accountKey, final InternalTenantContext context) {
+    public List<BusinessInvoiceModelDao> getInvoicesByKey(final String accountKey, final InternalTenantContext context) {
         return invoiceSqlDao.getInvoicesForAccountByKey(accountKey, context);
     }
 
     @Override
-    public List<BusinessAccountTag> getTagsForAccount(final String accountKey, final InternalTenantContext context) {
+    public List<BusinessAccountTagModelDao> getTagsForAccount(final String accountKey, final InternalTenantContext context) {
         return accountTagSqlDao.getTagsForAccountByKey(accountKey, context);
     }
 
     @Override
-    public List<BusinessInvoiceItem> getInvoiceItemsForInvoice(final String invoiceId, final InternalTenantContext context) {
+    public List<BusinessInvoiceItemModelDao> getInvoiceItemsForInvoice(final String invoiceId, final InternalTenantContext context) {
         return invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId, context);
     }
 
     @Override
-    public List<BusinessOverdueStatus> getOverdueStatusesForBundleByKey(final String externalKey, final InternalTenantContext context) {
+    public List<BusinessOverdueStatusModelDao> getOverdueStatusesForBundleByKey(final String externalKey, final InternalTenantContext context) {
         return overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey, context);
     }
 
     @Override
-    public List<BusinessInvoicePayment> getInvoicePaymentsForAccountByKey(final String accountKey, final InternalTenantContext context) {
+    public List<BusinessInvoicePaymentModelDao> getInvoicePaymentsForAccountByKey(final String accountKey, final InternalTenantContext context) {
         return invoicePaymentSqlDao.getInvoicePaymentsForAccountByKey(accountKey, context);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsSanityDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsSanityDao.java
new file mode 100644
index 0000000..8e97d89
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsSanityDao.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010-2012 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.analytics.dao;
+
+import java.util.Collection;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.skife.jdbi.v2.IDBI;
+
+import com.ning.billing.util.callcontext.InternalTenantContext;
+
+public class DefaultAnalyticsSanityDao implements AnalyticsSanityDao {
+
+    private final AnalyticsSanitySqlDao sqlDao;
+
+    @Inject
+    public DefaultAnalyticsSanityDao(final IDBI dbi) {
+        sqlDao = dbi.onDemand(AnalyticsSanitySqlDao.class);
+    }
+
+    @Override
+    public Collection<UUID> checkBstMatchesSubscriptionEvents(final InternalTenantContext context) {
+        return sqlDao.checkBstMatchesSubscriptionEvents(context);
+    }
+
+    @Override
+    public Collection<UUID> checkBiiMatchesInvoiceItems(final InternalTenantContext context) {
+        return sqlDao.checkBiiMatchesInvoiceItems(context);
+    }
+
+    @Override
+    public Collection<UUID> checkBipMatchesInvoicePayments(final InternalTenantContext context) {
+        return sqlDao.checkBipMatchesInvoicePayments(context);
+    }
+
+    @Override
+    public Collection<UUID> checkBinAmountPaidMatchesInvoicePayments(final InternalTenantContext context) {
+        return sqlDao.checkBinAmountPaidMatchesInvoicePayments(context);
+    }
+
+    @Override
+    public Collection<UUID> checkBinAmountChargedMatchesInvoicePayments(final InternalTenantContext context) {
+        return sqlDao.checkBinAmountChargedMatchesInvoicePayments(context);
+    }
+
+    @Override
+    public Collection<UUID> checkBinBiiBalanceConsistency(final InternalTenantContext context) {
+        return sqlDao.checkBinBiiBalanceConsistency(context);
+    }
+
+    @Override
+    public Collection<UUID> checkBinBiiAmountCreditedConsistency(final InternalTenantContext context) {
+        return sqlDao.checkBinBiiAmountCreditedConsistency(context);
+    }
+
+    @Override
+    public Collection<UUID> checkBacBinBiiConsistency(final InternalTenantContext context) {
+        return sqlDao.checkBacBinBiiConsistency(context);
+    }
+
+    @Override
+    public Collection<UUID> checkBacTagsMatchesTags(final InternalTenantContext context) {
+        return sqlDao.checkBacTagsMatchesTags(context);
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/setup/AnalyticsModule.java b/analytics/src/main/java/com/ning/billing/analytics/setup/AnalyticsModule.java
index 7c9e1fd..ec2732e 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/setup/AnalyticsModule.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/setup/AnalyticsModule.java
@@ -22,9 +22,12 @@ import com.ning.billing.analytics.BusinessSubscriptionTransitionDao;
 import com.ning.billing.analytics.BusinessTagDao;
 import com.ning.billing.analytics.api.AnalyticsService;
 import com.ning.billing.analytics.api.DefaultAnalyticsService;
+import com.ning.billing.analytics.api.sanity.AnalyticsSanityApi;
+import com.ning.billing.analytics.api.sanity.DefaultAnalyticsSanityApi;
 import com.ning.billing.analytics.api.user.AnalyticsUserApi;
 import com.ning.billing.analytics.api.user.DefaultAnalyticsUserApi;
 import com.ning.billing.analytics.dao.AnalyticsDao;
+import com.ning.billing.analytics.dao.AnalyticsSanityDao;
 import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
 import com.ning.billing.analytics.dao.BusinessAccountTagSqlDao;
 import com.ning.billing.analytics.dao.BusinessInvoiceFieldSqlDao;
@@ -40,6 +43,7 @@ import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionFieldSqlDao;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionTagSqlDao;
 import com.ning.billing.analytics.dao.DefaultAnalyticsDao;
+import com.ning.billing.analytics.dao.DefaultAnalyticsSanityDao;
 
 import com.google.inject.AbstractModule;
 
@@ -67,9 +71,11 @@ public class AnalyticsModule extends AbstractModule {
         bind(AnalyticsListener.class).asEagerSingleton();
 
         bind(AnalyticsDao.class).to(DefaultAnalyticsDao.class).asEagerSingleton();
+        bind(AnalyticsSanityDao.class).to(DefaultAnalyticsSanityDao.class).asEagerSingleton();
         bind(AnalyticsService.class).to(DefaultAnalyticsService.class).asEagerSingleton();
 
         bind(DefaultAnalyticsUserApi.class).asEagerSingleton();
+        bind(AnalyticsSanityApi.class).to(DefaultAnalyticsSanityApi.class).asEagerSingleton();
         bind(AnalyticsUserApi.class).to(DefaultAnalyticsUserApi.class).asEagerSingleton();
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/utils/Rounder.java b/analytics/src/main/java/com/ning/billing/analytics/utils/Rounder.java
index 6222a34..74ad689 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/utils/Rounder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/utils/Rounder.java
@@ -19,6 +19,7 @@ package com.ning.billing.analytics.utils;
 import java.math.BigDecimal;
 
 public class Rounder {
+
     public static final int SCALE = 4;
 
     // Static only
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/AnalyticsSanitySqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/AnalyticsSanitySqlDao.sql.stg
new file mode 100644
index 0000000..4040115
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/AnalyticsSanitySqlDao.sql.stg
@@ -0,0 +1,301 @@
+group AnalyticsSanitySqlDao;
+
+CHECK_TENANT(prefix) ::= "<prefix>tenant_record_id = :tenantRecordId"
+AND_CHECK_TENANT(prefix) ::= "AND <CHECK_TENANT(prefix)>"
+
+checkBstMatchesSubscriptionEvents() ::= <<
+select distinct
+  account_id
+from (
+    select
+      account_id
+    , sum(per_event_check) account_check_left
+    , count(*) account_check_right
+    from (
+        select
+          account_id
+        , account_key_check and app_id and date_type and slug per_event_check
+        from (
+            select
+              q.account_key
+            , q.account_id
+            , b_account_key = account_key account_key_check
+            , b_app_id = app_id app_id
+            , case
+                when b_event like 'CANCEL_%' then b_req_dt = req_dt
+                when b_event like 'SYSTEM_CANCEL_%' then b_req_dt = eff_dt
+                else b_req_dt = req_dt  and b_eff_dt = eff_dt
+              end date_type
+            , coalesce(b_slug = slug, 1) slug
+            from (
+                select
+                  bst.total_ordering record_id
+                , bst.account_key b_account_key
+                , bst.external_key b_app_id
+                , bst.event b_event
+                , bst.next_slug b_slug
+                , from_unixtime(bst.requested_timestamp / 1000) b_req_dt
+                , from_unixtime(bst.next_start_date / 1000) b_eff_dt
+                , a.external_key account_key
+                , a.id account_id
+                , b.external_key app_id
+                , s.id
+                , e.event_type
+                , e.user_type
+                , e.phase_name slug
+                , e.effective_date eff_dt
+                , e.requested_date req_dt
+                , from_unixtime(coalesce(bst.next_start_date, bst.requested_timestamp) / 1000) b_dt
+                from subscription_events e
+                join subscriptions s on e.subscription_id = s.id
+                join bundles b on s.bundle_id = b.id
+                join accounts a on b.account_id = a.id
+                join bst on bst.total_ordering = e.record_id
+                where
+                    e.is_active = 1
+                and e.user_type != 'MIGRATE_BILLING'
+                <AND_CHECK_TENANT("e.")>
+                <AND_CHECK_TENANT("s.")>
+                <AND_CHECK_TENANT("b.")>
+                <AND_CHECK_TENANT("a.")>
+                <AND_CHECK_TENANT("bst.")>
+                order by e.record_id asc
+            ) q
+        ) p
+    ) r group by (account_id)
+) s
+where account_check_left != account_check_right
+;
+>>
+
+checkBiiMatchesInvoiceItems() ::= <<
+select distinct
+  account_id
+from (
+    select
+      id
+    , account_id
+    , start_date_check and end_date_check and amount_check and currency_check and linked_item_id_check and slug_check per_item_check
+    from (
+        select
+          ii.id
+        , ii.account_id
+        , ii.start_date = bii.start_date start_date_check
+        , coalesce(ii.end_date, bii.end_date) = bii.end_date end_date_check
+        , ii.amount = bii.amount amount_check
+        , ii.currency = bii.currency currency_check
+        , coalesce(ii.linked_item_id = bii.linked_item_id, 1) linked_item_id_check
+        , ii.phase_name = bii.slug slug_check
+        from invoice_items ii
+        join bii on ii.id = bii.item_id
+        where <CHECK_TENANT("ii.")>
+        <AND_CHECK_TENANT("bii.")>
+    ) p
+) q where !per_item_check
+;
+>>
+
+checkBipMatchesInvoicePayments() ::= <<
+select distinct
+  account_id
+from (
+    select
+      payment_id
+    , account_id
+    , amount_check and currency_check and payment_type_check and linked_invoice_payment_id_check and invoice_id_check total_check
+    from (
+        select
+          bip.payment_id
+        , a.id account_id
+        , bip.amount = ip.amount amount_check
+        , bip.currency = ip.currency currency_check
+        , bip.invoice_payment_type = ip.type payment_type_check
+        , bip.linked_invoice_payment_id = ip.linked_invoice_payment_id linked_invoice_payment_id_check
+        , bip.invoice_id = ip.invoice_id invoice_id_check
+        from bip
+        join invoice_payments ip on bip.payment_id = ip.id
+        join accounts a on a.record_id = ip.account_record_id
+        where <CHECK_TENANT("bip.")>
+        <AND_CHECK_TENANT("ip.")>
+        <AND_CHECK_TENANT("a.")>
+    ) p
+) q where !total_check
+;
+>>
+
+checkBinAmountPaidMatchesInvoicePayments() ::= <<
+select distinct
+  account_id
+from (
+    select
+      bin.invoice_id
+    , bin.account_id
+    , sum(ip.amount) = amount_paid amount_paid_check
+    from bin
+    join invoice_payments ip on bin.invoice_id = ip.invoice_id
+    where <CHECK_TENANT("bin.")>
+    <AND_CHECK_TENANT("ip.")>
+    group by ip.invoice_id, bin.account_id
+) p where !amount_paid_check
+;
+>>
+
+checkBinAmountChargedMatchesInvoicePayments() ::= <<
+select distinct
+  account_id
+from (
+    select
+      bin.invoice_id
+    , bin.account_id
+    , sum(ip.amount) = amount_charged amount_charged_check
+    from bin
+    join invoice_payments ip on bin.invoice_id = ip.invoice_id
+    where <CHECK_TENANT("bin.")>
+    <AND_CHECK_TENANT("ip.")>
+    group by ip.invoice_id, bin.account_id
+) p where !amount_charged_check
+;
+>>
+
+checkBinBiiBalanceConsistency() ::= <<
+select distinct
+  account_id
+from (
+    select
+      invoice_id
+    , account_id
+    , balance = amount_charged + total_adj_amount + total_cba - amount_paid balance_check
+    from (
+        select
+          bin.invoice_id
+        , bin.account_id
+        , bin.amount_paid
+        , bin.amount_charged
+        , bin.amount_credited
+        , bin.balance
+        , coalesce(total_adj_amount, 0) total_adj_amount
+        , coalesce(total_cba, 0) total_cba
+        from bin
+        left join (
+          select
+            bii.invoice_id
+          , sum(amount) total_adj_amount
+          from bii
+          join bin on bin.invoice_id = bii.invoice_id
+          where bii.item_type in ('CREDIT_ADJ', 'REFUND_ADJ', 'ITEM_ADJ')
+          <AND_CHECK_TENANT("bii.")>
+          <AND_CHECK_TENANT("bin.")>
+          group by (bii.invoice_id)
+        ) p on bin.invoice_id = p.invoice_id
+        left join (
+          select
+            q.invoice_id
+          , total_cba
+          from (
+              select
+                bii.invoice_id
+              , sum(amount) total_cba
+              from bii
+              join bin on bin.invoice_id = bii.invoice_id
+              where bii.item_type in ('CBA_ADJ')
+              <AND_CHECK_TENANT("bii.")>
+              <AND_CHECK_TENANT("bin.")>
+              group by (bii.invoice_id)
+          ) q
+        ) r on r.invoice_id = bin.invoice_id
+        where <CHECK_TENANT("bin.")>
+    ) s
+) t where !balance_check
+;
+>>
+
+checkBinBiiAmountCreditedConsistency() ::= <<
+select distinct
+  account_id
+from (
+    select
+      bii.invoice_id
+    , bin.account_id
+    , sum(amount) = bin.amount_credited credit_check
+    from bii
+    join bin on bin.invoice_id = bii.invoice_id
+    where bii.item_type in ('CREDIT_ADJ')
+    <AND_CHECK_TENANT("bii.")>
+    <AND_CHECK_TENANT("bin.")>
+    group by bii.invoice_id, bin.account_id
+) p where !credit_check
+;
+>>
+
+checkBacBinBiiConsistency() ::= <<
+select distinct
+  account_id
+from (
+    select
+      account_id
+    , total_invoice_balance_check and total_account_balance_check bac_check
+    from (
+        select
+          account_id
+        , total_invoice_balance_on_account = total_invoice_balance total_invoice_balance_check
+        , total_account_balance = total_invoice_balance_on_account - account_cba total_account_balance_check
+        from (
+            select
+              bac.account_id
+            , bac.total_invoice_balance total_invoice_balance_on_account
+            , sum(bin.balance) total_invoice_balance
+            , bac.balance total_account_balance
+            , coalesce(account_cba, 0) account_cba
+            from bac
+            -- some might not have cba items
+            left join (
+                select
+                  bin.account_id
+                , sum(bii.amount) account_cba
+                from bac
+                join bin on bin.account_id = bac.account_id
+                join bii on bii.invoice_id = bin.invoice_id
+                where bii.item_type = 'CBA_ADJ'
+                <AND_CHECK_TENANT("bac.")>
+                <AND_CHECK_TENANT("bin.")>
+                <AND_CHECK_TENANT("bii.")>
+                group by (bin.account_id)
+            ) p on bac.account_id = p.account_id
+            left join bin on bin.account_id = bac.account_id
+            where <CHECK_TENANT("bac.")>
+            <AND_CHECK_TENANT("bin.")>
+            group by bac.account_id, account_cba
+        ) q
+    ) r
+) s where !bac_check
+;
+>>
+
+checkBacTagsMatchesTags() ::= <<
+select distinct
+  account_id
+from (
+    select
+      account_id
+    , b_tag_name = tag_name tag_name_check
+    from (
+        select
+          bt.account_id account_id
+        , bt.name b_tag_name
+        , case
+          when t.tag_definition_id = '00000000-0000-0000-0000-000000000001' then 'AUTO_PAY_OFF'
+          when t.tag_definition_id = '00000000-0000-0000-0000-000000000002' then 'AUTO_INVOICING_OFF'
+          when t.tag_definition_id = '00000000-0000-0000-0000-000000000003' then 'OVERDUE_ENFORCEMENT_OFF'
+          when t.tag_definition_id = '00000000-0000-0000-0000-000000000003' then 'WRITTEN_OFF'
+          else tdef.name
+        end tag_name
+        from bac_tags bt
+        join tags t on t.object_id = bt.account_id
+        left join tag_definitions tdef on t.tag_definition_id = tdef.id
+        where t.object_type  = 'account'
+        <AND_CHECK_TENANT("bt.")>
+        <AND_CHECK_TENANT("t.")>
+        <AND_CHECK_TENANT("tdef.")>
+    ) p
+) q where ! tag_name_check;
+>>
diff --git a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
index 23ff8a4..ca7ad62 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
@@ -40,6 +40,7 @@ import com.ning.billing.util.glue.TagStoreModule;
 import com.ning.billing.util.tag.dao.TagDefinitionSqlDao;
 
 public class AnalyticsTestModule extends AnalyticsModule {
+
     @Override
     protected void configure() {
         super.configure();
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
index e9bc472..265631d 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
@@ -16,8 +16,6 @@
 
 package com.ning.billing.analytics.api;
 
-import static org.testng.Assert.fail;
-
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.sql.SQLException;
@@ -44,7 +42,7 @@ import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
 import com.ning.billing.analytics.model.BusinessSubscription;
 import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.catalog.MockPriceList;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -87,6 +85,8 @@ import com.ning.billing.util.svcsapi.bus.InternalBus;
 
 import com.google.inject.Inject;
 
+import static org.testng.Assert.fail;
+
 @Guice(modules = {AnalyticsTestModule.class})
 public class TestAnalyticsService extends AnalyticsTestSuiteWithEmbeddedDB {
 
@@ -128,7 +128,7 @@ public class TestAnalyticsService extends AnalyticsTestSuiteWithEmbeddedDB {
     private BusinessAccountSqlDao accountSqlDao;
 
     private EffectiveSubscriptionInternalEvent transition;
-    private BusinessSubscriptionTransition expectedTransition;
+    private BusinessSubscriptionTransitionModelDao expectedTransition;
 
     private AccountCreationInternalEvent accountCreationNotification;
     private InvoiceCreationInternalEvent invoiceCreationNotification;
@@ -204,7 +204,7 @@ public class TestAnalyticsService extends AnalyticsTestSuiteWithEmbeddedDB {
                 TOTAL_ORDERING,
                 null,
                 true), null, 1L, 1L);
-        expectedTransition = new BusinessSubscriptionTransition(
+        expectedTransition = new BusinessSubscriptionTransitionModelDao(
                 TOTAL_ORDERING,
                 transition.getBundleId(),
                 BUNDLE_EXTERNAL_KEY,
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java b/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
index 572f6c8..998e67a 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
@@ -46,10 +46,10 @@ import com.ning.billing.analytics.dao.BusinessInvoiceSqlDao;
 import com.ning.billing.analytics.dao.BusinessOverdueStatusSqlDao;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
 import com.ning.billing.analytics.dao.DefaultAnalyticsDao;
-import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
 import com.ning.billing.analytics.model.BusinessSubscription;
 import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.PhaseType;
@@ -110,8 +110,8 @@ public class TestDefaultAnalyticsUserApi extends AnalyticsTestSuiteWithEmbeddedD
 
     @Test(groups = "slow")
     public void testAccountsCreatedOverTime() throws Exception {
-        final BusinessAccount account = new BusinessAccount(UUID.randomUUID(), UUID.randomUUID().toString(), UUID.randomUUID().toString(), BigDecimal.ONE, clock.getUTCToday(),
-                                                            BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "FRANCE", "USD", clock.getUTCNow(), clock.getUTCNow());
+        final BusinessAccountModelDao account = new BusinessAccountModelDao(UUID.randomUUID(), UUID.randomUUID().toString(), UUID.randomUUID().toString(), BigDecimal.ONE, clock.getUTCToday(),
+                                                                            BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "FRANCE", "USD", clock.getUTCNow(), clock.getUTCNow());
         accountSqlDao.createAccount(account, internalCallContext);
 
         final TimeSeriesData data = analyticsUserApi.getAccountsCreatedOverTime(tenantContext);
@@ -130,7 +130,7 @@ public class TestDefaultAnalyticsUserApi extends AnalyticsTestSuiteWithEmbeddedD
         final Catalog catalog = Mockito.mock(Catalog.class);
         Mockito.when(catalog.findPlan(Mockito.anyString(), Mockito.<DateTime>any(), Mockito.<DateTime>any())).thenReturn(plan);
         Mockito.when(catalog.findPhase(Mockito.anyString(), Mockito.<DateTime>any(), Mockito.<DateTime>any())).thenReturn(phase);
-        final BusinessSubscriptionTransition transition = new BusinessSubscriptionTransition(
+        final BusinessSubscriptionTransitionModelDao transition = new BusinessSubscriptionTransitionModelDao(
                 3L,
                 UUID.randomUUID(),
                 UUID.randomUUID().toString(),
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
index a263962..28d76a8 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
@@ -33,10 +33,10 @@ import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
 import com.ning.billing.analytics.MockDuration;
 import com.ning.billing.analytics.MockPhase;
 import com.ning.billing.analytics.MockProduct;
-import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccountModelDao;
 import com.ning.billing.analytics.model.BusinessSubscription;
 import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.analytics.utils.Rounder;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -67,9 +67,9 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
     private final PlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
 
     private BusinessSubscriptionTransitionSqlDao businessSubscriptionTransitionSqlDao;
-    private BusinessSubscriptionTransition transition;
+    private BusinessSubscriptionTransitionModelDao transition;
     private BusinessAccountSqlDao businessAccountSqlDao;
-    private BusinessAccount account;
+    private BusinessAccountModelDao account;
 
     private final CatalogService catalogService = Mockito.mock(CatalogService.class);
     private final Catalog catalog = Mockito.mock(Catalog.class);
@@ -91,8 +91,8 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
         final BusinessSubscription nextSubscription = new BusinessSubscription(null, plan.getName(), phase.getName(), Currency.USD, clock.getUTCNow(), Subscription.SubscriptionState.CANCELLED, catalog);
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCancelled(plan.getName(), catalog, requestedTimestamp, requestedTimestamp);
 
-        transition = new BusinessSubscriptionTransition(TOTAL_ORDERING, BUNDLE_ID, EXTERNAL_KEY, ACCOUNT_ID, ACCOUNT_KEY,
-                                                        UUID.randomUUID(), requestedTimestamp, event, prevSubscription, nextSubscription);
+        transition = new BusinessSubscriptionTransitionModelDao(TOTAL_ORDERING, BUNDLE_ID, EXTERNAL_KEY, ACCOUNT_ID, ACCOUNT_KEY,
+                                                                UUID.randomUUID(), requestedTimestamp, event, prevSubscription, nextSubscription);
 
         final IDBI dbi = helper.getDBI();
         businessSubscriptionTransitionSqlDao = dbi.onDemand(BusinessSubscriptionTransitionSqlDao.class);
@@ -106,8 +106,8 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
     }
 
     private void setupBusinessAccount() {
-        account = new BusinessAccount(UUID.randomUUID(), ACCOUNT_KEY, UUID.randomUUID().toString(), BigDecimal.ONE, clock.getUTCToday(),
-                                      BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "FRANCE", CURRENCY, clock.getUTCNow(), clock.getUTCNow());
+        account = new BusinessAccountModelDao(UUID.randomUUID(), ACCOUNT_KEY, UUID.randomUUID().toString(), BigDecimal.ONE, clock.getUTCToday(),
+                                              BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "FRANCE", CURRENCY, clock.getUTCNow(), clock.getUTCNow());
 
         final IDBI dbi = helper.getDBI();
         businessAccountSqlDao = dbi.onDemand(BusinessAccountSqlDao.class);
@@ -122,7 +122,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
 
     @Test(groups = "slow")
     public void testTransitionsWithNullPrevSubscription() {
-        final BusinessSubscriptionTransition transitionWithNullPrev = new BusinessSubscriptionTransition(
+        final BusinessSubscriptionTransitionModelDao transitionWithNullPrev = new BusinessSubscriptionTransitionModelDao(
                 transition.getTotalOrdering(),
                 transition.getBundleId(),
                 transition.getExternalKey(),
@@ -136,14 +136,14 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
         );
         businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPrev, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
+        final List<BusinessSubscriptionTransitionModelDao> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullPrev);
     }
 
     @Test(groups = "slow")
     public void testTransitionsWithNullNextSubscription() {
-        final BusinessSubscriptionTransition transitionWithNullNext = new BusinessSubscriptionTransition(
+        final BusinessSubscriptionTransitionModelDao transitionWithNullNext = new BusinessSubscriptionTransitionModelDao(
                 transition.getTotalOrdering(),
                 transition.getBundleId(),
                 transition.getExternalKey(),
@@ -157,7 +157,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
         );
         businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullNext, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
+        final List<BusinessSubscriptionTransitionModelDao> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullNext);
     }
@@ -165,7 +165,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testTransitionsWithNullFieldsInSubscription() {
         final BusinessSubscription subscriptionWithNullFields = new BusinessSubscription(null, plan.getName(), phase.getName(), Currency.USD, null, null, catalog);
-        final BusinessSubscriptionTransition transitionWithNullFields = new BusinessSubscriptionTransition(
+        final BusinessSubscriptionTransitionModelDao transitionWithNullFields = new BusinessSubscriptionTransitionModelDao(
                 transition.getTotalOrdering(),
                 transition.getBundleId(),
                 transition.getExternalKey(),
@@ -179,7 +179,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
         );
         businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullFields, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
+        final List<BusinessSubscriptionTransitionModelDao> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullFields);
     }
@@ -187,7 +187,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testTransitionsWithNullPlanAndPhase() throws Exception {
         final BusinessSubscription subscriptionWithNullPlanAndPhase = new BusinessSubscription(null, null, null, Currency.USD, null, null, catalog);
-        final BusinessSubscriptionTransition transitionWithNullPlanAndPhase = new BusinessSubscriptionTransition(
+        final BusinessSubscriptionTransitionModelDao transitionWithNullPlanAndPhase = new BusinessSubscriptionTransitionModelDao(
                 transition.getTotalOrdering(),
                 transition.getBundleId(),
                 transition.getExternalKey(),
@@ -201,7 +201,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
         );
         businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPlanAndPhase, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
+        final List<BusinessSubscriptionTransitionModelDao> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0).getExternalKey(), transition.getExternalKey());
         Assert.assertEquals(transitions.get(0).getRequestedTimestamp(), transition.getRequestedTimestamp());
@@ -213,7 +213,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testTransitionsWithNullPlan() throws Exception {
         final BusinessSubscription subscriptionWithNullPlan = new BusinessSubscription(null, null, phase.getName(), Currency.USD, null, null, catalog);
-        final BusinessSubscriptionTransition transitionWithNullPlan = new BusinessSubscriptionTransition(
+        final BusinessSubscriptionTransitionModelDao transitionWithNullPlan = new BusinessSubscriptionTransitionModelDao(
                 transition.getTotalOrdering(),
                 transition.getBundleId(),
                 transition.getExternalKey(),
@@ -227,7 +227,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
         );
         businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPlan, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
+        final List<BusinessSubscriptionTransitionModelDao> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         // Null Plan but Phase - we don't turn the subscription into a null
         Assert.assertEquals(transitions.get(0), transitionWithNullPlan);
@@ -236,7 +236,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testTransitionsWithNullPhase() throws Exception {
         final BusinessSubscription subscriptionWithNullPhase = new BusinessSubscription(null, plan.getName(), null, Currency.USD, null, null, catalog);
-        final BusinessSubscriptionTransition transitionWithNullPhase = new BusinessSubscriptionTransition(
+        final BusinessSubscriptionTransitionModelDao transitionWithNullPhase = new BusinessSubscriptionTransitionModelDao(
                 transition.getTotalOrdering(),
                 transition.getBundleId(),
                 transition.getExternalKey(),
@@ -250,7 +250,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
         );
         businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPhase, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
+        final List<BusinessSubscriptionTransitionModelDao> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0).getExternalKey(), transition.getExternalKey());
         Assert.assertEquals(transitions.get(0).getRequestedTimestamp(), transition.getRequestedTimestamp());
@@ -266,7 +266,7 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
     public void testCreateAndRetrieveTransitions() {
         businessSubscriptionTransitionSqlDao.createTransition(transition, internalCallContext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
+        final List<BusinessSubscriptionTransitionModelDao> transitions = businessSubscriptionTransitionSqlDao.getTransitionsByKey(EXTERNAL_KEY, internalCallContext);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transition);
 
@@ -277,9 +277,9 @@ public class TestAnalyticsDao extends AnalyticsTestSuiteWithEmbeddedDB {
     public void testCreateSaveAndRetrieveAccounts() {
         // Create and retrieve an account
         businessAccountSqlDao.createAccount(account, internalCallContext);
-        final BusinessAccount foundAccount = businessAccountSqlDao.getAccountByKey(ACCOUNT_KEY, internalCallContext);
-        Assert.assertEquals(foundAccount.getCreatedDt().getMillis(), account.getCreatedDt().getMillis());
-        Assert.assertEquals(foundAccount.getUpdatedDt().getMillis(), account.getUpdatedDt().getMillis());
+        final BusinessAccountModelDao foundAccount = businessAccountSqlDao.getAccountByKey(ACCOUNT_KEY, internalCallContext);
+        Assert.assertEquals(foundAccount.getCreatedDate().getMillis(), account.getCreatedDate().getMillis());
+        Assert.assertEquals(foundAccount.getUpdatedDate().getMillis(), account.getUpdatedDate().getMillis());
         Assert.assertTrue(foundAccount.equals(account));
 
         // Try to update the account
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java
index c3d7167..9ac475a 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java
@@ -25,9 +25,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessAccountField;
+import com.ning.billing.analytics.model.BusinessAccountFieldModelDao;
 
 public class TestBusinessAccountFieldSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
+
     private BusinessAccountFieldSqlDao accountFieldSqlDao;
 
     @BeforeMethod(groups = "slow")
@@ -49,11 +50,11 @@ public class TestBusinessAccountFieldSqlDao extends AnalyticsTestSuiteWithEmbedd
 
         // Add an entry
         Assert.assertEquals(accountFieldSqlDao.addField(accountId.toString(), accountKey, name, value, internalCallContext), 1);
-        final List<BusinessAccountField> fieldsForAccount = accountFieldSqlDao.getFieldsForAccountByKey(accountKey, internalCallContext);
+        final List<BusinessAccountFieldModelDao> fieldsForAccount = accountFieldSqlDao.getFieldsForAccountByKey(accountKey, internalCallContext);
         Assert.assertEquals(fieldsForAccount.size(), 1);
 
         // Retrieve it
-        final BusinessAccountField accountField = fieldsForAccount.get(0);
+        final BusinessAccountFieldModelDao accountField = fieldsForAccount.get(0);
         Assert.assertEquals(accountField.getAccountId(), accountId);
         Assert.assertEquals(accountField.getAccountKey(), accountKey);
         Assert.assertEquals(accountField.getName(), name);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java
index 90f7f58..2631c25 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java
@@ -25,9 +25,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessAccountTag;
+import com.ning.billing.analytics.model.BusinessAccountTagModelDao;
 
 public class TestBusinessAccountTagSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
+
     private BusinessAccountTagSqlDao accountTagSqlDao;
 
     @BeforeMethod(groups = "slow")
@@ -48,11 +49,11 @@ public class TestBusinessAccountTagSqlDao extends AnalyticsTestSuiteWithEmbedded
 
         // Add an entry
         Assert.assertEquals(accountTagSqlDao.addTag(accountId.toString(), accountKey, name, internalCallContext), 1);
-        final List<BusinessAccountTag> tagsForAccount = accountTagSqlDao.getTagsForAccountByKey(accountKey, internalCallContext);
+        final List<BusinessAccountTagModelDao> tagsForAccount = accountTagSqlDao.getTagsForAccountByKey(accountKey, internalCallContext);
         Assert.assertEquals(tagsForAccount.size(), 1);
 
         // Retrieve it
-        final BusinessAccountTag accountTag = tagsForAccount.get(0);
+        final BusinessAccountTagModelDao accountTag = tagsForAccount.get(0);
         Assert.assertEquals(accountTag.getAccountId(), accountId);
         Assert.assertEquals(accountTag.getAccountKey(), accountKey);
         Assert.assertEquals(accountTag.getName(), name);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
index 72f70e0..920811e 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
@@ -25,9 +25,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessInvoiceField;
+import com.ning.billing.analytics.model.BusinessInvoiceFieldModelDao;
 
 public class TestBusinessInvoiceFieldSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
+
     private BusinessInvoiceFieldSqlDao invoiceFieldSqlDao;
 
     @BeforeMethod(groups = "slow")
@@ -48,11 +49,11 @@ public class TestBusinessInvoiceFieldSqlDao extends AnalyticsTestSuiteWithEmbedd
 
         // Add an entry
         Assert.assertEquals(invoiceFieldSqlDao.addField(invoiceId, name, value, internalCallContext), 1);
-        final List<BusinessInvoiceField> fieldsForInvoice = invoiceFieldSqlDao.getFieldsForInvoice(invoiceId, internalCallContext);
+        final List<BusinessInvoiceFieldModelDao> fieldsForInvoice = invoiceFieldSqlDao.getFieldsForInvoice(invoiceId, internalCallContext);
         Assert.assertEquals(fieldsForInvoice.size(), 1);
 
         // Retrieve it
-        final BusinessInvoiceField invoiceField = fieldsForInvoice.get(0);
+        final BusinessInvoiceFieldModelDao invoiceField = fieldsForInvoice.get(0);
         Assert.assertEquals(invoiceField.getInvoiceId().toString(), invoiceId);
         Assert.assertEquals(invoiceField.getName(), name);
         Assert.assertEquals(invoiceField.getValue(), value);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java
index 494abc4..a86074b 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java
@@ -27,7 +27,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessInvoiceItemModelDao;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
@@ -48,7 +48,7 @@ public class TestBusinessInvoiceItemSqlDao extends AnalyticsTestSuiteWithEmbedde
     public void testCRUD() throws Exception {
         final UUID invoiceId = UUID.randomUUID();
         final String externalKey = UUID.randomUUID().toString();
-        final BusinessInvoiceItem invoiceItem = createInvoiceItem(invoiceId, externalKey);
+        final BusinessInvoiceItemModelDao invoiceItem = createInvoiceItem(invoiceId, externalKey);
 
         // Verify initial state
         Assert.assertNull(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString(), internalCallContext));
@@ -75,10 +75,10 @@ public class TestBusinessInvoiceItemSqlDao extends AnalyticsTestSuiteWithEmbedde
     public void testSegmentation() throws Exception {
         final UUID invoiceId1 = UUID.randomUUID();
         final String externalKey1 = UUID.randomUUID().toString();
-        final BusinessInvoiceItem invoiceItem1 = createInvoiceItem(invoiceId1, externalKey1);
+        final BusinessInvoiceItemModelDao invoiceItem1 = createInvoiceItem(invoiceId1, externalKey1);
         final UUID invoiceId2 = UUID.randomUUID();
         final String externalKey2 = UUID.randomUUID().toString();
-        final BusinessInvoiceItem invoiceItem2 = createInvoiceItem(invoiceId2, externalKey2);
+        final BusinessInvoiceItemModelDao invoiceItem2 = createInvoiceItem(invoiceId2, externalKey2);
 
         // Create both invoice items
         Assert.assertEquals(invoiceItemSqlDao.createInvoiceItem(invoiceItem1, internalCallContext), 1);
@@ -108,7 +108,7 @@ public class TestBusinessInvoiceItemSqlDao extends AnalyticsTestSuiteWithEmbedde
         }
     }
 
-    private BusinessInvoiceItem createInvoiceItem(final UUID invoiceId, final String externalKey) {
+    private BusinessInvoiceItemModelDao createInvoiceItem(final UUID invoiceId, final String externalKey) {
         final BigDecimal amount = BigDecimal.TEN;
         final String billingPeriod = UUID.randomUUID().toString().substring(0, 20);
         final DateTime createdDate = clock.getUTCNow();
@@ -125,7 +125,7 @@ public class TestBusinessInvoiceItemSqlDao extends AnalyticsTestSuiteWithEmbedde
         final LocalDate startDate = clock.getUTCToday();
         final DateTime updatedDate = clock.getUTCNow();
 
-        return new BusinessInvoiceItem(amount, billingPeriod, createdDate, currency, endDate, externalKey, invoiceId, itemId,
-                                       linkedItemId, itemType, phase, productCategory, productName, productType, slug, startDate, updatedDate);
+        return new BusinessInvoiceItemModelDao(amount, billingPeriod, createdDate, currency, endDate, externalKey, invoiceId, itemId,
+                                               linkedItemId, itemType, phase, productCategory, productName, productType, slug, startDate, updatedDate);
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
index 9ee46c7..8db50d9 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
@@ -25,9 +25,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessInvoicePaymentField;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentFieldModelDao;
 
 public class TestBusinessInvoicePaymentFieldSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
+
     private BusinessInvoicePaymentFieldSqlDao invoicePaymentFieldSqlDao;
 
     @BeforeMethod(groups = "slow")
@@ -48,11 +49,11 @@ public class TestBusinessInvoicePaymentFieldSqlDao extends AnalyticsTestSuiteWit
 
         // Add an entry
         Assert.assertEquals(invoicePaymentFieldSqlDao.addField(paymentId, name, value, internalCallContext), 1);
-        final List<BusinessInvoicePaymentField> fieldsForInvoicePayment = invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId, internalCallContext);
+        final List<BusinessInvoicePaymentFieldModelDao> fieldsForInvoicePayment = invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId, internalCallContext);
         Assert.assertEquals(fieldsForInvoicePayment.size(), 1);
 
         // Retrieve it
-        final BusinessInvoicePaymentField invoicePaymentField = fieldsForInvoicePayment.get(0);
+        final BusinessInvoicePaymentFieldModelDao invoicePaymentField = fieldsForInvoicePayment.get(0);
         Assert.assertEquals(invoicePaymentField.getPaymentId().toString(), paymentId);
         Assert.assertEquals(invoicePaymentField.getName(), name);
         Assert.assertEquals(invoicePaymentField.getValue(), value);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
index c4eb863..70058b8 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
@@ -27,10 +27,11 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessInvoicePayment;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentModelDao;
 import com.ning.billing.catalog.api.Currency;
 
 public class TestBusinessInvoicePaymentSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
+
     private BusinessInvoicePaymentSqlDao invoicePaymentSqlDao;
 
     @BeforeMethod(groups = "slow")
@@ -44,7 +45,7 @@ public class TestBusinessInvoicePaymentSqlDao extends AnalyticsTestSuiteWithEmbe
         final String extFirstPaymentRefId = UUID.randomUUID().toString();
         final String extSecondPaymentRefId = UUID.randomUUID().toString();
         final String accountKey = UUID.randomUUID().toString();
-        final BusinessInvoicePayment invoicePayment = createInvoicePayment(extFirstPaymentRefId, extSecondPaymentRefId, accountKey);
+        final BusinessInvoicePaymentModelDao invoicePayment = createInvoicePayment(extFirstPaymentRefId, extSecondPaymentRefId, accountKey);
 
         // Verify initial state
         Assert.assertNull(invoicePaymentSqlDao.getInvoicePayment(invoicePayment.getPaymentId().toString(), internalCallContext));
@@ -69,11 +70,11 @@ public class TestBusinessInvoicePaymentSqlDao extends AnalyticsTestSuiteWithEmbe
         final String extFirstPaymentRefId1 = UUID.randomUUID().toString();
         final String extSecondPaymentRefId1 = UUID.randomUUID().toString();
         final String accountKey1 = UUID.randomUUID().toString();
-        final BusinessInvoicePayment invoicePayment1 = createInvoicePayment(extFirstPaymentRefId1, extSecondPaymentRefId1, accountKey1);
+        final BusinessInvoicePaymentModelDao invoicePayment1 = createInvoicePayment(extFirstPaymentRefId1, extSecondPaymentRefId1, accountKey1);
         final String extFirstPaymentRefId2 = UUID.randomUUID().toString();
         final String extSecondPaymentRefId2 = UUID.randomUUID().toString();
         final String accountKey2 = UUID.randomUUID().toString();
-        final BusinessInvoicePayment invoicePayment2 = createInvoicePayment(extFirstPaymentRefId2, extSecondPaymentRefId2,  accountKey2);
+        final BusinessInvoicePaymentModelDao invoicePayment2 = createInvoicePayment(extFirstPaymentRefId2, extSecondPaymentRefId2, accountKey2);
 
         // Create both invoice payments
         Assert.assertEquals(invoicePaymentSqlDao.createInvoicePayment(invoicePayment1, internalCallContext), 1);
@@ -103,7 +104,7 @@ public class TestBusinessInvoicePaymentSqlDao extends AnalyticsTestSuiteWithEmbe
         }
     }
 
-    private BusinessInvoicePayment createInvoicePayment(final String extFirstPaymentRefId, final String extSecondPaymentRefId, final String accountKey) {
+    private BusinessInvoicePaymentModelDao createInvoicePayment(final String extFirstPaymentRefId, final String extSecondPaymentRefId, final String accountKey) {
         final BigDecimal amount = BigDecimal.ONE;
         final String cardCountry = UUID.randomUUID().toString().substring(0, 20);
         final String cardType = UUID.randomUUID().toString().substring(0, 20);
@@ -122,12 +123,12 @@ public class TestBusinessInvoicePaymentSqlDao extends AnalyticsTestSuiteWithEmbe
         final String invoicePaymentType = UUID.randomUUID().toString().substring(0, 10);
         final UUID linkedInvoicePaymentId = UUID.randomUUID();
 
-        return new BusinessInvoicePayment(accountKey, amount, extFirstPaymentRefId, extSecondPaymentRefId,
-                                          cardCountry, cardType, createdDate,
-                                          currency, effectiveDate, invoiceId,
-                                          paymentError, paymentId, paymentMethod,
-                                          paymentType, pluginName, processingStatus,
-                                          requestedAmount, updatedDate, invoicePaymentType,
-                                          linkedInvoicePaymentId);
+        return new BusinessInvoicePaymentModelDao(accountKey, amount, extFirstPaymentRefId, extSecondPaymentRefId,
+                                                  cardCountry, cardType, createdDate,
+                                                  currency, effectiveDate, invoiceId,
+                                                  paymentError, paymentId, paymentMethod,
+                                                  paymentType, pluginName, processingStatus,
+                                                  requestedAmount, updatedDate, invoicePaymentType,
+                                                  linkedInvoicePaymentId);
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
index a3d4be3..ad24025 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
@@ -25,9 +25,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessInvoicePaymentTag;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentTagModelDao;
 
 public class TestBusinessInvoicePaymentTagSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
+
     private BusinessInvoicePaymentTagSqlDao invoicePaymentTagSqlDao;
 
     @BeforeMethod(groups = "slow")
@@ -47,11 +48,11 @@ public class TestBusinessInvoicePaymentTagSqlDao extends AnalyticsTestSuiteWithE
 
         // Add an entry
         Assert.assertEquals(invoicePaymentTagSqlDao.addTag(paymentId, name, internalCallContext), 1);
-        final List<BusinessInvoicePaymentTag> tagsForInvoicePayment = invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId, internalCallContext);
+        final List<BusinessInvoicePaymentTagModelDao> tagsForInvoicePayment = invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId, internalCallContext);
         Assert.assertEquals(tagsForInvoicePayment.size(), 1);
 
         // Retrieve it
-        final BusinessInvoicePaymentTag invoicePaymentTag = tagsForInvoicePayment.get(0);
+        final BusinessInvoicePaymentTagModelDao invoicePaymentTag = tagsForInvoicePayment.get(0);
         Assert.assertEquals(invoicePaymentTag.getPaymentId().toString(), paymentId);
         Assert.assertEquals(invoicePaymentTag.getName(), name);
 
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java
index f273ed2..0bf6bf4 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java
@@ -27,7 +27,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.model.BusinessInvoiceModelDao;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
@@ -49,7 +49,7 @@ public class TestBusinessInvoiceSqlDao extends AnalyticsTestSuiteWithEmbeddedDB 
         final UUID invoiceId = UUID.randomUUID();
         final UUID accountId = UUID.randomUUID();
         final String accountKey = UUID.randomUUID().toString();
-        final BusinessInvoice invoice = createInvoice(accountId, invoiceId, accountKey);
+        final BusinessInvoiceModelDao invoice = createInvoice(accountId, invoiceId, accountKey);
 
         // Verify initial state
         Assert.assertNull(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString(), internalCallContext));
@@ -74,11 +74,11 @@ public class TestBusinessInvoiceSqlDao extends AnalyticsTestSuiteWithEmbeddedDB 
         final UUID invoiceId1 = UUID.randomUUID();
         final UUID accountId1 = UUID.randomUUID();
         final String accountKey1 = UUID.randomUUID().toString();
-        final BusinessInvoice invoice1 = createInvoice(invoiceId1, accountId1, accountKey1);
+        final BusinessInvoiceModelDao invoice1 = createInvoice(invoiceId1, accountId1, accountKey1);
         final UUID invoiceId2 = UUID.randomUUID();
         final UUID accountId2 = UUID.randomUUID();
         final String accountKey2 = UUID.randomUUID().toString();
-        final BusinessInvoice invoice2 = createInvoice(invoiceId2, accountId2, accountKey2);
+        final BusinessInvoiceModelDao invoice2 = createInvoice(invoiceId2, accountId2, accountKey2);
 
         // Create both invoices
         Assert.assertEquals(invoiceSqlDao.createInvoice(invoice1, internalCallContext), 1);
@@ -104,7 +104,7 @@ public class TestBusinessInvoiceSqlDao extends AnalyticsTestSuiteWithEmbeddedDB 
         }
     }
 
-    private BusinessInvoice createInvoice(final UUID invoiceId, final UUID accountId, final String accountKey) {
+    private BusinessInvoiceModelDao createInvoice(final UUID invoiceId, final UUID accountId, final String accountKey) {
         final BigDecimal amountCharged = BigDecimal.ZERO;
         final BigDecimal amountCredited = BigDecimal.ONE;
         final BigDecimal amountPaid = BigDecimal.TEN;
@@ -115,7 +115,7 @@ public class TestBusinessInvoiceSqlDao extends AnalyticsTestSuiteWithEmbeddedDB 
         final LocalDate targetDate = clock.getUTCToday();
         final DateTime updatedDate = clock.getUTCNow();
 
-        return new BusinessInvoice(accountId, accountKey, amountCharged, amountCredited, amountPaid, balance,
-                                   createdDate, currency, invoiceDate, invoiceId, 12, targetDate, updatedDate);
+        return new BusinessInvoiceModelDao(accountId, accountKey, amountCharged, amountCredited, amountPaid, balance,
+                                           createdDate, currency, invoiceDate, invoiceId, 12, targetDate, updatedDate);
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java
index 7f99aab..5d4cbc3 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java
@@ -25,9 +25,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessInvoiceTag;
+import com.ning.billing.analytics.model.BusinessInvoiceTagModelDao;
 
 public class TestBusinessInvoiceTagSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
+
     private BusinessInvoiceTagSqlDao invoiceTagSqlDao;
 
     @BeforeMethod(groups = "slow")
@@ -47,11 +48,11 @@ public class TestBusinessInvoiceTagSqlDao extends AnalyticsTestSuiteWithEmbedded
 
         // Add an entry
         Assert.assertEquals(invoiceTagSqlDao.addTag(invoiceId, name, internalCallContext), 1);
-        final List<BusinessInvoiceTag> tagsForInvoice = invoiceTagSqlDao.getTagsForInvoice(invoiceId, internalCallContext);
+        final List<BusinessInvoiceTagModelDao> tagsForInvoice = invoiceTagSqlDao.getTagsForInvoice(invoiceId, internalCallContext);
         Assert.assertEquals(tagsForInvoice.size(), 1);
 
         // Retrieve it
-        final BusinessInvoiceTag invoiceTag = tagsForInvoice.get(0);
+        final BusinessInvoiceTagModelDao invoiceTag = tagsForInvoice.get(0);
         Assert.assertEquals(invoiceTag.getInvoiceId().toString(), invoiceId);
         Assert.assertEquals(invoiceTag.getName(), name);
 
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java
index 9662857..d26a03c 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java
@@ -26,9 +26,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessOverdueStatus;
+import com.ning.billing.analytics.model.BusinessOverdueStatusModelDao;
 
 public class TestBusinessOverdueStatusSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
+
     private BusinessOverdueStatusSqlDao overdueStatusSqlDao;
 
     @BeforeMethod(groups = "slow")
@@ -42,7 +43,7 @@ public class TestBusinessOverdueStatusSqlDao extends AnalyticsTestSuiteWithEmbed
         final String accountKey = UUID.randomUUID().toString();
         final UUID bundleId = UUID.randomUUID();
         final String externalKey = UUID.randomUUID().toString();
-        final BusinessOverdueStatus firstOverdueStatus = createOverdueStatus(accountKey, bundleId, externalKey);
+        final BusinessOverdueStatusModelDao firstOverdueStatus = createOverdueStatus(accountKey, bundleId, externalKey);
 
         // Verify initial state
         Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContext).size(), 0);
@@ -55,7 +56,7 @@ public class TestBusinessOverdueStatusSqlDao extends AnalyticsTestSuiteWithEmbed
         Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundleByKey(externalKey, internalCallContext).get(0), firstOverdueStatus);
 
         // Add a second one
-        final BusinessOverdueStatus secondOverdueStatus = createOverdueStatus(accountKey, bundleId, externalKey);
+        final BusinessOverdueStatusModelDao secondOverdueStatus = createOverdueStatus(accountKey, bundleId, externalKey);
         Assert.assertEquals(overdueStatusSqlDao.createOverdueStatus(secondOverdueStatus, internalCallContext), 1);
 
         // Retrieve both
@@ -74,11 +75,11 @@ public class TestBusinessOverdueStatusSqlDao extends AnalyticsTestSuiteWithEmbed
         }
     }
 
-    private BusinessOverdueStatus createOverdueStatus(final String accountKey, final UUID bundleId, final String externalKey) {
+    private BusinessOverdueStatusModelDao createOverdueStatus(final String accountKey, final UUID bundleId, final String externalKey) {
         final DateTime endDate = new DateTime(DateTimeZone.UTC);
         final DateTime startDate = new DateTime(DateTimeZone.UTC);
         final String status = UUID.randomUUID().toString();
 
-        return new BusinessOverdueStatus(accountKey, bundleId, endDate, externalKey, startDate, status);
+        return new BusinessOverdueStatusModelDao(accountKey, bundleId, endDate, externalKey, startDate, status);
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java
index 77d4870..b24b162 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java
@@ -25,9 +25,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransitionField;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionFieldModelDao;
 
 public class TestBusinessSubscriptionTransitionFieldSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
+
     private BusinessSubscriptionTransitionFieldSqlDao subscriptionTransitionFieldSqlDao;
 
     @BeforeMethod(groups = "slow")
@@ -50,11 +51,11 @@ public class TestBusinessSubscriptionTransitionFieldSqlDao extends AnalyticsTest
 
         // Add an entry
         Assert.assertEquals(subscriptionTransitionFieldSqlDao.addField(accountKey, bundleId.toString(), externalKey, name, value, internalCallContext), 1);
-        final List<BusinessSubscriptionTransitionField> fieldsForBusinessSubscriptionTransition = subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext);
+        final List<BusinessSubscriptionTransitionFieldModelDao> fieldsForBusinessSubscriptionTransition = subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext);
         Assert.assertEquals(fieldsForBusinessSubscriptionTransition.size(), 1);
 
         // Retrieve it
-        final BusinessSubscriptionTransitionField subscriptionTransitionField = fieldsForBusinessSubscriptionTransition.get(0);
+        final BusinessSubscriptionTransitionFieldModelDao subscriptionTransitionField = fieldsForBusinessSubscriptionTransition.get(0);
         Assert.assertEquals(subscriptionTransitionField.getBundleId(), bundleId);
         Assert.assertEquals(subscriptionTransitionField.getExternalKey(), externalKey);
         Assert.assertEquals(subscriptionTransitionField.getName(), name);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java
index 8b1f081..d70e7ec 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java
@@ -25,9 +25,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.AnalyticsTestSuiteWithEmbeddedDB;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransitionTag;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionTagModelDao;
 
 public class TestBusinessSubscriptionTransitionTagSqlDao extends AnalyticsTestSuiteWithEmbeddedDB {
+
     private BusinessSubscriptionTransitionTagSqlDao subscriptionTransitionTagSqlDao;
 
     @BeforeMethod(groups = "slow")
@@ -49,11 +50,11 @@ public class TestBusinessSubscriptionTransitionTagSqlDao extends AnalyticsTestSu
 
         // Add an entry
         Assert.assertEquals(subscriptionTransitionTagSqlDao.addTag(accountKey, bundleId.toString(), externalKey, name, internalCallContext), 1);
-        final List<BusinessSubscriptionTransitionTag> tagsForBusinessSubscriptionTransition = subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext);
+        final List<BusinessSubscriptionTransitionTagModelDao> tagsForBusinessSubscriptionTransition = subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransitionByKey(externalKey, internalCallContext);
         Assert.assertEquals(tagsForBusinessSubscriptionTransition.size(), 1);
 
         // Retrieve it
-        final BusinessSubscriptionTransitionTag subscriptionTransitionTag = tagsForBusinessSubscriptionTransition.get(0);
+        final BusinessSubscriptionTransitionTagModelDao subscriptionTransitionTag = tagsForBusinessSubscriptionTransition.get(0);
         Assert.assertEquals(subscriptionTransitionTag.getBundleId(), bundleId);
         Assert.assertEquals(subscriptionTransitionTag.getExternalKey(), externalKey);
         Assert.assertEquals(subscriptionTransitionTag.getName(), name);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionSqlDao.java
index c677d82..babc5d9 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionSqlDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockBusinessSubscriptionTransitionSqlDao.java
@@ -29,7 +29,7 @@ import org.testng.Assert;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionBinder;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
 import com.ning.billing.analytics.dao.TimeSeriesTuple;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.InternalTenantContextBinder;
@@ -38,7 +38,7 @@ import com.google.common.collect.ImmutableList;
 
 public class MockBusinessSubscriptionTransitionSqlDao implements BusinessSubscriptionTransitionSqlDao {
 
-    private final Map<String, List<BusinessSubscriptionTransition>> content = new HashMap<String, List<BusinessSubscriptionTransition>>();
+    private final Map<String, List<BusinessSubscriptionTransitionModelDao>> content = new HashMap<String, List<BusinessSubscriptionTransitionModelDao>>();
     private final Map<String, String> keyForBundleId = new HashMap<String, String>();
 
     @Override
@@ -49,27 +49,27 @@ public class MockBusinessSubscriptionTransitionSqlDao implements BusinessSubscri
     }
 
     @Override
-    public List<BusinessSubscriptionTransition> getTransitionsByKey(@Bind("event_key") final String key,
-                                                                    @InternalTenantContextBinder final InternalTenantContext context) {
+    public List<BusinessSubscriptionTransitionModelDao> getTransitionsByKey(@Bind("event_key") final String key,
+                                                                            @InternalTenantContextBinder final InternalTenantContext context) {
         return content.get(key);
     }
 
     @Override
-    public List<BusinessSubscriptionTransition> getTransitionForSubscription(@Bind("subscription_id") final String subscriptionId,
-                                                                             @InternalTenantContextBinder final InternalTenantContext context) {
-        return ImmutableList.<BusinessSubscriptionTransition>of();
+    public List<BusinessSubscriptionTransitionModelDao> getTransitionForSubscription(@Bind("subscription_id") final String subscriptionId,
+                                                                                     @InternalTenantContextBinder final InternalTenantContext context) {
+        return ImmutableList.<BusinessSubscriptionTransitionModelDao>of();
     }
 
     @Override
-    public List<BusinessSubscriptionTransition> getTransitionsForAccount(@Bind("account_id") final String accountId, @InternalTenantContextBinder final InternalTenantContext context) {
-        return ImmutableList.<BusinessSubscriptionTransition>of();
+    public List<BusinessSubscriptionTransitionModelDao> getTransitionsForAccount(@Bind("account_id") final String accountId, @InternalTenantContextBinder final InternalTenantContext context) {
+        return ImmutableList.<BusinessSubscriptionTransitionModelDao>of();
     }
 
     @Override
-    public int createTransition(@BusinessSubscriptionTransitionBinder final BusinessSubscriptionTransition transition,
+    public int createTransition(@BusinessSubscriptionTransitionBinder final BusinessSubscriptionTransitionModelDao transition,
                                 @InternalTenantContextBinder final InternalCallContext context) {
         if (content.get(transition.getExternalKey()) == null) {
-            content.put(transition.getExternalKey(), new ArrayList<BusinessSubscriptionTransition>());
+            content.put(transition.getExternalKey(), new ArrayList<BusinessSubscriptionTransitionModelDao>());
         }
         content.get(transition.getExternalKey()).add(transition);
         keyForBundleId.put(transition.getBundleId().toString(), transition.getExternalKey());
@@ -79,7 +79,7 @@ public class MockBusinessSubscriptionTransitionSqlDao implements BusinessSubscri
     @Override
     public void deleteTransitionsForBundle(@Bind("bundle_id") final String bundleId,
                                            @InternalTenantContextBinder final InternalCallContext context) {
-        content.put(keyForBundleId.get(bundleId), new ArrayList<BusinessSubscriptionTransition>());
+        content.put(keyForBundleId.get(bundleId), new ArrayList<BusinessSubscriptionTransitionModelDao>());
     }
 
     @Override
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockPhase.java b/analytics/src/test/java/com/ning/billing/analytics/MockPhase.java
index c3779df..4fb496e 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockPhase.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockPhase.java
@@ -28,6 +28,7 @@ import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.Price;
 
 public class MockPhase implements PlanPhase {
+
     private final PhaseType cohort;
     private final Plan plan;
     private final Duration duration;
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockProduct.java b/analytics/src/test/java/com/ning/billing/analytics/MockProduct.java
index 624768e..95b8616 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockProduct.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockProduct.java
@@ -20,6 +20,7 @@ import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
 
 public class MockProduct implements Product {
+
     private final String name;
     private final String type;
     private final ProductCategory category;
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccount.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccount.java
index dfd5b5d..a86a3c2 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccount.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccount.java
@@ -33,13 +33,13 @@ public class TestBusinessAccount extends AnalyticsTestSuite {
 
     private final Clock clock = new DefaultClock();
 
-    private BusinessAccount account;
+    private BusinessAccountModelDao account;
 
     @BeforeMethod(groups = "fast")
     public void setUp() throws Exception {
-        account = new BusinessAccount(UUID.randomUUID(), "pierre", UUID.randomUUID().toString(), BigDecimal.ONE, clock.getUTCToday(),
-                                      BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "", UUID.randomUUID().toString(),
-                                      clock.getUTCNow(), clock.getUTCNow());
+        account = new BusinessAccountModelDao(UUID.randomUUID(), "pierre", UUID.randomUUID().toString(), BigDecimal.ONE, clock.getUTCToday(),
+                                              BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "", UUID.randomUUID().toString(),
+                                              clock.getUTCNow(), clock.getUTCNow());
     }
 
     @Test(groups = "fast")
@@ -48,17 +48,17 @@ public class TestBusinessAccount extends AnalyticsTestSuite {
         Assert.assertEquals(account, account);
         Assert.assertTrue(account.equals(account));
 
-        final BusinessAccount otherAccount = new BusinessAccount(UUID.randomUUID(), "pierre cardin", UUID.randomUUID().toString(),
-                                                                 BigDecimal.ONE, clock.getUTCToday(),
-                                                                 BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa",
-                                                                 "", UUID.randomUUID().toString(), clock.getUTCNow(), clock.getUTCNow());
+        final BusinessAccountModelDao otherAccount = new BusinessAccountModelDao(UUID.randomUUID(), "pierre cardin", UUID.randomUUID().toString(),
+                                                                                 BigDecimal.ONE, clock.getUTCToday(),
+                                                                                 BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa",
+                                                                                 "", UUID.randomUUID().toString(), clock.getUTCNow(), clock.getUTCNow());
         Assert.assertFalse(account.equals(otherAccount));
     }
 
     @Test(groups = "fast")
     public void testDefaultBigDecimalValues() throws Exception {
         final Account account = Mockito.mock(Account.class);
-        final BusinessAccount bac = new BusinessAccount(account);
+        final BusinessAccountModelDao bac = new BusinessAccountModelDao(account);
         Assert.assertEquals(bac.getBalance(), BigDecimal.ZERO);
         Assert.assertEquals(bac.getTotalInvoiceBalance(), BigDecimal.ZERO);
 
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountField.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountField.java
index 86ce86c..ea104f8 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountField.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountField.java
@@ -24,16 +24,17 @@ import org.testng.annotations.Test;
 import com.ning.billing.analytics.AnalyticsTestSuite;
 
 public class TestBusinessAccountField extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testEquals() throws Exception {
         final UUID accountId = UUID.randomUUID();
         final String accountKey = UUID.randomUUID().toString();
         final String name = UUID.randomUUID().toString();
         final String value = UUID.randomUUID().toString();
-        final BusinessAccountField accountField = new BusinessAccountField(accountId,
-                                                                           accountKey,
-                                                                           name,
-                                                                           value);
+        final BusinessAccountFieldModelDao accountField = new BusinessAccountFieldModelDao(accountId,
+                                                                                           accountKey,
+                                                                                           name,
+                                                                                           value);
         Assert.assertSame(accountField, accountField);
         Assert.assertEquals(accountField, accountField);
         Assert.assertTrue(accountField.equals(accountField));
@@ -42,10 +43,10 @@ public class TestBusinessAccountField extends AnalyticsTestSuite {
         Assert.assertEquals(accountField.getName(), name);
         Assert.assertEquals(accountField.getValue(), value);
 
-        final BusinessAccountField otherAccountField = new BusinessAccountField(UUID.randomUUID(),
-                                                                                UUID.randomUUID().toString(),
-                                                                                UUID.randomUUID().toString(),
-                                                                                UUID.randomUUID().toString());
+        final BusinessAccountFieldModelDao otherAccountField = new BusinessAccountFieldModelDao(UUID.randomUUID(),
+                                                                                                UUID.randomUUID().toString(),
+                                                                                                UUID.randomUUID().toString(),
+                                                                                                UUID.randomUUID().toString());
         Assert.assertFalse(accountField.equals(otherAccountField));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountTag.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountTag.java
index 4d0014e..bbaeed3 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountTag.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountTag.java
@@ -24,12 +24,13 @@ import org.testng.annotations.Test;
 import com.ning.billing.analytics.AnalyticsTestSuite;
 
 public class TestBusinessAccountTag extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testEquals() throws Exception {
         final UUID accountId = UUID.randomUUID();
         final String accountKey = UUID.randomUUID().toString();
         final String name = UUID.randomUUID().toString();
-        final BusinessAccountTag accountTag = new BusinessAccountTag(accountId, accountKey, name);
+        final BusinessAccountTagModelDao accountTag = new BusinessAccountTagModelDao(accountId, accountKey, name);
         Assert.assertSame(accountTag, accountTag);
         Assert.assertEquals(accountTag, accountTag);
         Assert.assertTrue(accountTag.equals(accountTag));
@@ -37,7 +38,7 @@ public class TestBusinessAccountTag extends AnalyticsTestSuite {
         Assert.assertEquals(accountTag.getAccountKey(), accountKey);
         Assert.assertEquals(accountTag.getName(), name);
 
-        final BusinessAccountTag otherAccountTag = new BusinessAccountTag(UUID.randomUUID(), UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        final BusinessAccountTagModelDao otherAccountTag = new BusinessAccountTagModelDao(UUID.randomUUID(), UUID.randomUUID().toString(), UUID.randomUUID().toString());
         Assert.assertFalse(accountTag.equals(otherAccountTag));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoice.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoice.java
index d866eda..3b22900 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoice.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoice.java
@@ -48,8 +48,8 @@ public class TestBusinessInvoice extends AnalyticsTestSuite {
         final Integer invoiceNumber = 15;
         final LocalDate targetDate = clock.getUTCToday();
         final DateTime updatedDate = clock.getUTCNow();
-        final BusinessInvoice invoice = new BusinessInvoice(accountId, accountKey, amountCharged, amountCredited, amountPaid, balance,
-                                                            createdDate, currency, invoiceDate, invoiceId, invoiceNumber, targetDate, updatedDate);
+        final BusinessInvoiceModelDao invoice = new BusinessInvoiceModelDao(accountId, accountKey, amountCharged, amountCredited, amountPaid, balance,
+                                                                            createdDate, currency, invoiceDate, invoiceId, invoiceNumber, targetDate, updatedDate);
         Assert.assertSame(invoice, invoice);
         Assert.assertEquals(invoice, invoice);
         Assert.assertTrue(invoice.equals(invoice));
@@ -67,8 +67,8 @@ public class TestBusinessInvoice extends AnalyticsTestSuite {
         Assert.assertEquals(invoice.getTargetDate(), targetDate);
         Assert.assertEquals(invoice.getUpdatedDate(), updatedDate);
 
-        final BusinessInvoice otherInvoice = new BusinessInvoice(null, null, null, null, null, null, createdDate, null,
-                                                                 null, invoiceId, 0, null, null);
+        final BusinessInvoiceModelDao otherInvoice = new BusinessInvoiceModelDao(null, null, null, null, null, null, createdDate, null,
+                                                                                 null, invoiceId, 0, null, null);
         Assert.assertFalse(invoice.equals(otherInvoice));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceField.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceField.java
index b2c0937..66a26be 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceField.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceField.java
@@ -24,14 +24,15 @@ import org.testng.annotations.Test;
 import com.ning.billing.analytics.AnalyticsTestSuite;
 
 public class TestBusinessInvoiceField extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testEquals() throws Exception {
         final UUID invoiceId = UUID.randomUUID();
         final String name = UUID.randomUUID().toString();
         final String value = UUID.randomUUID().toString();
-        final BusinessInvoiceField invoiceField = new BusinessInvoiceField(invoiceId,
-                                                                           name,
-                                                                           value);
+        final BusinessInvoiceFieldModelDao invoiceField = new BusinessInvoiceFieldModelDao(invoiceId,
+                                                                                           name,
+                                                                                           value);
         Assert.assertSame(invoiceField, invoiceField);
         Assert.assertEquals(invoiceField, invoiceField);
         Assert.assertTrue(invoiceField.equals(invoiceField));
@@ -39,9 +40,9 @@ public class TestBusinessInvoiceField extends AnalyticsTestSuite {
         Assert.assertEquals(invoiceField.getName(), name);
         Assert.assertEquals(invoiceField.getValue(), value);
 
-        final BusinessInvoiceField otherInvoiceField = new BusinessInvoiceField(UUID.randomUUID(),
-                                                                                UUID.randomUUID().toString(),
-                                                                                UUID.randomUUID().toString());
+        final BusinessInvoiceFieldModelDao otherInvoiceField = new BusinessInvoiceFieldModelDao(UUID.randomUUID(),
+                                                                                                UUID.randomUUID().toString(),
+                                                                                                UUID.randomUUID().toString());
         Assert.assertFalse(invoiceField.equals(otherInvoiceField));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceItem.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceItem.java
index 4e43290..1b1c84c 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceItem.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceItem.java
@@ -52,10 +52,10 @@ public class TestBusinessInvoiceItem extends AnalyticsTestSuite {
         final String slug = UUID.randomUUID().toString();
         final LocalDate startDate = clock.getUTCToday();
         final DateTime updatedDate = clock.getUTCNow();
-        final BusinessInvoiceItem invoiceItem = new BusinessInvoiceItem(amount, billingPeriod, createdDate, currency,
-                                                                        endDate, externalKey, invoiceId, itemId, linkedItemId,
-                                                                        itemType, phase, productCategory, productName, productType,
-                                                                        slug, startDate, updatedDate);
+        final BusinessInvoiceItemModelDao invoiceItem = new BusinessInvoiceItemModelDao(amount, billingPeriod, createdDate, currency,
+                                                                                        endDate, externalKey, invoiceId, itemId, linkedItemId,
+                                                                                        itemType, phase, productCategory, productName, productType,
+                                                                                        slug, startDate, updatedDate);
         Assert.assertSame(invoiceItem, invoiceItem);
         Assert.assertEquals(invoiceItem, invoiceItem);
         Assert.assertTrue(invoiceItem.equals(invoiceItem));
@@ -77,8 +77,8 @@ public class TestBusinessInvoiceItem extends AnalyticsTestSuite {
         Assert.assertEquals(invoiceItem.getStartDate(), startDate);
         Assert.assertEquals(invoiceItem.getUpdatedDate(), updatedDate);
 
-        final BusinessInvoiceItem otherInvoiceItem = new BusinessInvoiceItem(null, null, createdDate, null, null, null, null, itemId,
-                                                                             linkedItemId, null, null, null, null, null, null, null, null);
+        final BusinessInvoiceItemModelDao otherInvoiceItem = new BusinessInvoiceItemModelDao(null, null, createdDate, null, null, null, null, itemId,
+                                                                                             linkedItemId, null, null, null, null, null, null, null, null);
         Assert.assertFalse(invoiceItem.equals(otherInvoiceItem));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePayment.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePayment.java
index 97c3028..b4c29ca 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePayment.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePayment.java
@@ -28,6 +28,7 @@ import com.ning.billing.analytics.AnalyticsTestSuite;
 import com.ning.billing.catalog.api.Currency;
 
 public class TestBusinessInvoicePayment extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testEquals() throws Exception {
         final String accountKey = UUID.randomUUID().toString();
@@ -50,13 +51,13 @@ public class TestBusinessInvoicePayment extends AnalyticsTestSuite {
         final DateTime updatedDate = new DateTime(DateTimeZone.UTC);
         final String invoicePaymentType = UUID.randomUUID().toString();
         final UUID linkedInvoicePaymentId = UUID.randomUUID();
-        final BusinessInvoicePayment invoicePayment = new BusinessInvoicePayment(accountKey, amount, extFirstPaymentRefId, extSecondPaymentRefId,
-                                                                                 cardCountry, cardType, createdDate,
-                                                                                 currency, effectiveDate, invoiceId,
-                                                                                 paymentError, paymentId, paymentMethod,
-                                                                                 paymentType, pluginName, processingStatus,
-                                                                                 requestedAmount, updatedDate, invoicePaymentType,
-                                                                                 linkedInvoicePaymentId);
+        final BusinessInvoicePaymentModelDao invoicePayment = new BusinessInvoicePaymentModelDao(accountKey, amount, extFirstPaymentRefId, extSecondPaymentRefId,
+                                                                                                 cardCountry, cardType, createdDate,
+                                                                                                 currency, effectiveDate, invoiceId,
+                                                                                                 paymentError, paymentId, paymentMethod,
+                                                                                                 paymentType, pluginName, processingStatus,
+                                                                                                 requestedAmount, updatedDate, invoicePaymentType,
+                                                                                                 linkedInvoicePaymentId);
         Assert.assertSame(invoicePayment, invoicePayment);
         Assert.assertEquals(invoicePayment, invoicePayment);
         Assert.assertTrue(invoicePayment.equals(invoicePayment));
@@ -81,9 +82,9 @@ public class TestBusinessInvoicePayment extends AnalyticsTestSuite {
         Assert.assertEquals(invoicePayment.getInvoicePaymentType(), invoicePaymentType);
         Assert.assertEquals(invoicePayment.getLinkedInvoicePaymentId(), linkedInvoicePaymentId);
 
-        final BusinessInvoicePayment otherInvoicePayment = new BusinessInvoicePayment(null, null, extFirstPaymentRefId, extSecondPaymentRefId, null, null, createdDate,
-                                                                                      null, null, null, null, paymentId, null,
-                                                                                      null, null, null, null, null, null, null);
+        final BusinessInvoicePaymentModelDao otherInvoicePayment = new BusinessInvoicePaymentModelDao(null, null, extFirstPaymentRefId, extSecondPaymentRefId, null, null, createdDate,
+                                                                                                      null, null, null, null, paymentId, null,
+                                                                                                      null, null, null, null, null, null, null);
         Assert.assertFalse(invoicePayment.equals(otherInvoicePayment));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentField.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentField.java
index 2d73c48..0ace55c 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentField.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentField.java
@@ -24,14 +24,15 @@ import org.testng.annotations.Test;
 import com.ning.billing.analytics.AnalyticsTestSuite;
 
 public class TestBusinessInvoicePaymentField extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testEquals() throws Exception {
         final UUID paymentId = UUID.randomUUID();
         final String name = UUID.randomUUID().toString();
         final String value = UUID.randomUUID().toString();
-        final BusinessInvoicePaymentField invoiceField = new BusinessInvoicePaymentField(paymentId,
-                                                                                         name,
-                                                                                         value);
+        final BusinessInvoicePaymentFieldModelDao invoiceField = new BusinessInvoicePaymentFieldModelDao(paymentId,
+                                                                                                         name,
+                                                                                                         value);
         Assert.assertSame(invoiceField, invoiceField);
         Assert.assertEquals(invoiceField, invoiceField);
         Assert.assertTrue(invoiceField.equals(invoiceField));
@@ -39,9 +40,9 @@ public class TestBusinessInvoicePaymentField extends AnalyticsTestSuite {
         Assert.assertEquals(invoiceField.getName(), name);
         Assert.assertEquals(invoiceField.getValue(), value);
 
-        final BusinessInvoicePaymentField otherInvoicePaymentField = new BusinessInvoicePaymentField(UUID.randomUUID(),
-                                                                                                     UUID.randomUUID().toString(),
-                                                                                                     UUID.randomUUID().toString());
+        final BusinessInvoicePaymentFieldModelDao otherInvoicePaymentField = new BusinessInvoicePaymentFieldModelDao(UUID.randomUUID(),
+                                                                                                                     UUID.randomUUID().toString(),
+                                                                                                                     UUID.randomUUID().toString());
         Assert.assertFalse(invoiceField.equals(otherInvoicePaymentField));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentTag.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentTag.java
index b5ae515..1bd23e2 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentTag.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentTag.java
@@ -24,19 +24,20 @@ import org.testng.annotations.Test;
 import com.ning.billing.analytics.AnalyticsTestSuite;
 
 public class TestBusinessInvoicePaymentTag extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testEquals() throws Exception {
         final UUID paymentId = UUID.randomUUID();
         final String name = UUID.randomUUID().toString();
-        final BusinessInvoicePaymentTag invoicePaymentTag = new BusinessInvoicePaymentTag(paymentId, name);
+        final BusinessInvoicePaymentTagModelDao invoicePaymentTag = new BusinessInvoicePaymentTagModelDao(paymentId, name);
         Assert.assertSame(invoicePaymentTag, invoicePaymentTag);
         Assert.assertEquals(invoicePaymentTag, invoicePaymentTag);
         Assert.assertTrue(invoicePaymentTag.equals(invoicePaymentTag));
         Assert.assertEquals(invoicePaymentTag.getPaymentId(), paymentId);
         Assert.assertEquals(invoicePaymentTag.getName(), name);
 
-        final BusinessInvoicePaymentTag otherInvoicePaymentTag = new BusinessInvoicePaymentTag(UUID.randomUUID(),
-                                                                                               UUID.randomUUID().toString());
+        final BusinessInvoicePaymentTagModelDao otherInvoicePaymentTag = new BusinessInvoicePaymentTagModelDao(UUID.randomUUID(),
+                                                                                                               UUID.randomUUID().toString());
         Assert.assertFalse(invoicePaymentTag.equals(otherInvoicePaymentTag));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceTag.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceTag.java
index 3e92eae..9211226 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceTag.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceTag.java
@@ -24,18 +24,19 @@ import org.testng.annotations.Test;
 import com.ning.billing.analytics.AnalyticsTestSuite;
 
 public class TestBusinessInvoiceTag extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testEquals() throws Exception {
         final UUID invoiceId = UUID.randomUUID();
         final String name = UUID.randomUUID().toString();
-        final BusinessInvoiceTag invoiceTag = new BusinessInvoiceTag(invoiceId, name);
+        final BusinessInvoiceTagModelDao invoiceTag = new BusinessInvoiceTagModelDao(invoiceId, name);
         Assert.assertSame(invoiceTag, invoiceTag);
         Assert.assertEquals(invoiceTag, invoiceTag);
         Assert.assertTrue(invoiceTag.equals(invoiceTag));
         Assert.assertEquals(invoiceTag.getInvoiceId(), invoiceId);
         Assert.assertEquals(invoiceTag.getName(), name);
 
-        final BusinessInvoiceTag otherInvoiceTag = new BusinessInvoiceTag(UUID.randomUUID(), UUID.randomUUID().toString());
+        final BusinessInvoiceTagModelDao otherInvoiceTag = new BusinessInvoiceTagModelDao(UUID.randomUUID(), UUID.randomUUID().toString());
         Assert.assertFalse(invoiceTag.equals(otherInvoiceTag));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessOverdueStatus.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessOverdueStatus.java
index be467e9..9d77303 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessOverdueStatus.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessOverdueStatus.java
@@ -26,6 +26,7 @@ import org.testng.annotations.Test;
 import com.ning.billing.analytics.AnalyticsTestSuite;
 
 public class TestBusinessOverdueStatus extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testEquals() throws Exception {
         final String accountKey = UUID.randomUUID().toString();
@@ -34,7 +35,7 @@ public class TestBusinessOverdueStatus extends AnalyticsTestSuite {
         final String externalKey = UUID.randomUUID().toString();
         final DateTime startDate = new DateTime(DateTimeZone.UTC);
         final String status = UUID.randomUUID().toString();
-        final BusinessOverdueStatus overdueStatus = new BusinessOverdueStatus(accountKey, bundleId, endDate, externalKey, startDate, status);
+        final BusinessOverdueStatusModelDao overdueStatus = new BusinessOverdueStatusModelDao(accountKey, bundleId, endDate, externalKey, startDate, status);
         Assert.assertSame(overdueStatus, overdueStatus);
         Assert.assertEquals(overdueStatus, overdueStatus);
         Assert.assertTrue(overdueStatus.equals(overdueStatus));
@@ -45,12 +46,12 @@ public class TestBusinessOverdueStatus extends AnalyticsTestSuite {
         Assert.assertEquals(overdueStatus.getStartDate(), startDate);
         Assert.assertEquals(overdueStatus.getStatus(), status);
 
-        final BusinessOverdueStatus otherOverdueStatus = new BusinessOverdueStatus(UUID.randomUUID().toString(),
-                                                                                   UUID.randomUUID(),
-                                                                                   new DateTime(DateTimeZone.UTC),
-                                                                                   UUID.randomUUID().toString(),
-                                                                                   new DateTime(DateTimeZone.UTC),
-                                                                                   UUID.randomUUID().toString());
+        final BusinessOverdueStatusModelDao otherOverdueStatus = new BusinessOverdueStatusModelDao(UUID.randomUUID().toString(),
+                                                                                                   UUID.randomUUID(),
+                                                                                                   new DateTime(DateTimeZone.UTC),
+                                                                                                   UUID.randomUUID().toString(),
+                                                                                                   new DateTime(DateTimeZone.UTC),
+                                                                                                   UUID.randomUUID().toString());
         Assert.assertFalse(overdueStatus.equals(otherOverdueStatus));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionEvent.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionEvent.java
index de713a8..24b65ed 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionEvent.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionEvent.java
@@ -38,6 +38,7 @@ import com.ning.billing.mock.MockPlan;
 import com.ning.billing.mock.MockSubscription;
 
 public class TestBusinessSubscriptionEvent extends AnalyticsTestSuite {
+
     private Product product;
     private Plan plan;
     private PlanPhase phase;
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransition.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransition.java
index 3e237bc..fc362f5 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransition.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransition.java
@@ -43,6 +43,7 @@ import com.ning.billing.mock.MockSubscription;
 import static com.ning.billing.catalog.api.Currency.USD;
 
 public class TestBusinessSubscriptionTransition extends AnalyticsTestSuite {
+
     private BusinessSubscription prevSubscription;
     private BusinessSubscription nextSubscription;
     private BusinessSubscriptionEvent event;
@@ -53,7 +54,7 @@ public class TestBusinessSubscriptionTransition extends AnalyticsTestSuite {
     private UUID accountId;
     private String accountKey;
     private UUID subscriptionId;
-    private BusinessSubscriptionTransition transition;
+    private BusinessSubscriptionTransitionModelDao transition;
 
     private final CatalogService catalogService = Mockito.mock(CatalogService.class);
     private final Catalog catalog = Mockito.mock(Catalog.class);
@@ -82,8 +83,8 @@ public class TestBusinessSubscriptionTransition extends AnalyticsTestSuite {
         accountId = UUID.randomUUID();
         accountKey = "pierre-1234";
         subscriptionId = UUID.randomUUID();
-        transition = new BusinessSubscriptionTransition(totalOrdering, bundleId, externalKey, accountId, accountKey,
-                                                        subscriptionId, requestedTimestamp, event, prevSubscription, nextSubscription);
+        transition = new BusinessSubscriptionTransitionModelDao(totalOrdering, bundleId, externalKey, accountId, accountKey,
+                                                                subscriptionId, requestedTimestamp, event, prevSubscription, nextSubscription);
     }
 
     @Test(groups = "fast")
@@ -100,58 +101,58 @@ public class TestBusinessSubscriptionTransition extends AnalyticsTestSuite {
         Assert.assertEquals(transition, transition);
         Assert.assertTrue(transition.equals(transition));
 
-        BusinessSubscriptionTransition otherTransition;
+        BusinessSubscriptionTransitionModelDao otherTransition;
 
-        otherTransition = new BusinessSubscriptionTransition(totalOrdering, bundleId, externalKey, accountId, accountKey,
-                                                             subscriptionId, new DateTime(), event, prevSubscription, nextSubscription);
+        otherTransition = new BusinessSubscriptionTransitionModelDao(totalOrdering, bundleId, externalKey, accountId, accountKey,
+                                                                     subscriptionId, new DateTime(), event, prevSubscription, nextSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(totalOrdering, bundleId, "12345", accountId, accountKey,
-                                                             subscriptionId, requestedTimestamp, event, prevSubscription, nextSubscription);
+        otherTransition = new BusinessSubscriptionTransitionModelDao(totalOrdering, bundleId, "12345", accountId, accountKey,
+                                                                     subscriptionId, requestedTimestamp, event, prevSubscription, nextSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(totalOrdering, bundleId, externalKey, accountId, accountKey,
-                                                             subscriptionId, requestedTimestamp, event, prevSubscription, prevSubscription);
+        otherTransition = new BusinessSubscriptionTransitionModelDao(totalOrdering, bundleId, externalKey, accountId, accountKey,
+                                                                     subscriptionId, requestedTimestamp, event, prevSubscription, prevSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(totalOrdering, bundleId, externalKey, accountId, accountKey,
-                                                             subscriptionId, requestedTimestamp, event, nextSubscription, nextSubscription);
+        otherTransition = new BusinessSubscriptionTransitionModelDao(totalOrdering, bundleId, externalKey, accountId, accountKey,
+                                                                     subscriptionId, requestedTimestamp, event, nextSubscription, nextSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
 
-        otherTransition = new BusinessSubscriptionTransition(totalOrdering, bundleId, externalKey, accountId, accountKey,
-                                                             subscriptionId, requestedTimestamp, event, nextSubscription, prevSubscription);
+        otherTransition = new BusinessSubscriptionTransitionModelDao(totalOrdering, bundleId, externalKey, accountId, accountKey,
+                                                                     subscriptionId, requestedTimestamp, event, nextSubscription, prevSubscription);
         Assert.assertTrue(!transition.equals(otherTransition));
     }
 
     @Test(groups = "fast")
     public void testRejectInvalidTransitions() throws Exception {
         try {
-            new BusinessSubscriptionTransition(null, bundleId, externalKey, accountId, accountKey,
-                                               subscriptionId, requestedTimestamp, event, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransitionModelDao(null, bundleId, externalKey, accountId, accountKey,
+                                                       subscriptionId, requestedTimestamp, event, prevSubscription, nextSubscription);
             Assert.fail();
         } catch (IllegalArgumentException e) {
             Assert.assertTrue(true);
         }
 
         try {
-            new BusinessSubscriptionTransition(totalOrdering, bundleId, null, accountId, accountKey,
-                                               subscriptionId, requestedTimestamp, event, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransitionModelDao(totalOrdering, bundleId, null, accountId, accountKey,
+                                                       subscriptionId, requestedTimestamp, event, prevSubscription, nextSubscription);
             Assert.fail();
         } catch (IllegalArgumentException e) {
             Assert.assertTrue(true);
         }
 
         try {
-            new BusinessSubscriptionTransition(totalOrdering, bundleId, externalKey, accountId, accountKey,
-                                               subscriptionId, null, event, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransitionModelDao(totalOrdering, bundleId, externalKey, accountId, accountKey,
+                                                       subscriptionId, null, event, prevSubscription, nextSubscription);
             Assert.fail();
         } catch (IllegalArgumentException e) {
             Assert.assertTrue(true);
         }
 
         try {
-            new BusinessSubscriptionTransition(totalOrdering, bundleId, externalKey, accountId, accountKey,
-                                               subscriptionId, requestedTimestamp, null, prevSubscription, nextSubscription);
+            new BusinessSubscriptionTransitionModelDao(totalOrdering, bundleId, externalKey, accountId, accountKey,
+                                                       subscriptionId, requestedTimestamp, null, prevSubscription, nextSubscription);
             Assert.fail();
         } catch (IllegalArgumentException e) {
             Assert.assertTrue(true);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionField.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionField.java
index 18a46f3..022190c 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionField.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionField.java
@@ -24,6 +24,7 @@ import org.testng.annotations.Test;
 import com.ning.billing.analytics.AnalyticsTestSuite;
 
 public class TestBusinessSubscriptionTransitionField extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testEquals() throws Exception {
         final String accountKey = UUID.randomUUID().toString();
@@ -31,11 +32,11 @@ public class TestBusinessSubscriptionTransitionField extends AnalyticsTestSuite 
         final String externalKey = UUID.randomUUID().toString();
         final String name = UUID.randomUUID().toString();
         final String value = UUID.randomUUID().toString();
-        final BusinessSubscriptionTransitionField subscriptionTransitionField = new BusinessSubscriptionTransitionField(accountKey,
-                                                                                                                        bundleId,
-                                                                                                                        externalKey,
-                                                                                                                        name,
-                                                                                                                        value);
+        final BusinessSubscriptionTransitionFieldModelDao subscriptionTransitionField = new BusinessSubscriptionTransitionFieldModelDao(accountKey,
+                                                                                                                                        bundleId,
+                                                                                                                                        externalKey,
+                                                                                                                                        name,
+                                                                                                                                        value);
         Assert.assertSame(subscriptionTransitionField, subscriptionTransitionField);
         Assert.assertEquals(subscriptionTransitionField, subscriptionTransitionField);
         Assert.assertTrue(subscriptionTransitionField.equals(subscriptionTransitionField));
@@ -45,11 +46,11 @@ public class TestBusinessSubscriptionTransitionField extends AnalyticsTestSuite 
         Assert.assertEquals(subscriptionTransitionField.getName(), name);
         Assert.assertEquals(subscriptionTransitionField.getValue(), value);
 
-        final BusinessSubscriptionTransitionField otherSubscriptionField = new BusinessSubscriptionTransitionField(UUID.randomUUID().toString(),
-                                                                                                                   UUID.randomUUID(),
-                                                                                                                   UUID.randomUUID().toString(),
-                                                                                                                   UUID.randomUUID().toString(),
-                                                                                                                   UUID.randomUUID().toString());
+        final BusinessSubscriptionTransitionFieldModelDao otherSubscriptionField = new BusinessSubscriptionTransitionFieldModelDao(UUID.randomUUID().toString(),
+                                                                                                                                   UUID.randomUUID(),
+                                                                                                                                   UUID.randomUUID().toString(),
+                                                                                                                                   UUID.randomUUID().toString(),
+                                                                                                                                   UUID.randomUUID().toString());
         Assert.assertFalse(subscriptionTransitionField.equals(otherSubscriptionField));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionTag.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionTag.java
index 66c2da8..70972a9 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionTag.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionTag.java
@@ -24,16 +24,17 @@ import org.testng.annotations.Test;
 import com.ning.billing.analytics.AnalyticsTestSuite;
 
 public class TestBusinessSubscriptionTransitionTag extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testEquals() throws Exception {
         final String accountKey = UUID.randomUUID().toString();
         final UUID bundleId = UUID.randomUUID();
         final String externalKey = UUID.randomUUID().toString();
         final String name = UUID.randomUUID().toString();
-        final BusinessSubscriptionTransitionTag subscriptionTransitionTag = new BusinessSubscriptionTransitionTag(accountKey,
-                                                                                                                  bundleId,
-                                                                                                                  externalKey,
-                                                                                                                  name);
+        final BusinessSubscriptionTransitionTagModelDao subscriptionTransitionTag = new BusinessSubscriptionTransitionTagModelDao(accountKey,
+                                                                                                                                  bundleId,
+                                                                                                                                  externalKey,
+                                                                                                                                  name);
         Assert.assertSame(subscriptionTransitionTag, subscriptionTransitionTag);
         Assert.assertEquals(subscriptionTransitionTag, subscriptionTransitionTag);
         Assert.assertTrue(subscriptionTransitionTag.equals(subscriptionTransitionTag));
@@ -42,10 +43,10 @@ public class TestBusinessSubscriptionTransitionTag extends AnalyticsTestSuite {
         Assert.assertEquals(subscriptionTransitionTag.getExternalKey(), externalKey);
         Assert.assertEquals(subscriptionTransitionTag.getName(), name);
 
-        final BusinessSubscriptionTransitionTag otherTransitionTag = new BusinessSubscriptionTransitionTag(UUID.randomUUID().toString(),
-                                                                                                           UUID.randomUUID(),
-                                                                                                           UUID.randomUUID().toString(),
-                                                                                                           UUID.randomUUID().toString());
+        final BusinessSubscriptionTransitionTagModelDao otherTransitionTag = new BusinessSubscriptionTransitionTagModelDao(UUID.randomUUID().toString(),
+                                                                                                                           UUID.randomUUID(),
+                                                                                                                           UUID.randomUUID().toString(),
+                                                                                                                           UUID.randomUUID().toString());
         Assert.assertFalse(subscriptionTransitionTag.equals(otherTransitionTag));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessInvoiceRecorder.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessInvoiceRecorder.java
index ceebb20..dc38e99 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessInvoiceRecorder.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessInvoiceRecorder.java
@@ -25,7 +25,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.analytics.dao.BusinessInvoiceSqlDao;
-import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessInvoiceItemModelDao;
 import com.ning.billing.catalog.MockCatalog;
 import com.ning.billing.catalog.MockCatalogService;
 import com.ning.billing.catalog.api.Currency;
@@ -59,7 +59,7 @@ public class TestBusinessInvoiceRecorder extends AnalyticsTestSuite {
         Mockito.when(invoiceItem.getStartDate()).thenReturn(new LocalDate(1985, 9, 10));
         Mockito.when(invoiceItem.getInvoiceItemType()).thenReturn(InvoiceItemType.CREDIT_ADJ);
 
-        final BusinessInvoiceItem bii = dao.createBusinessInvoiceItem(invoiceItem, internalCallContext);
+        final BusinessInvoiceItemModelDao bii = dao.createBusinessInvoiceItem(invoiceItem, internalCallContext);
         Assert.assertNotNull(bii);
         Assert.assertEquals(bii.getAmount(), invoiceItem.getAmount());
         Assert.assertEquals(bii.getCurrency(), invoiceItem.getCurrency());
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
index 78dbe98..05e27ec 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
@@ -26,7 +26,7 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.account.api.Account;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionModelDao;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
@@ -64,8 +64,6 @@ public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSui
         final EntitlementInternalApi entitlementApi = Mockito.mock(EntitlementInternalApi.class);
         Mockito.when(entitlementApi.getBundleFromId(Mockito.<UUID>any(), Mockito.<InternalTenantContext>any())).thenReturn(bundle);
 
-
-
         // Setup the account API
         final Account account = Mockito.mock(Account.class);
         Mockito.when(account.getExternalKey()).thenReturn(externalKey.toString());
@@ -92,7 +90,7 @@ public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSui
         dao.rebuildTransitionsForBundle(bundle.getId(), internalCallContext);
 
         Assert.assertEquals(sqlDao.getTransitionsByKey(externalKey.toString(), internalCallContext).size(), 1);
-        final BusinessSubscriptionTransition transition = sqlDao.getTransitionsByKey(externalKey.toString(), internalCallContext).get(0);
+        final BusinessSubscriptionTransitionModelDao transition = sqlDao.getTransitionsByKey(externalKey.toString(), internalCallContext).get(0);
         Assert.assertEquals(transition.getTotalOrdering(), (long) eventEffective.getTotalOrdering());
         Assert.assertEquals(transition.getAccountKey(), externalKey.toString());
         // Make sure all the prev_ columns are null
diff --git a/analytics/src/test/java/com/ning/billing/analytics/utils/TestRounder.java b/analytics/src/test/java/com/ning/billing/analytics/utils/TestRounder.java
index e685641..b5a913f 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/utils/TestRounder.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/utils/TestRounder.java
@@ -24,6 +24,7 @@ import org.testng.annotations.Test;
 import com.ning.billing.analytics.AnalyticsTestSuite;
 
 public class TestRounder extends AnalyticsTestSuite {
+
     @Test(groups = "fast")
     public void testRound() throws Exception {
         Assert.assertEquals(Rounder.round(null), 0.0);
diff --git a/api/src/main/java/com/ning/billing/analytics/api/BusinessAccount.java b/api/src/main/java/com/ning/billing/analytics/api/BusinessAccount.java
new file mode 100644
index 0000000..6b148f0
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/analytics/api/BusinessAccount.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import java.math.BigDecimal;
+
+import org.joda.time.LocalDate;
+
+import com.ning.billing.util.entity.Entity;
+
+public interface BusinessAccount extends Entity {
+
+    /**
+     * @return account external key, if available
+     */
+    public String getExternalKey();
+
+    /**
+     * @return account holder name
+     */
+    public String getName();
+
+    /**
+     * @return account currency
+     */
+    public String getCurrency();
+
+    /**
+     * @return current account balance
+     */
+    public BigDecimal getBalance();
+
+    /**
+     * @return date of the last invoice
+     */
+    public LocalDate getLastInvoiceDate();
+
+    /**
+     * @return sum of all invoices balance
+     */
+    public BigDecimal getTotalInvoiceBalance();
+
+    /**
+     * @return status of the last payment
+     */
+    public String getLastPaymentStatus();
+
+    /**
+     * @return default payment method type
+     */
+    public String getDefaultPaymentMethodType();
+
+    /**
+     * @return type of credit card for the default payment method,
+     *         if the default payment method is a credit card
+     */
+    public String getDefaultCreditCardType();
+
+    /**
+     * @return billing country for the default payment method
+     */
+    public String getDefaultBillingAddressCountry();
+}
diff --git a/api/src/main/java/com/ning/billing/analytics/api/BusinessField.java b/api/src/main/java/com/ning/billing/analytics/api/BusinessField.java
new file mode 100644
index 0000000..cd9c0e9
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/analytics/api/BusinessField.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.entity.Entity;
+
+public interface BusinessField extends Entity {
+
+    /**
+     * @return applicable object type
+     */
+    public ObjectType getObjectType();
+
+    /**
+     * @return custom field name
+     */
+    public String getName();
+
+    /**
+     * @return custom field value
+     */
+    public String getValue();
+}
diff --git a/api/src/main/java/com/ning/billing/analytics/api/BusinessInvoice.java b/api/src/main/java/com/ning/billing/analytics/api/BusinessInvoice.java
new file mode 100644
index 0000000..76b590b
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/analytics/api/BusinessInvoice.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.LocalDate;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.entity.Entity;
+
+public interface BusinessInvoice extends Entity {
+
+    public UUID getInvoiceId();
+
+    public Integer getInvoiceNumber();
+
+    public UUID getAccountId();
+
+    public String getAccountKey();
+
+    public LocalDate getInvoiceDate();
+
+    public LocalDate getTargetDate();
+
+    public Currency getCurrency();
+
+    public BigDecimal getBalance();
+
+    public BigDecimal getAmountPaid();
+
+    public BigDecimal getAmountCharged();
+
+    public BigDecimal getAmountCredited();
+
+    public List<BusinessInvoiceItem> getInvoiceItems();
+
+    public interface BusinessInvoiceItem {
+
+        public UUID getItemId();
+
+        public UUID getInvoiceId();
+
+        public String getItemType();
+
+        public String getExternalKey();
+
+        public String getProductName();
+
+        public String getProductType();
+
+        public String getProductCategory();
+
+        public String getSlug();
+
+        public String getPhase();
+
+        public String getBillingPeriod();
+
+        public LocalDate getStartDate();
+
+        public LocalDate getEndDate();
+
+        public BigDecimal getAmount();
+
+        public Currency getCurrency();
+
+        public UUID getLinkedItemId();
+    }
+}
diff --git a/api/src/main/java/com/ning/billing/analytics/api/BusinessInvoicePayment.java b/api/src/main/java/com/ning/billing/analytics/api/BusinessInvoicePayment.java
new file mode 100644
index 0000000..6bf4162
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/analytics/api/BusinessInvoicePayment.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.entity.Entity;
+
+public interface BusinessInvoicePayment extends Entity {
+
+    public UUID getPaymentId();
+
+    public String getExtFirstPaymentRefId();
+
+    public String getExtSecondPaymentRefId();
+
+    public String getAccountKey();
+
+    public UUID getInvoiceId();
+
+    public DateTime getEffectiveDate();
+
+    public BigDecimal getAmount();
+
+    public Currency getCurrency();
+
+    public String getPaymentError();
+
+    public String getProcessingStatus();
+
+    public BigDecimal getRequestedAmount();
+
+    public String getPluginName();
+
+    public String getPaymentType();
+
+    public String getPaymentMethod();
+
+    public String getCardType();
+
+    public String getCardCountry();
+
+    public String getInvoicePaymentType();
+
+    public UUID getLinkedInvoicePaymentId();
+}
diff --git a/api/src/main/java/com/ning/billing/analytics/api/BusinessOverdueStatus.java b/api/src/main/java/com/ning/billing/analytics/api/BusinessOverdueStatus.java
new file mode 100644
index 0000000..0d1737f
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/analytics/api/BusinessOverdueStatus.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.entity.Entity;
+
+public interface BusinessOverdueStatus extends Entity {
+
+    /**
+     * @return applicable object type
+     */
+    public ObjectType getObjectType();
+
+    public String getAccountKey();
+
+    public String getStatus();
+
+    public DateTime getStartDate();
+
+    public DateTime getEndDate();
+}
diff --git a/api/src/main/java/com/ning/billing/analytics/api/BusinessSnapshot.java b/api/src/main/java/com/ning/billing/analytics/api/BusinessSnapshot.java
new file mode 100644
index 0000000..ed2575f
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/analytics/api/BusinessSnapshot.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import java.util.Collection;
+
+public interface BusinessSnapshot {
+
+    public BusinessAccount getBusinessAccount();
+
+    public Collection<BusinessSubscriptionTransition> getBusinessSubscriptionTransitions();
+
+    public Collection<BusinessInvoice> getBusinessInvoices();
+
+    public Collection<BusinessInvoicePayment> getBusinessInvoicePayments();
+
+    public Collection<BusinessOverdueStatus> getBusinessOverdueStatuses();
+
+    public Collection<BusinessTag> getBusinessTags();
+
+    public Collection<BusinessField> getBusinessFields();
+}
diff --git a/api/src/main/java/com/ning/billing/analytics/api/BusinessSubscriptionTransition.java b/api/src/main/java/com/ning/billing/analytics/api/BusinessSubscriptionTransition.java
new file mode 100644
index 0000000..05684b6
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/analytics/api/BusinessSubscriptionTransition.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.util.entity.Entity;
+
+public interface BusinessSubscriptionTransition extends Entity {
+
+    public long getTotalOrdering();
+
+    public UUID getBundleId();
+
+    public String getExternalKey();
+
+    public UUID getAccountId();
+
+    public String getAccountKey();
+
+    public UUID getSubscriptionId();
+
+    public DateTime getRequestedTimestamp();
+
+    public String getEventType();
+
+    public String getCategory();
+
+    public String getPrevProductName();
+
+    public String getPrevProductType();
+
+    public String getPrevProductCategory();
+
+    public String getPrevSlug();
+
+    public String getPrevPhase();
+
+    public String getPrevBillingPeriod();
+
+    public BigDecimal getPrevPrice();
+
+    public String getPrevPriceList();
+
+    public BigDecimal getPrevMrr();
+
+    public String getPrevCurrency();
+
+    public DateTime getPrevStartDate();
+
+    public String getPrevState();
+
+    public String getNextProductName();
+
+    public String getNextProductType();
+
+    public String getNextProductCategory();
+
+    public String getNextSlug();
+
+    public String getNextPhase();
+
+    public String getNextBillingPeriod();
+
+    public BigDecimal getNextPrice();
+
+    public String getNextPriceList();
+
+    public BigDecimal getNextMrr();
+
+    public String getNextCurrency();
+
+    public DateTime getNextStartDate();
+
+    public String getNextState();
+}
diff --git a/api/src/main/java/com/ning/billing/analytics/api/BusinessTag.java b/api/src/main/java/com/ning/billing/analytics/api/BusinessTag.java
new file mode 100644
index 0000000..0799364
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/analytics/api/BusinessTag.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2012 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.analytics.api;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.util.entity.Entity;
+
+public interface BusinessTag extends Entity {
+
+    /**
+     * @return applicable object type
+     */
+    public ObjectType getObjectType();
+
+    /**
+     * @return tag name
+     */
+    public String getName();
+}
diff --git a/api/src/main/java/com/ning/billing/analytics/api/sanity/AnalyticsSanityApi.java b/api/src/main/java/com/ning/billing/analytics/api/sanity/AnalyticsSanityApi.java
new file mode 100644
index 0000000..adf59c4
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/analytics/api/sanity/AnalyticsSanityApi.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010-2012 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.analytics.api.sanity;
+
+import java.util.Collection;
+import java.util.UUID;
+
+import com.ning.billing.util.callcontext.TenantContext;
+
+public interface AnalyticsSanityApi {
+
+    /**
+     * @return the list of account ids not in sync with entitlement
+     */
+    public Collection<UUID> checkAnalyticsInSyncWithEntitlement(TenantContext context);
+
+    /**
+     * @return the list of account ids not in sync with invoice
+     */
+    public Collection<UUID> checkAnalyticsInSyncWithInvoice(TenantContext context);
+
+    /**
+     * @return the list of account ids not in sync with payment
+     */
+    public Collection<UUID> checkAnalyticsInSyncWithPayment(TenantContext context);
+
+    /**
+     * @return the list of account ids not in sync with the tag service
+     */
+    public Collection<UUID> checkAnalyticsInSyncWithTag(TenantContext context);
+
+    /**
+     * @return the list of account ids not self-consistent in Analytics
+     */
+    public Collection<UUID> checkAnalyticsConsistency(TenantContext context);
+}
diff --git a/api/src/main/java/com/ning/billing/analytics/api/user/AnalyticsUserApi.java b/api/src/main/java/com/ning/billing/analytics/api/user/AnalyticsUserApi.java
index 859a1eb..42e2484 100644
--- a/api/src/main/java/com/ning/billing/analytics/api/user/AnalyticsUserApi.java
+++ b/api/src/main/java/com/ning/billing/analytics/api/user/AnalyticsUserApi.java
@@ -16,7 +16,16 @@
 
 package com.ning.billing.analytics.api.user;
 
+import java.util.List;
+
 import com.ning.billing.account.api.Account;
+import com.ning.billing.analytics.api.BusinessAccount;
+import com.ning.billing.analytics.api.BusinessInvoice;
+import com.ning.billing.analytics.api.BusinessInvoicePayment;
+import com.ning.billing.analytics.api.BusinessOverdueStatus;
+import com.ning.billing.analytics.api.BusinessSnapshot;
+import com.ning.billing.analytics.api.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.api.BusinessTag;
 import com.ning.billing.analytics.api.TimeSeriesData;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.TenantContext;
@@ -26,6 +35,20 @@ import com.ning.billing.util.callcontext.TenantContext;
  */
 public interface AnalyticsUserApi {
 
+    public BusinessSnapshot getBusinessSnapshot(Account account, TenantContext context);
+
+    public BusinessAccount getAccountByKey(String accountKey, TenantContext context);
+
+    public List<BusinessSubscriptionTransition> getTransitionsForBundle(String externalKey, TenantContext context);
+
+    public List<BusinessInvoice> getInvoicesForAccount(String accountKey, TenantContext context);
+
+    public List<BusinessInvoicePayment> getInvoicePaymentsForAccount(String accountKey, TenantContext context);
+
+    public List<BusinessOverdueStatus> getOverdueStatusesForBundle(String externalKey, TenantContext context);
+
+    public List<BusinessTag> getTagsForAccount(String accountKey, TenantContext context);
+
     /**
      * @return the number of accounts created per day
      */
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java
index 3b738db..328ab3f 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java
@@ -35,14 +35,14 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountData;
 import com.ning.billing.account.api.MutableAccountData;
-import com.ning.billing.analytics.model.BusinessAccount;
-import com.ning.billing.analytics.model.BusinessAccountTag;
-import com.ning.billing.analytics.model.BusinessInvoice;
-import com.ning.billing.analytics.model.BusinessInvoiceItem;
-import com.ning.billing.analytics.model.BusinessInvoicePayment;
-import com.ning.billing.analytics.model.BusinessOverdueStatus;
+import com.ning.billing.analytics.api.BusinessAccount;
+import com.ning.billing.analytics.api.BusinessInvoice;
+import com.ning.billing.analytics.api.BusinessInvoice.BusinessInvoiceItem;
+import com.ning.billing.analytics.api.BusinessInvoicePayment;
+import com.ning.billing.analytics.api.BusinessOverdueStatus;
+import com.ning.billing.analytics.api.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.api.BusinessTag;
 import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
-import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
 import com.ning.billing.analytics.utils.Rounder;
 import com.ning.billing.api.TestApiListener;
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -75,48 +75,48 @@ public class TestAnalytics extends TestIntegrationBase {
     @BeforeMethod(groups = "slow")
     public void setUpAnalyticsHandler() throws Exception {
         final String configXml = "<overdueConfig>" +
-                "   <bundleOverdueStates>" +
-                "       <state name=\"OD3\">" +
-                "           <condition>" +
-                "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                "                   <unit>DAYS</unit><number>50</number>" +
-                "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                "           </condition>" +
-                "           <externalMessage>Reached OD3</externalMessage>" +
-                "           <blockChanges>true</blockChanges>" +
-                "           <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
-                "           <autoReevaluationInterval>" +
-                "               <unit>DAYS</unit><number>5</number>" +
-                "           </autoReevaluationInterval>" +
-                "       </state>" +
-                "       <state name=\"OD2\">" +
-                "           <condition>" +
-                "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                "                   <unit>DAYS</unit><number>40</number>" +
-                "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                "           </condition>" +
-                "           <externalMessage>Reached OD2</externalMessage>" +
-                "           <blockChanges>true</blockChanges>" +
-                "           <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
-                "           <autoReevaluationInterval>" +
-                "               <unit>DAYS</unit><number>5</number>" +
-                "           </autoReevaluationInterval>" +
-                "       </state>" +
-                "       <state name=\"OD1\">" +
-                "           <condition>" +
-                "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                "                   <unit>DAYS</unit><number>30</number>" +
-                "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                "           </condition>" +
-                "           <externalMessage>Reached OD1</externalMessage>" +
-                "           <blockChanges>true</blockChanges>" +
-                "           <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
-                "           <autoReevaluationInterval>" +
-                "               <unit>DAYS</unit><number>100</number>" + // this number is intentionally too high
-                "           </autoReevaluationInterval>" +
-                "       </state>" +
-                "   </bundleOverdueStates>" +
-                "</overdueConfig>";
+                                 "   <bundleOverdueStates>" +
+                                 "       <state name=\"OD3\">" +
+                                 "           <condition>" +
+                                 "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                                 "                   <unit>DAYS</unit><number>50</number>" +
+                                 "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                                 "           </condition>" +
+                                 "           <externalMessage>Reached OD3</externalMessage>" +
+                                 "           <blockChanges>true</blockChanges>" +
+                                 "           <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
+                                 "           <autoReevaluationInterval>" +
+                                 "               <unit>DAYS</unit><number>5</number>" +
+                                 "           </autoReevaluationInterval>" +
+                                 "       </state>" +
+                                 "       <state name=\"OD2\">" +
+                                 "           <condition>" +
+                                 "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                                 "                   <unit>DAYS</unit><number>40</number>" +
+                                 "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                                 "           </condition>" +
+                                 "           <externalMessage>Reached OD2</externalMessage>" +
+                                 "           <blockChanges>true</blockChanges>" +
+                                 "           <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
+                                 "           <autoReevaluationInterval>" +
+                                 "               <unit>DAYS</unit><number>5</number>" +
+                                 "           </autoReevaluationInterval>" +
+                                 "       </state>" +
+                                 "       <state name=\"OD1\">" +
+                                 "           <condition>" +
+                                 "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                                 "                   <unit>DAYS</unit><number>30</number>" +
+                                 "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                                 "           </condition>" +
+                                 "           <externalMessage>Reached OD1</externalMessage>" +
+                                 "           <blockChanges>true</blockChanges>" +
+                                 "           <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
+                                 "           <autoReevaluationInterval>" +
+                                 "               <unit>DAYS</unit><number>100</number>" + // this number is intentionally too high
+                                 "           </autoReevaluationInterval>" +
+                                 "       </state>" +
+                                 "   </bundleOverdueStates>" +
+                                 "</overdueConfig>";
         final InputStream is = new ByteArrayInputStream(configXml.getBytes());
         final OverdueConfig config = XMLLoader.getObjectFromStreamNoValidation(is, OverdueConfig.class);
         overdueWrapperFactory.setOverdueConfig(config);
@@ -146,7 +146,7 @@ public class TestAnalytics extends TestIntegrationBase {
         analyticsUserApi.rebuildAnalyticsForAccount(account, callContext);
 
         // Check the tag
-        final List<BusinessAccountTag> tagsForAccount = analyticsUserApi.getTagsForAccount(account.getExternalKey(), callContext);
+        final List<BusinessTag> tagsForAccount = analyticsUserApi.getTagsForAccount(account.getExternalKey(), callContext);
         Assert.assertEquals(tagsForAccount.size(), 1);
         Assert.assertEquals(tagsForAccount.get(0).getName(), tagDefinition.getName());
     }
@@ -280,8 +280,7 @@ public class TestAnalytics extends TestIntegrationBase {
         final List<BusinessOverdueStatus> od1Bundle = analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey(), callContext);
         Assert.assertEquals(od1Bundle.size(), 1);
         Assert.assertEquals(od1Bundle.get(0).getStatus(), "OD1");
-        Assert.assertEquals(od1Bundle.get(0).getBundleId(), bundle.getId());
-        Assert.assertEquals(od1Bundle.get(0).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od1Bundle.get(0).getId(), bundle.getId());
         Assert.assertEquals(od1Bundle.get(0).getAccountKey(), account.getExternalKey());
 
         clock.addDays(2); // DAY 67 - 37 days after invoice
@@ -291,8 +290,7 @@ public class TestAnalytics extends TestIntegrationBase {
         final List<BusinessOverdueStatus> stillOd1Bundle = analyticsUserApi.getOverdueStatusesForBundle(bundle.getKey(), callContext);
         Assert.assertEquals(stillOd1Bundle.size(), 1);
         Assert.assertEquals(stillOd1Bundle.get(0).getStatus(), "OD1");
-        Assert.assertEquals(stillOd1Bundle.get(0).getBundleId(), bundle.getId());
-        Assert.assertEquals(stillOd1Bundle.get(0).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(stillOd1Bundle.get(0).getId(), bundle.getId());
         Assert.assertEquals(stillOd1Bundle.get(0).getAccountKey(), account.getExternalKey());
 
         clock.addDays(8); // DAY 75 - 45 days after invoice
@@ -305,11 +303,9 @@ public class TestAnalytics extends TestIntegrationBase {
         Assert.assertEquals(od2Bundle.get(1).getStatus(), "OD2");
         Assert.assertEquals(od2Bundle.get(0).getEndDate(),
                             od2Bundle.get(1).getStartDate());
-        Assert.assertEquals(od2Bundle.get(0).getBundleId(), bundle.getId());
-        Assert.assertEquals(od2Bundle.get(0).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od2Bundle.get(0).getId(), bundle.getId());
         Assert.assertEquals(od2Bundle.get(0).getAccountKey(), account.getExternalKey());
-        Assert.assertEquals(od2Bundle.get(1).getBundleId(), bundle.getId());
-        Assert.assertEquals(od2Bundle.get(1).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od2Bundle.get(1).getId(), bundle.getId());
         Assert.assertEquals(od2Bundle.get(1).getAccountKey(), account.getExternalKey());
 
         clock.addDays(10); // DAY 85 - 55 days after invoice
@@ -325,14 +321,11 @@ public class TestAnalytics extends TestIntegrationBase {
                             od3Bundle.get(1).getStartDate());
         Assert.assertEquals(od3Bundle.get(1).getEndDate(),
                             od3Bundle.get(2).getStartDate());
-        Assert.assertEquals(od3Bundle.get(0).getBundleId(), bundle.getId());
-        Assert.assertEquals(od3Bundle.get(0).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od3Bundle.get(0).getId(), bundle.getId());
         Assert.assertEquals(od3Bundle.get(0).getAccountKey(), account.getExternalKey());
-        Assert.assertEquals(od3Bundle.get(1).getBundleId(), bundle.getId());
-        Assert.assertEquals(od3Bundle.get(1).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od3Bundle.get(1).getId(), bundle.getId());
         Assert.assertEquals(od3Bundle.get(1).getAccountKey(), account.getExternalKey());
-        Assert.assertEquals(od3Bundle.get(2).getBundleId(), bundle.getId());
-        Assert.assertEquals(od3Bundle.get(2).getExternalKey(), bundle.getKey());
+        Assert.assertEquals(od3Bundle.get(2).getId(), bundle.getId());
         Assert.assertEquals(od3Bundle.get(2).getAccountKey(), account.getExternalKey());
     }
 
@@ -354,7 +347,7 @@ public class TestAnalytics extends TestIntegrationBase {
         Assert.assertNotNull(businessAccount);
         // No balance yet
         Assert.assertEquals(businessAccount.getBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
-        Assert.assertEquals(businessAccount.getKey(), account.getExternalKey());
+        Assert.assertEquals(businessAccount.getExternalKey(), account.getExternalKey());
         // No invoice yet
         Assert.assertNull(businessAccount.getLastInvoiceDate());
         // No payment yet
@@ -391,7 +384,7 @@ public class TestAnalytics extends TestIntegrationBase {
         Assert.assertNotNull(businessAccount);
         // No balance yet
         Assert.assertEquals(businessAccount.getBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
-        Assert.assertEquals(businessAccount.getKey(), mutableAccountData.getExternalKey());
+        Assert.assertEquals(businessAccount.getExternalKey(), mutableAccountData.getExternalKey());
         // No invoice yet
         Assert.assertNull(businessAccount.getLastInvoiceDate());
         // No payment yet
@@ -416,7 +409,7 @@ public class TestAnalytics extends TestIntegrationBase {
 
         waitALittle();
 
-        final List<BusinessAccountTag> tagsForAccount = analyticsUserApi.getTagsForAccount(account.getExternalKey(), callContext);
+        final List<BusinessTag> tagsForAccount = analyticsUserApi.getTagsForAccount(account.getExternalKey(), callContext);
         Assert.assertEquals(tagsForAccount.size(), 1);
         Assert.assertEquals(tagsForAccount.get(0).getName(), tagDefinition.getName());
     }
@@ -467,7 +460,7 @@ public class TestAnalytics extends TestIntegrationBase {
         Assert.assertEquals(invoice.getCurrency(), account.getCurrency());
 
         // The invoice should have a single item associated to it
-        final List<BusinessInvoiceItem> invoiceItems = analyticsUserApi.getInvoiceItemsForInvoice(invoice.getInvoiceId(), callContext);
+        final List<BusinessInvoiceItem> invoiceItems = invoice.getInvoiceItems();
         Assert.assertEquals(invoiceItems.size(), 1);
         final BusinessInvoiceItem invoiceItem = invoiceItems.get(0);
         Assert.assertEquals(invoiceItem.getAmount().doubleValue(), 0.0);
@@ -527,48 +520,46 @@ public class TestAnalytics extends TestIntegrationBase {
         Assert.assertEquals(initialTransition.getAccountId(), account.getId());
         Assert.assertEquals(initialTransition.getAccountKey(), account.getExternalKey());
         Assert.assertEquals(initialTransition.getSubscriptionId(), subscription.getId());
-        Assert.assertEquals(initialTransition.getEvent().getCategory(), currentProduct.getCategory());
-        Assert.assertEquals(initialTransition.getEvent().getEventType(), BusinessSubscriptionEvent.EventType.ADD);
+        Assert.assertEquals(initialTransition.getCategory(), currentProduct.getCategory().toString());
+        Assert.assertEquals(initialTransition.getEventType(), BusinessSubscriptionEvent.EventType.ADD.toString());
 
         // This is the first transition
-        Assert.assertNull(initialTransition.getPreviousSubscription());
+        Assert.assertNull(initialTransition.getPrevSlug());
 
-        Assert.assertEquals(initialTransition.getNextSubscription().getBillingPeriod(), BillingPeriod.NO_BILLING_PERIOD.toString());
-        Assert.assertEquals(initialTransition.getNextSubscription().getCurrency(), account.getCurrency().toString());
-        Assert.assertEquals(initialTransition.getNextSubscription().getPhase(), PhaseType.TRIAL.toString());
+        Assert.assertEquals(initialTransition.getNextBillingPeriod(), BillingPeriod.NO_BILLING_PERIOD.toString());
+        Assert.assertEquals(initialTransition.getNextCurrency(), account.getCurrency().toString());
+        Assert.assertEquals(initialTransition.getNextPhase(), PhaseType.TRIAL.toString());
         // Trial: fixed price of zero
-        Assert.assertEquals(initialTransition.getNextSubscription().getPrice().doubleValue(), (double) 0);
-        Assert.assertEquals(initialTransition.getNextSubscription().getPriceList(), subscription.getCurrentPriceList().getName());
-        Assert.assertEquals(initialTransition.getNextSubscription().getProductCategory(), currentProduct.getCategory());
-        Assert.assertEquals(initialTransition.getNextSubscription().getProductName(), currentProduct.getName());
-        Assert.assertEquals(initialTransition.getNextSubscription().getProductType(), currentProduct.getCatalogName());
-        Assert.assertEquals(initialTransition.getNextSubscription().getSlug(), currentProduct.getName().toLowerCase() + "-monthly-trial");
-        Assert.assertEquals(initialTransition.getNextSubscription().getStartDate(), subscription.getStartDate());
-        Assert.assertEquals(initialTransition.getNextSubscription().getState(), Subscription.SubscriptionState.ACTIVE);
+        Assert.assertEquals(initialTransition.getNextPrice().doubleValue(), (double) 0);
+        Assert.assertEquals(initialTransition.getNextPriceList(), subscription.getCurrentPriceList().getName());
+        Assert.assertEquals(initialTransition.getNextProductCategory(), currentProduct.getCategory().toString());
+        Assert.assertEquals(initialTransition.getNextProductName(), currentProduct.getName());
+        Assert.assertEquals(initialTransition.getNextProductType(), currentProduct.getCatalogName());
+        Assert.assertEquals(initialTransition.getNextSlug(), currentProduct.getName().toLowerCase() + "-monthly-trial");
+        Assert.assertEquals(initialTransition.getNextStartDate(), subscription.getStartDate());
+        Assert.assertEquals(initialTransition.getNextState(), Subscription.SubscriptionState.ACTIVE.toString());
 
         // Check the second transition (from trial to evergreen)
         final BusinessSubscriptionTransition futureTransition = transitions.get(1);
         Assert.assertEquals(futureTransition.getExternalKey(), bundle.getKey());
         Assert.assertEquals(futureTransition.getAccountKey(), account.getExternalKey());
-        Assert.assertEquals(futureTransition.getEvent().getCategory(), currentProduct.getCategory());
-        Assert.assertEquals(futureTransition.getEvent().getEventType(), BusinessSubscriptionEvent.EventType.SYSTEM_CHANGE);
-
-        Assert.assertEquals(futureTransition.getPreviousSubscription(), initialTransition.getNextSubscription());
+        Assert.assertEquals(futureTransition.getCategory(), currentProduct.getCategory().toString());
+        Assert.assertEquals(futureTransition.getEventType(), BusinessSubscriptionEvent.EventType.SYSTEM_CHANGE.toString());
 
         // The billing period should have changed (NO_BILLING_PERIOD for the trial period)
-        Assert.assertEquals(futureTransition.getNextSubscription().getBillingPeriod(), BillingPeriod.MONTHLY.toString());
-        Assert.assertEquals(initialTransition.getNextSubscription().getCurrency(), account.getCurrency().toString());
+        Assert.assertEquals(futureTransition.getNextBillingPeriod(), BillingPeriod.MONTHLY.toString());
+        Assert.assertEquals(initialTransition.getNextCurrency(), account.getCurrency().toString());
         // From trial to evergreen
-        Assert.assertEquals(futureTransition.getNextSubscription().getPhase(), PhaseType.EVERGREEN.toString());
-        Assert.assertTrue(futureTransition.getNextSubscription().getPrice().doubleValue() > 0);
-        Assert.assertEquals(futureTransition.getNextSubscription().getPriceList(), subscription.getCurrentPriceList().getName());
-        Assert.assertEquals(futureTransition.getNextSubscription().getProductCategory(), currentProduct.getCategory());
-        Assert.assertEquals(futureTransition.getNextSubscription().getProductName(), currentProduct.getName());
-        Assert.assertEquals(futureTransition.getNextSubscription().getProductType(), currentProduct.getCatalogName());
-        Assert.assertEquals(futureTransition.getNextSubscription().getSlug(), currentProduct.getName().toLowerCase() + "-monthly-evergreen");
+        Assert.assertEquals(futureTransition.getNextPhase(), PhaseType.EVERGREEN.toString());
+        Assert.assertTrue(futureTransition.getNextPrice().doubleValue() > 0);
+        Assert.assertEquals(futureTransition.getNextPriceList(), subscription.getCurrentPriceList().getName());
+        Assert.assertEquals(futureTransition.getNextProductCategory(), currentProduct.getCategory().toString());
+        Assert.assertEquals(futureTransition.getNextProductName(), currentProduct.getName());
+        Assert.assertEquals(futureTransition.getNextProductType(), currentProduct.getCatalogName());
+        Assert.assertEquals(futureTransition.getNextSlug(), currentProduct.getName().toLowerCase() + "-monthly-evergreen");
         // 30 days trial
-        Assert.assertEquals(futureTransition.getNextSubscription().getStartDate(), subscription.getStartDate().plusDays(30));
-        Assert.assertEquals(futureTransition.getNextSubscription().getState(), Subscription.SubscriptionState.ACTIVE);
+        Assert.assertEquals(futureTransition.getNextStartDate(), subscription.getStartDate().plusDays(30));
+        Assert.assertEquals(futureTransition.getNextState(), Subscription.SubscriptionState.ACTIVE.toString());
     }
 
     private void verifyCancellationTransition(final Account account, final SubscriptionBundle bundle) throws CatalogApiException {
@@ -578,12 +569,10 @@ public class TestAnalytics extends TestIntegrationBase {
         final BusinessSubscriptionTransition cancellationRequest = transitions.get(2);
         Assert.assertEquals(cancellationRequest.getExternalKey(), bundle.getKey());
         Assert.assertEquals(cancellationRequest.getAccountKey(), account.getExternalKey());
-        Assert.assertEquals(cancellationRequest.getEvent().getCategory(), currentProduct.getCategory());
-        Assert.assertEquals(cancellationRequest.getEvent().getEventType(), BusinessSubscriptionEvent.EventType.CANCEL);
+        Assert.assertEquals(cancellationRequest.getCategory(), currentProduct.getCategory().toString());
+        Assert.assertEquals(cancellationRequest.getEventType(), BusinessSubscriptionEvent.EventType.CANCEL.toString());
 
-        Assert.assertNull(cancellationRequest.getNextSubscription());
-        // The actual content has already been checked in verifyTrialAndEvergreenPhases
-        Assert.assertEquals(cancellationRequest.getPreviousSubscription(), transitions.get(1).getNextSubscription());
+        Assert.assertNull(cancellationRequest.getNextSlug());
     }
 
     private void verifySystemCancellationTransition(final Account account, final SubscriptionBundle bundle) throws CatalogApiException {
@@ -592,12 +581,10 @@ public class TestAnalytics extends TestIntegrationBase {
         final BusinessSubscriptionTransition systemCancellation = transitions.get(3);
         Assert.assertEquals(systemCancellation.getExternalKey(), bundle.getKey());
         Assert.assertEquals(systemCancellation.getAccountKey(), account.getExternalKey());
-        Assert.assertEquals(systemCancellation.getEvent().getCategory(), ProductCategory.BASE);
-        Assert.assertEquals(systemCancellation.getEvent().getEventType(), BusinessSubscriptionEvent.EventType.SYSTEM_CANCEL);
+        Assert.assertEquals(systemCancellation.getCategory(), ProductCategory.BASE.toString());
+        Assert.assertEquals(systemCancellation.getEventType(), BusinessSubscriptionEvent.EventType.SYSTEM_CANCEL.toString());
 
-        Assert.assertNull(systemCancellation.getNextSubscription());
-        // The actual content has already been checked in verifyTrialAndEvergreenPhases
-        Assert.assertEquals(systemCancellation.getPreviousSubscription(), transitions.get(1).getNextSubscription());
+        Assert.assertNull(systemCancellation.getNextSlug());
     }
 
     private void verifyChangePlan(final Account account, final SubscriptionBundle bundle, final Subscription subscription) throws EntitlementUserApiException, InterruptedException {
@@ -619,27 +606,26 @@ public class TestAnalytics extends TestIntegrationBase {
         Assert.assertEquals(transition.getAccountId(), account.getId());
         Assert.assertEquals(transition.getAccountKey(), account.getExternalKey());
         Assert.assertEquals(transition.getSubscriptionId(), subscription.getId());
-        Assert.assertEquals(transition.getEvent().getCategory(), ProductCategory.BASE);
-        Assert.assertEquals(transition.getEvent().getEventType(), BusinessSubscriptionEvent.EventType.CHANGE);
+        Assert.assertEquals(transition.getCategory(), ProductCategory.BASE.toString());
+        Assert.assertEquals(transition.getEventType(), BusinessSubscriptionEvent.EventType.CHANGE.toString());
 
-        // Verify the previous subscription matches
-        Assert.assertNull(previousTransition.getPreviousSubscription());
-        Assert.assertEquals(previousTransition.getNextSubscription(), transition.getPreviousSubscription());
+        // Verify the previous subscription is null
+        Assert.assertNull(previousTransition.getPrevSlug());
 
         // Verify the next subscription
         // No billing period for the trial phase
-        Assert.assertEquals(transition.getNextSubscription().getBillingPeriod(), BillingPeriod.NO_BILLING_PERIOD.toString());
-        Assert.assertEquals(transition.getNextSubscription().getCurrency(), account.getCurrency().toString());
-        Assert.assertEquals(transition.getNextSubscription().getPhase(), PhaseType.TRIAL.toString());
+        Assert.assertEquals(transition.getNextBillingPeriod(), BillingPeriod.NO_BILLING_PERIOD.toString());
+        Assert.assertEquals(transition.getNextCurrency(), account.getCurrency().toString());
+        Assert.assertEquals(transition.getNextPhase(), PhaseType.TRIAL.toString());
         // We're still in trial
-        Assert.assertEquals(transition.getNextSubscription().getPrice().doubleValue(), 0.0);
-        Assert.assertEquals(transition.getNextSubscription().getPriceList(), newPlanSetName);
-        Assert.assertEquals(transition.getNextSubscription().getProductCategory(), ProductCategory.BASE);
-        Assert.assertEquals(transition.getNextSubscription().getProductName(), newProductName);
-        Assert.assertEquals(transition.getNextSubscription().getProductType(), subscription.getCurrentPlan().getProduct().getCatalogName());
-        Assert.assertEquals(transition.getNextSubscription().getSlug(), subscription.getCurrentPhase().getName());
-        Assert.assertEquals(transition.getNextSubscription().getStartDate(), requestedDate);
-        Assert.assertEquals(transition.getNextSubscription().getState(), Subscription.SubscriptionState.ACTIVE);
+        Assert.assertEquals(transition.getNextPrice().doubleValue(), 0.0);
+        Assert.assertEquals(transition.getNextPriceList(), newPlanSetName);
+        Assert.assertEquals(transition.getNextProductCategory(), ProductCategory.BASE.toString());
+        Assert.assertEquals(transition.getNextProductName(), newProductName);
+        Assert.assertEquals(transition.getNextProductType(), subscription.getCurrentPlan().getProduct().getCatalogName());
+        Assert.assertEquals(transition.getNextSlug(), subscription.getCurrentPhase().getName());
+        Assert.assertEquals(transition.getNextStartDate(), requestedDate);
+        Assert.assertEquals(transition.getNextState(), Subscription.SubscriptionState.ACTIVE.toString());
 
         // The account should have two invoices for the trial phase of both subscriptions
         final List<BusinessInvoice> invoicesForAccount = analyticsUserApi.getInvoicesForAccount(account.getExternalKey(), callContext);
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AnalyticsSanityJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AnalyticsSanityJson.java
new file mode 100644
index 0000000..f2e4136
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AnalyticsSanityJson.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2010-2012 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.jaxrs.json;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+
+public class AnalyticsSanityJson extends JsonBase {
+
+    private final List<String> checkEntitlement;
+    private final List<String> checkInvoice;
+    private final List<String> checkPayment;
+    private final List<String> checkTag;
+    private final List<String> checkConsistency;
+
+    @JsonCreator
+    public AnalyticsSanityJson(@JsonProperty("checkEntitlement") final List<String> checkEntitlement,
+                               @JsonProperty("checkInvoice") final List<String> checkInvoice,
+                               @JsonProperty("checkPayment") final List<String> checkPayment,
+                               @JsonProperty("checkTag") final List<String> checkTag,
+                               @JsonProperty("checkConsistency") final List<String> checkConsistency) {
+        this.checkEntitlement = checkEntitlement;
+        this.checkInvoice = checkInvoice;
+        this.checkPayment = checkPayment;
+        this.checkTag = checkTag;
+        this.checkConsistency = checkConsistency;
+    }
+
+    public AnalyticsSanityJson(final Collection<UUID> checkEntitlement,
+                               final Collection<UUID> checkInvoice,
+                               final Collection<UUID> checkPayment,
+                               final Collection<UUID> checkTag,
+                               final Collection<UUID> checkConsistency) {
+        this.checkEntitlement = ImmutableList.<String>copyOf(Collections2.transform(checkEntitlement, new Function<UUID, String>() {
+            @Override
+            public String apply(final UUID input) {
+                return input.toString();
+            }
+        }));
+        this.checkInvoice = ImmutableList.<String>copyOf(Collections2.transform(checkInvoice, new Function<UUID, String>() {
+            @Override
+            public String apply(final UUID input) {
+                return input.toString();
+            }
+        }));
+        this.checkPayment = ImmutableList.<String>copyOf(Collections2.transform(checkPayment, new Function<UUID, String>() {
+            @Override
+            public String apply(final UUID input) {
+                return input.toString();
+            }
+        }));
+        this.checkTag = ImmutableList.<String>copyOf(Collections2.transform(checkTag, new Function<UUID, String>() {
+            @Override
+            public String apply(final UUID input) {
+                return input.toString();
+            }
+        }));
+        this.checkConsistency = ImmutableList.<String>copyOf(Collections2.transform(checkConsistency, new Function<UUID, String>() {
+            @Override
+            public String apply(final UUID input) {
+                return input.toString();
+            }
+        }));
+    }
+
+    public List<String> getCheckEntitlement() {
+        return checkEntitlement;
+    }
+
+    public List<String> getCheckInvoice() {
+        return checkInvoice;
+    }
+
+    public List<String> getCheckPayment() {
+        return checkPayment;
+    }
+
+    public List<String> getCheckTag() {
+        return checkTag;
+    }
+
+    public List<String> getCheckConsistency() {
+        return checkConsistency;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("AnalyticsSanityJson");
+        sb.append("{checkEntitlement=").append(checkEntitlement);
+        sb.append(", checkInvoice=").append(checkInvoice);
+        sb.append(", checkPayment=").append(checkPayment);
+        sb.append(", checkTag=").append(checkTag);
+        sb.append(", checkConsistency=").append(checkConsistency);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final AnalyticsSanityJson json = (AnalyticsSanityJson) o;
+
+        if (checkConsistency != null ? !checkConsistency.equals(json.checkConsistency) : json.checkConsistency != null) {
+            return false;
+        }
+        if (checkEntitlement != null ? !checkEntitlement.equals(json.checkEntitlement) : json.checkEntitlement != null) {
+            return false;
+        }
+        if (checkInvoice != null ? !checkInvoice.equals(json.checkInvoice) : json.checkInvoice != null) {
+            return false;
+        }
+        if (checkPayment != null ? !checkPayment.equals(json.checkPayment) : json.checkPayment != null) {
+            return false;
+        }
+        if (checkTag != null ? !checkTag.equals(json.checkTag) : json.checkTag != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = checkEntitlement != null ? checkEntitlement.hashCode() : 0;
+        result = 31 * result + (checkInvoice != null ? checkInvoice.hashCode() : 0);
+        result = 31 * result + (checkPayment != null ? checkPayment.hashCode() : 0);
+        result = 31 * result + (checkTag != null ? checkTag.hashCode() : 0);
+        result = 31 * result + (checkConsistency != null ? checkConsistency.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessAccountJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessAccountJson.java
new file mode 100644
index 0000000..85d1112
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessAccountJson.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2010-2012 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.jaxrs.json;
+
+import java.math.BigDecimal;
+
+import org.joda.time.LocalDate;
+
+import com.ning.billing.analytics.api.BusinessAccount;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class BusinessAccountJson extends JsonBase {
+
+    private final String externalKey;
+    private final String name;
+    private final String currency;
+    private final BigDecimal balance;
+    private final LocalDate lastInvoiceDate;
+    private final BigDecimal totalInvoiceBalance;
+    private final String lastPaymentStatus;
+    private final String defaultPaymentMethodType;
+    private final String defaultCreditCardType;
+    private final String defaultBillingAddressCountry;
+
+    @JsonCreator
+    public BusinessAccountJson(@JsonProperty("externalKey") final String externalKey,
+                               @JsonProperty("name") final String name,
+                               @JsonProperty("currency") final String currency,
+                               @JsonProperty("balance") final BigDecimal balance,
+                               @JsonProperty("lastInvoiceDate") final LocalDate lastInvoiceDate,
+                               @JsonProperty("totalInvoiceBalance") final BigDecimal totalInvoiceBalance,
+                               @JsonProperty("lastPaymentStatus") final String lastPaymentStatus,
+                               @JsonProperty("defaultPaymentMethodType") final String defaultPaymentMethodType,
+                               @JsonProperty("defaultCreditCardType") final String defaultCreditCardType,
+                               @JsonProperty("defaultBillingAddressCountry") final String defaultBillingAddressCountry) {
+        this.externalKey = externalKey;
+        this.name = name;
+        this.currency = currency;
+        this.balance = balance;
+        this.lastInvoiceDate = lastInvoiceDate;
+        this.totalInvoiceBalance = totalInvoiceBalance;
+        this.lastPaymentStatus = lastPaymentStatus;
+        this.defaultPaymentMethodType = defaultPaymentMethodType;
+        this.defaultCreditCardType = defaultCreditCardType;
+        this.defaultBillingAddressCountry = defaultBillingAddressCountry;
+    }
+
+    public BusinessAccountJson(final BusinessAccount businessAccount) {
+        this(businessAccount.getExternalKey(),
+             businessAccount.getName(),
+             businessAccount.getCurrency(),
+             businessAccount.getBalance(),
+             businessAccount.getLastInvoiceDate(),
+             businessAccount.getTotalInvoiceBalance(),
+             businessAccount.getLastPaymentStatus(),
+             businessAccount.getDefaultPaymentMethodType(),
+             businessAccount.getDefaultCreditCardType(),
+             businessAccount.getDefaultBillingAddressCountry());
+    }
+
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public BigDecimal getBalance() {
+        return balance;
+    }
+
+    public LocalDate getLastInvoiceDate() {
+        return lastInvoiceDate;
+    }
+
+    public BigDecimal getTotalInvoiceBalance() {
+        return totalInvoiceBalance;
+    }
+
+    public String getLastPaymentStatus() {
+        return lastPaymentStatus;
+    }
+
+    public String getDefaultPaymentMethodType() {
+        return defaultPaymentMethodType;
+    }
+
+    public String getDefaultCreditCardType() {
+        return defaultCreditCardType;
+    }
+
+    public String getDefaultBillingAddressCountry() {
+        return defaultBillingAddressCountry;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessAccountJson");
+        sb.append("{externalKey='").append(externalKey).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append(", currency='").append(currency).append('\'');
+        sb.append(", balance=").append(balance);
+        sb.append(", lastInvoiceDate=").append(lastInvoiceDate);
+        sb.append(", totalInvoiceBalance=").append(totalInvoiceBalance);
+        sb.append(", lastPaymentStatus='").append(lastPaymentStatus).append('\'');
+        sb.append(", defaultPaymentMethodType='").append(defaultPaymentMethodType).append('\'');
+        sb.append(", defaultCreditCardType='").append(defaultCreditCardType).append('\'');
+        sb.append(", defaultBillingAddressCountry='").append(defaultBillingAddressCountry).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessAccountJson that = (BusinessAccountJson) o;
+
+        if (balance != null ? !balance.equals(that.balance) : that.balance != null) {
+            return false;
+        }
+        if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
+            return false;
+        }
+        if (defaultBillingAddressCountry != null ? !defaultBillingAddressCountry.equals(that.defaultBillingAddressCountry) : that.defaultBillingAddressCountry != null) {
+            return false;
+        }
+        if (defaultCreditCardType != null ? !defaultCreditCardType.equals(that.defaultCreditCardType) : that.defaultCreditCardType != null) {
+            return false;
+        }
+        if (defaultPaymentMethodType != null ? !defaultPaymentMethodType.equals(that.defaultPaymentMethodType) : that.defaultPaymentMethodType != null) {
+            return false;
+        }
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+            return false;
+        }
+        if (lastInvoiceDate != null ? !lastInvoiceDate.equals(that.lastInvoiceDate) : that.lastInvoiceDate != null) {
+            return false;
+        }
+        if (lastPaymentStatus != null ? !lastPaymentStatus.equals(that.lastPaymentStatus) : that.lastPaymentStatus != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        if (totalInvoiceBalance != null ? !totalInvoiceBalance.equals(that.totalInvoiceBalance) : that.totalInvoiceBalance != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = externalKey != null ? externalKey.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (balance != null ? balance.hashCode() : 0);
+        result = 31 * result + (lastInvoiceDate != null ? lastInvoiceDate.hashCode() : 0);
+        result = 31 * result + (totalInvoiceBalance != null ? totalInvoiceBalance.hashCode() : 0);
+        result = 31 * result + (lastPaymentStatus != null ? lastPaymentStatus.hashCode() : 0);
+        result = 31 * result + (defaultPaymentMethodType != null ? defaultPaymentMethodType.hashCode() : 0);
+        result = 31 * result + (defaultCreditCardType != null ? defaultCreditCardType.hashCode() : 0);
+        result = 31 * result + (defaultBillingAddressCountry != null ? defaultBillingAddressCountry.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessFieldJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessFieldJson.java
new file mode 100644
index 0000000..2a2e2ee
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessFieldJson.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2010-2012 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.jaxrs.json;
+
+import com.ning.billing.analytics.api.BusinessField;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class BusinessFieldJson extends JsonBase {
+
+    private final String objectType;
+    private final String id;
+    private final String name;
+    private final String value;
+
+    @JsonCreator
+    public BusinessFieldJson(@JsonProperty("objectType") final String objectType,
+                             @JsonProperty("id") final String id,
+                             @JsonProperty("name") final String name,
+                             @JsonProperty("value") final String value) {
+        this.objectType = objectType;
+        this.id = id;
+        this.name = name;
+        this.value = value;
+    }
+
+    public BusinessFieldJson(final BusinessField businessField) {
+        this(businessField.getObjectType().toString(),
+             businessField.getId().toString(),
+             businessField.getName(),
+             businessField.getValue());
+    }
+
+    public String getObjectType() {
+        return objectType;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessFieldJson");
+        sb.append("{objectType='").append(objectType).append('\'');
+        sb.append(", id='").append(id).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append(", value='").append(value).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessFieldJson that = (BusinessFieldJson) o;
+
+        if (id != null ? !id.equals(that.id) : that.id != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        if (objectType != null ? !objectType.equals(that.objectType) : that.objectType != null) {
+            return false;
+        }
+        if (value != null ? !value.equals(that.value) : that.value != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = objectType != null ? objectType.hashCode() : 0;
+        result = 31 * result + (id != null ? id.hashCode() : 0);
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (value != null ? value.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessInvoiceJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessInvoiceJson.java
new file mode 100644
index 0000000..5b554eb
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessInvoiceJson.java
@@ -0,0 +1,464 @@
+/*
+ * Copyright 2010-2012 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.jaxrs.json;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.LocalDate;
+
+import com.ning.billing.analytics.api.BusinessInvoice;
+import com.ning.billing.analytics.api.BusinessInvoice.BusinessInvoiceItem;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+
+public class BusinessInvoiceJson extends JsonBase {
+
+    private final String invoiceId;
+    private final Integer invoiceNumber;
+    private final String accountId;
+    private final String accountKey;
+    private final LocalDate invoiceDate;
+    private final LocalDate targetDate;
+    private final String currency;
+    private final BigDecimal balance;
+    private final BigDecimal amountPaid;
+    private final BigDecimal amountCharged;
+    private final BigDecimal amountCredited;
+    private final List<BusinessInvoiceItemJson> invoiceItems;
+
+    @JsonCreator
+    public BusinessInvoiceJson(@JsonProperty("invoiceId") final String invoiceId,
+                               @JsonProperty("invoiceNumber") final Integer invoiceNumber,
+                               @JsonProperty("accountId") final String accountId,
+                               @JsonProperty("accountKey") final String accountKey,
+                               @JsonProperty("invoiceDate") final LocalDate invoiceDate,
+                               @JsonProperty("targetDate") final LocalDate targetDate,
+                               @JsonProperty("currency") final String currency,
+                               @JsonProperty("balance") final BigDecimal balance,
+                               @JsonProperty("amountPaid") final BigDecimal amountPaid,
+                               @JsonProperty("amountCharged") final BigDecimal amountCharged,
+                               @JsonProperty("amountCredited") final BigDecimal amountCredited,
+                               @JsonProperty("invoiceItems") final List<BusinessInvoiceItemJson> invoiceItems) {
+        this.invoiceId = invoiceId;
+        this.invoiceNumber = invoiceNumber;
+        this.accountId = accountId;
+        this.accountKey = accountKey;
+        this.invoiceDate = invoiceDate;
+        this.targetDate = targetDate;
+        this.currency = currency;
+        this.balance = balance;
+        this.amountPaid = amountPaid;
+        this.amountCharged = amountCharged;
+        this.amountCredited = amountCredited;
+        this.invoiceItems = invoiceItems;
+    }
+
+    public BusinessInvoiceJson(final BusinessInvoice businessInvoice) {
+        this.invoiceId = businessInvoice.getInvoiceId().toString();
+        this.invoiceNumber = businessInvoice.getInvoiceNumber();
+        this.accountId = businessInvoice.getAccountId().toString();
+        this.accountKey = businessInvoice.getAccountKey();
+        this.invoiceDate = businessInvoice.getInvoiceDate();
+        this.targetDate = businessInvoice.getTargetDate();
+        this.currency = businessInvoice.getCurrency().toString();
+        this.balance = businessInvoice.getBalance();
+        this.amountPaid = businessInvoice.getAmountPaid();
+        this.amountCharged = businessInvoice.getAmountCharged();
+        this.amountCredited = businessInvoice.getAmountCredited();
+        this.invoiceItems = ImmutableList.<BusinessInvoiceItemJson>copyOf(Collections2.transform(businessInvoice.getInvoiceItems(), new Function<BusinessInvoiceItem, BusinessInvoiceItemJson>() {
+            @Override
+            public BusinessInvoiceItemJson apply(@Nullable final BusinessInvoiceItem input) {
+                return new BusinessInvoiceItemJson(input);
+            }
+        }));
+    }
+
+    public static class BusinessInvoiceItemJson extends JsonBase {
+
+        private final String itemId;
+        private final String invoiceId;
+        private final String itemType;
+        private final String externalKey;
+        private final String productName;
+        private final String productType;
+        private final String productCategory;
+        private final String slug;
+        private final String phase;
+        private final String billingPeriod;
+        private final LocalDate startDate;
+        private final LocalDate endDate;
+        private final BigDecimal amount;
+        private final String currency;
+        private final String linkedItemId;
+
+        private BusinessInvoiceItemJson(@JsonProperty("itemId") final String itemId,
+                                        @JsonProperty("invoiceId") final String invoiceId,
+                                        @JsonProperty("itemType") final String itemType,
+                                        @JsonProperty("externalKey") final String externalKey,
+                                        @JsonProperty("productName") final String productName,
+                                        @JsonProperty("productType") final String productType,
+                                        @JsonProperty("productCategory") final String productCategory,
+                                        @JsonProperty("slug") final String slug,
+                                        @JsonProperty("phase") final String phase,
+                                        @JsonProperty("billingPeriod") final String billingPeriod,
+                                        @JsonProperty("startDate") final LocalDate startDate,
+                                        @JsonProperty("endDate") final LocalDate endDate,
+                                        @JsonProperty("amount") final BigDecimal amount,
+                                        @JsonProperty("currency") final String currency,
+                                        @JsonProperty("linkedItemId") final String linkedItemId) {
+            this.itemId = itemId;
+            this.invoiceId = invoiceId;
+            this.itemType = itemType;
+            this.externalKey = externalKey;
+            this.productName = productName;
+            this.productType = productType;
+            this.productCategory = productCategory;
+            this.slug = slug;
+            this.phase = phase;
+            this.billingPeriod = billingPeriod;
+            this.startDate = startDate;
+            this.endDate = endDate;
+            this.amount = amount;
+            this.currency = currency;
+            this.linkedItemId = linkedItemId;
+        }
+
+        public BusinessInvoiceItemJson(final BusinessInvoiceItem businessInvoiceItem) {
+            this(businessInvoiceItem.getItemId().toString(),
+                 businessInvoiceItem.getInvoiceId().toString(),
+                 businessInvoiceItem.getItemType().toLowerCase(),
+                 businessInvoiceItem.getExternalKey(),
+                 businessInvoiceItem.getProductName(),
+                 businessInvoiceItem.getProductType(),
+                 businessInvoiceItem.getProductCategory(),
+                 businessInvoiceItem.getSlug(),
+                 businessInvoiceItem.getPhase(),
+                 businessInvoiceItem.getBillingPeriod(),
+                 businessInvoiceItem.getStartDate(),
+                 businessInvoiceItem.getEndDate(),
+                 businessInvoiceItem.getAmount(),
+                 businessInvoiceItem.getCurrency().toString(),
+                 businessInvoiceItem.getLinkedItemId() == null ? null : businessInvoiceItem.getLinkedItemId().toString());
+        }
+
+        public String getItemId() {
+            return itemId;
+        }
+
+        public String getInvoiceId() {
+            return invoiceId;
+        }
+
+        public String getItemType() {
+            return itemType;
+        }
+
+        public String getExternalKey() {
+            return externalKey;
+        }
+
+        public String getProductName() {
+            return productName;
+        }
+
+        public String getProductType() {
+            return productType;
+        }
+
+        public String getProductCategory() {
+            return productCategory;
+        }
+
+        public String getSlug() {
+            return slug;
+        }
+
+        public String getPhase() {
+            return phase;
+        }
+
+        public String getBillingPeriod() {
+            return billingPeriod;
+        }
+
+        public LocalDate getStartDate() {
+            return startDate;
+        }
+
+        public LocalDate getEndDate() {
+            return endDate;
+        }
+
+        public BigDecimal getAmount() {
+            return amount;
+        }
+
+        public String getCurrency() {
+            return currency;
+        }
+
+        public String getLinkedItemId() {
+            return linkedItemId;
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder sb = new StringBuilder();
+            sb.append("BusinessInvoiceItemJson");
+            sb.append("{itemId='").append(itemId).append('\'');
+            sb.append(", invoiceId='").append(invoiceId).append('\'');
+            sb.append(", itemType='").append(itemType).append('\'');
+            sb.append(", externalKey='").append(externalKey).append('\'');
+            sb.append(", productName='").append(productName).append('\'');
+            sb.append(", productType='").append(productType).append('\'');
+            sb.append(", productCategory='").append(productCategory).append('\'');
+            sb.append(", slug='").append(slug).append('\'');
+            sb.append(", phase='").append(phase).append('\'');
+            sb.append(", billingPeriod='").append(billingPeriod).append('\'');
+            sb.append(", startDate=").append(startDate);
+            sb.append(", endDate=").append(endDate);
+            sb.append(", amount=").append(amount);
+            sb.append(", currency='").append(currency).append('\'');
+            sb.append(", linkedItemId='").append(linkedItemId).append('\'');
+            sb.append('}');
+            return sb.toString();
+        }
+
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            final BusinessInvoiceItemJson that = (BusinessInvoiceItemJson) o;
+
+            if (amount != null ? !amount.equals(that.amount) : that.amount != null) {
+                return false;
+            }
+            if (billingPeriod != null ? !billingPeriod.equals(that.billingPeriod) : that.billingPeriod != null) {
+                return false;
+            }
+            if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
+                return false;
+            }
+            if (endDate != null ? !endDate.equals(that.endDate) : that.endDate != null) {
+                return false;
+            }
+            if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+                return false;
+            }
+            if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
+                return false;
+            }
+            if (itemId != null ? !itemId.equals(that.itemId) : that.itemId != null) {
+                return false;
+            }
+            if (itemType != null ? !itemType.equals(that.itemType) : that.itemType != null) {
+                return false;
+            }
+            if (linkedItemId != null ? !linkedItemId.equals(that.linkedItemId) : that.linkedItemId != null) {
+                return false;
+            }
+            if (phase != null ? !phase.equals(that.phase) : that.phase != null) {
+                return false;
+            }
+            if (productCategory != null ? !productCategory.equals(that.productCategory) : that.productCategory != null) {
+                return false;
+            }
+            if (productName != null ? !productName.equals(that.productName) : that.productName != null) {
+                return false;
+            }
+            if (productType != null ? !productType.equals(that.productType) : that.productType != null) {
+                return false;
+            }
+            if (slug != null ? !slug.equals(that.slug) : that.slug != null) {
+                return false;
+            }
+            if (startDate != null ? !startDate.equals(that.startDate) : that.startDate != null) {
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = itemId != null ? itemId.hashCode() : 0;
+            result = 31 * result + (invoiceId != null ? invoiceId.hashCode() : 0);
+            result = 31 * result + (itemType != null ? itemType.hashCode() : 0);
+            result = 31 * result + (externalKey != null ? externalKey.hashCode() : 0);
+            result = 31 * result + (productName != null ? productName.hashCode() : 0);
+            result = 31 * result + (productType != null ? productType.hashCode() : 0);
+            result = 31 * result + (productCategory != null ? productCategory.hashCode() : 0);
+            result = 31 * result + (slug != null ? slug.hashCode() : 0);
+            result = 31 * result + (phase != null ? phase.hashCode() : 0);
+            result = 31 * result + (billingPeriod != null ? billingPeriod.hashCode() : 0);
+            result = 31 * result + (startDate != null ? startDate.hashCode() : 0);
+            result = 31 * result + (endDate != null ? endDate.hashCode() : 0);
+            result = 31 * result + (amount != null ? amount.hashCode() : 0);
+            result = 31 * result + (currency != null ? currency.hashCode() : 0);
+            result = 31 * result + (linkedItemId != null ? linkedItemId.hashCode() : 0);
+            return result;
+        }
+    }
+
+    public String getInvoiceId() {
+        return invoiceId;
+    }
+
+    public Integer getInvoiceNumber() {
+        return invoiceNumber;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    public LocalDate getInvoiceDate() {
+        return invoiceDate;
+    }
+
+    public LocalDate getTargetDate() {
+        return targetDate;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public BigDecimal getBalance() {
+        return balance;
+    }
+
+    public BigDecimal getAmountPaid() {
+        return amountPaid;
+    }
+
+    public BigDecimal getAmountCharged() {
+        return amountCharged;
+    }
+
+    public BigDecimal getAmountCredited() {
+        return amountCredited;
+    }
+
+    public List<BusinessInvoiceItemJson> getInvoiceItems() {
+        return invoiceItems;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessInvoiceJson");
+        sb.append("{invoiceId='").append(invoiceId).append('\'');
+        sb.append(", invoiceNumber=").append(invoiceNumber);
+        sb.append(", accountId='").append(accountId).append('\'');
+        sb.append(", accountKey='").append(accountKey).append('\'');
+        sb.append(", invoiceDate=").append(invoiceDate);
+        sb.append(", targetDate=").append(targetDate);
+        sb.append(", currency='").append(currency).append('\'');
+        sb.append(", balance=").append(balance);
+        sb.append(", amountPaid=").append(amountPaid);
+        sb.append(", amountCharged=").append(amountCharged);
+        sb.append(", amountCredited=").append(amountCredited);
+        sb.append(", invoiceItems=").append(invoiceItems);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessInvoiceJson that = (BusinessInvoiceJson) o;
+
+        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+            return false;
+        }
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (amountCharged != null ? !amountCharged.equals(that.amountCharged) : that.amountCharged != null) {
+            return false;
+        }
+        if (amountCredited != null ? !amountCredited.equals(that.amountCredited) : that.amountCredited != null) {
+            return false;
+        }
+        if (amountPaid != null ? !amountPaid.equals(that.amountPaid) : that.amountPaid != null) {
+            return false;
+        }
+        if (balance != null ? !balance.equals(that.balance) : that.balance != null) {
+            return false;
+        }
+        if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
+            return false;
+        }
+        if (invoiceDate != null ? !invoiceDate.equals(that.invoiceDate) : that.invoiceDate != null) {
+            return false;
+        }
+        if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
+            return false;
+        }
+        if (invoiceItems != null ? !invoiceItems.equals(that.invoiceItems) : that.invoiceItems != null) {
+            return false;
+        }
+        if (invoiceNumber != null ? !invoiceNumber.equals(that.invoiceNumber) : that.invoiceNumber != null) {
+            return false;
+        }
+        if (targetDate != null ? !targetDate.equals(that.targetDate) : that.targetDate != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = invoiceId != null ? invoiceId.hashCode() : 0;
+        result = 31 * result + (invoiceNumber != null ? invoiceNumber.hashCode() : 0);
+        result = 31 * result + (accountId != null ? accountId.hashCode() : 0);
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
+        result = 31 * result + (invoiceDate != null ? invoiceDate.hashCode() : 0);
+        result = 31 * result + (targetDate != null ? targetDate.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (balance != null ? balance.hashCode() : 0);
+        result = 31 * result + (amountPaid != null ? amountPaid.hashCode() : 0);
+        result = 31 * result + (amountCharged != null ? amountCharged.hashCode() : 0);
+        result = 31 * result + (amountCredited != null ? amountCredited.hashCode() : 0);
+        result = 31 * result + (invoiceItems != null ? invoiceItems.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessInvoicePaymentJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessInvoicePaymentJson.java
new file mode 100644
index 0000000..9fa8310
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessInvoicePaymentJson.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2010-2012 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.jaxrs.json;
+
+import java.math.BigDecimal;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.analytics.api.BusinessInvoicePayment;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class BusinessInvoicePaymentJson extends JsonBase {
+
+    private final String paymentId;
+    private final String extFirstPaymentRefId;
+    private final String extSecondPaymentRefId;
+    private final String accountKey;
+    private final String invoiceId;
+    private final Integer invoiceNumber;
+    private final DateTime effectiveDate;
+    private final BigDecimal amount;
+    private final String currency;
+    private final String paymentError;
+    private final String processingStatus;
+    private final BigDecimal requestedAmount;
+    private final String pluginName;
+    private final String paymentType;
+    private final String paymentMethod;
+    private final String cardType;
+    private final String cardCountry;
+    private final String invoicePaymentType;
+    private final String linkedInvoicePaymentId;
+
+    @JsonCreator
+    public BusinessInvoicePaymentJson(@JsonProperty("paymentId") final String paymentId,
+                                      @JsonProperty("extFirstPaymentRefId") final String extFirstPaymentRefId,
+                                      @JsonProperty("extSecondPaymentRefId") final String extSecondPaymentRefId,
+                                      @JsonProperty("accountKey") final String accountKey,
+                                      @JsonProperty("invoiceId") final String invoiceId,
+                                      @JsonProperty("invoiceNumber") final Integer invoiceNumber,
+                                      @JsonProperty("effectiveDate") final DateTime effectiveDate,
+                                      @JsonProperty("amount") final BigDecimal amount,
+                                      @JsonProperty("currency") final String currency,
+                                      @JsonProperty("paymentError") final String paymentError,
+                                      @JsonProperty("processingStatus") final String processingStatus,
+                                      @JsonProperty("requestedAmount") final BigDecimal requestedAmount,
+                                      @JsonProperty("pluginName") final String pluginName,
+                                      @JsonProperty("paymentType") final String paymentType,
+                                      @JsonProperty("paymentMethod") final String paymentMethod,
+                                      @JsonProperty("cardType") final String cardType,
+                                      @JsonProperty("cardCountry") final String cardCountry,
+                                      @JsonProperty("invoicePaymentType") final String invoicePaymentType,
+                                      @JsonProperty("linkedInvoicePaymentId") final String linkedInvoicePaymentId) {
+        this.paymentId = paymentId;
+        this.extFirstPaymentRefId = extFirstPaymentRefId;
+        this.extSecondPaymentRefId = extSecondPaymentRefId;
+        this.accountKey = accountKey;
+        this.invoiceId = invoiceId;
+        this.invoiceNumber = invoiceNumber;
+        this.effectiveDate = effectiveDate;
+        this.amount = amount;
+        this.currency = currency;
+        this.paymentError = paymentError;
+        this.processingStatus = processingStatus;
+        this.requestedAmount = requestedAmount;
+        this.pluginName = pluginName;
+        this.paymentType = paymentType;
+        this.paymentMethod = paymentMethod;
+        this.cardType = cardType;
+        this.cardCountry = cardCountry;
+        this.invoicePaymentType = invoicePaymentType;
+        this.linkedInvoicePaymentId = linkedInvoicePaymentId;
+    }
+
+    public BusinessInvoicePaymentJson(final BusinessInvoicePayment businessInvoicePayment, final Integer invoiceNumber) {
+        // The bip table doesn't contain the invoice number, but we export it in here for convenience
+        this(businessInvoicePayment.getPaymentId().toString(),
+             businessInvoicePayment.getExtFirstPaymentRefId(),
+             businessInvoicePayment.getExtSecondPaymentRefId(),
+             businessInvoicePayment.getAccountKey(),
+             businessInvoicePayment.getInvoiceId().toString(),
+             invoiceNumber,
+             businessInvoicePayment.getEffectiveDate(),
+             businessInvoicePayment.getAmount(),
+             businessInvoicePayment.getCurrency().toString(),
+             businessInvoicePayment.getPaymentError(),
+             businessInvoicePayment.getProcessingStatus(),
+             businessInvoicePayment.getRequestedAmount(),
+             businessInvoicePayment.getPluginName(),
+             businessInvoicePayment.getPaymentType(),
+             businessInvoicePayment.getPaymentMethod(),
+             businessInvoicePayment.getCardType(),
+             businessInvoicePayment.getCardCountry(),
+             businessInvoicePayment.getInvoicePaymentType(),
+             businessInvoicePayment.getLinkedInvoicePaymentId() == null ? null : businessInvoicePayment.getLinkedInvoicePaymentId().toString());
+    }
+
+    public String getPaymentId() {
+        return paymentId;
+    }
+
+    public String getExtFirstPaymentRefId() {
+        return extFirstPaymentRefId;
+    }
+
+    public String getExtSecondPaymentRefId() {
+        return extSecondPaymentRefId;
+    }
+
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    public String getInvoiceId() {
+        return invoiceId;
+    }
+
+    public Integer getInvoiceNumber() {
+        return invoiceNumber;
+    }
+
+    public DateTime getEffectiveDate() {
+        return effectiveDate;
+    }
+
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public String getPaymentError() {
+        return paymentError;
+    }
+
+    public String getProcessingStatus() {
+        return processingStatus;
+    }
+
+    public BigDecimal getRequestedAmount() {
+        return requestedAmount;
+    }
+
+    public String getPluginName() {
+        return pluginName;
+    }
+
+    public String getPaymentType() {
+        return paymentType;
+    }
+
+    public String getPaymentMethod() {
+        return paymentMethod;
+    }
+
+    public String getCardType() {
+        return cardType;
+    }
+
+    public String getCardCountry() {
+        return cardCountry;
+    }
+
+    public String getInvoicePaymentType() {
+        return invoicePaymentType;
+    }
+
+    public String getLinkedInvoicePaymentId() {
+        return linkedInvoicePaymentId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessInvoicePaymentJson");
+        sb.append("{paymentId='").append(paymentId).append('\'');
+        sb.append(", extFirstPaymentRefId='").append(extFirstPaymentRefId).append('\'');
+        sb.append(", extSecondPaymentRefId='").append(extSecondPaymentRefId).append('\'');
+        sb.append(", accountKey='").append(accountKey).append('\'');
+        sb.append(", invoiceId='").append(invoiceId).append('\'');
+        sb.append(", invoiceNumber='").append(invoiceNumber).append('\'');
+        sb.append(", effectiveDate=").append(effectiveDate);
+        sb.append(", amount=").append(amount);
+        sb.append(", currency='").append(currency).append('\'');
+        sb.append(", paymentError='").append(paymentError).append('\'');
+        sb.append(", processingStatus='").append(processingStatus).append('\'');
+        sb.append(", requestedAmount=").append(requestedAmount);
+        sb.append(", pluginName='").append(pluginName).append('\'');
+        sb.append(", paymentType='").append(paymentType).append('\'');
+        sb.append(", paymentMethod='").append(paymentMethod).append('\'');
+        sb.append(", cardType='").append(cardType).append('\'');
+        sb.append(", cardCountry='").append(cardCountry).append('\'');
+        sb.append(", invoicePaymentType='").append(invoicePaymentType).append('\'');
+        sb.append(", linkedInvoicePaymentId='").append(linkedInvoicePaymentId).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessInvoicePaymentJson that = (BusinessInvoicePaymentJson) o;
+
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (amount != null ? !amount.equals(that.amount) : that.amount != null) {
+            return false;
+        }
+        if (cardCountry != null ? !cardCountry.equals(that.cardCountry) : that.cardCountry != null) {
+            return false;
+        }
+        if (cardType != null ? !cardType.equals(that.cardType) : that.cardType != null) {
+            return false;
+        }
+        if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
+            return false;
+        }
+        if (effectiveDate != null ? !effectiveDate.equals(that.effectiveDate) : that.effectiveDate != null) {
+            return false;
+        }
+        if (extFirstPaymentRefId != null ? !extFirstPaymentRefId.equals(that.extFirstPaymentRefId) : that.extFirstPaymentRefId != null) {
+            return false;
+        }
+        if (extSecondPaymentRefId != null ? !extSecondPaymentRefId.equals(that.extSecondPaymentRefId) : that.extSecondPaymentRefId != null) {
+            return false;
+        }
+        if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
+            return false;
+        }
+        if (invoiceNumber != null ? !invoiceNumber.equals(that.invoiceNumber) : that.invoiceNumber != null) {
+            return false;
+        }
+        if (invoicePaymentType != null ? !invoicePaymentType.equals(that.invoicePaymentType) : that.invoicePaymentType != null) {
+            return false;
+        }
+        if (linkedInvoicePaymentId != null ? !linkedInvoicePaymentId.equals(that.linkedInvoicePaymentId) : that.linkedInvoicePaymentId != null) {
+            return false;
+        }
+        if (paymentError != null ? !paymentError.equals(that.paymentError) : that.paymentError != null) {
+            return false;
+        }
+        if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
+            return false;
+        }
+        if (paymentMethod != null ? !paymentMethod.equals(that.paymentMethod) : that.paymentMethod != null) {
+            return false;
+        }
+        if (paymentType != null ? !paymentType.equals(that.paymentType) : that.paymentType != null) {
+            return false;
+        }
+        if (pluginName != null ? !pluginName.equals(that.pluginName) : that.pluginName != null) {
+            return false;
+        }
+        if (processingStatus != null ? !processingStatus.equals(that.processingStatus) : that.processingStatus != null) {
+            return false;
+        }
+        if (requestedAmount != null ? !requestedAmount.equals(that.requestedAmount) : that.requestedAmount != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = paymentId != null ? paymentId.hashCode() : 0;
+        result = 31 * result + (extFirstPaymentRefId != null ? extFirstPaymentRefId.hashCode() : 0);
+        result = 31 * result + (extSecondPaymentRefId != null ? extSecondPaymentRefId.hashCode() : 0);
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
+        result = 31 * result + (invoiceId != null ? invoiceId.hashCode() : 0);
+        result = 31 * result + (invoiceNumber != null ? invoiceNumber.hashCode() : 0);
+        result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
+        result = 31 * result + (amount != null ? amount.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (paymentError != null ? paymentError.hashCode() : 0);
+        result = 31 * result + (processingStatus != null ? processingStatus.hashCode() : 0);
+        result = 31 * result + (requestedAmount != null ? requestedAmount.hashCode() : 0);
+        result = 31 * result + (pluginName != null ? pluginName.hashCode() : 0);
+        result = 31 * result + (paymentType != null ? paymentType.hashCode() : 0);
+        result = 31 * result + (paymentMethod != null ? paymentMethod.hashCode() : 0);
+        result = 31 * result + (cardType != null ? cardType.hashCode() : 0);
+        result = 31 * result + (cardCountry != null ? cardCountry.hashCode() : 0);
+        result = 31 * result + (invoicePaymentType != null ? invoicePaymentType.hashCode() : 0);
+        result = 31 * result + (linkedInvoicePaymentId != null ? linkedInvoicePaymentId.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessOverdueStatusJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessOverdueStatusJson.java
new file mode 100644
index 0000000..6a8f805
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessOverdueStatusJson.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2010-2012 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.jaxrs.json;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.analytics.api.BusinessOverdueStatus;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class BusinessOverdueStatusJson extends JsonBase {
+
+    private final String objectType;
+    private final String id;
+    private final String accountKey;
+    private final String status;
+    private final DateTime startDate;
+    private final DateTime endDate;
+
+    @JsonCreator
+    public BusinessOverdueStatusJson(@JsonProperty("objectType") final String objectType,
+                                     @JsonProperty("id") final String id,
+                                     @JsonProperty("accountKey") final String accountKey,
+                                     @JsonProperty("status") final String status,
+                                     @JsonProperty("startDate") final DateTime startDate,
+                                     @JsonProperty("endDate") final DateTime endDate) {
+        this.objectType = objectType;
+        this.id = id;
+        this.accountKey = accountKey;
+        this.status = status;
+        this.startDate = startDate;
+        this.endDate = endDate;
+    }
+
+    public BusinessOverdueStatusJson(final BusinessOverdueStatus businessOverdueStatus) {
+        this(businessOverdueStatus.getObjectType().toString(),
+             businessOverdueStatus.getId().toString(),
+             businessOverdueStatus.getAccountKey(),
+             businessOverdueStatus.getStatus(),
+             businessOverdueStatus.getStartDate(),
+             businessOverdueStatus.getEndDate());
+    }
+
+    public String getObjectType() {
+        return objectType;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public DateTime getStartDate() {
+        return startDate;
+    }
+
+    public DateTime getEndDate() {
+        return endDate;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessOverdueStatusJson");
+        sb.append("{objectType='").append(objectType).append('\'');
+        sb.append(", id='").append(id).append('\'');
+        sb.append(", accountKey='").append(accountKey).append('\'');
+        sb.append(", status='").append(status).append('\'');
+        sb.append(", startDate=").append(startDate);
+        sb.append(", endDate=").append(endDate);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessOverdueStatusJson that = (BusinessOverdueStatusJson) o;
+
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (endDate != null ? !endDate.equals(that.endDate) : that.endDate != null) {
+            return false;
+        }
+        if (id != null ? !id.equals(that.id) : that.id != null) {
+            return false;
+        }
+        if (objectType != null ? !objectType.equals(that.objectType) : that.objectType != null) {
+            return false;
+        }
+        if (startDate != null ? !startDate.equals(that.startDate) : that.startDate != null) {
+            return false;
+        }
+        if (status != null ? !status.equals(that.status) : that.status != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = objectType != null ? objectType.hashCode() : 0;
+        result = 31 * result + (id != null ? id.hashCode() : 0);
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
+        result = 31 * result + (status != null ? status.hashCode() : 0);
+        result = 31 * result + (startDate != null ? startDate.hashCode() : 0);
+        result = 31 * result + (endDate != null ? endDate.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessSnapshotJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessSnapshotJson.java
new file mode 100644
index 0000000..dcac483
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessSnapshotJson.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2010-2012 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.jaxrs.json;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import com.ning.billing.analytics.api.BusinessField;
+import com.ning.billing.analytics.api.BusinessInvoice;
+import com.ning.billing.analytics.api.BusinessInvoicePayment;
+import com.ning.billing.analytics.api.BusinessOverdueStatus;
+import com.ning.billing.analytics.api.BusinessSnapshot;
+import com.ning.billing.analytics.api.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.api.BusinessTag;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+
+public class BusinessSnapshotJson extends JsonBase {
+
+    private final BusinessAccountJson businessAccount;
+    private final Collection<BusinessSubscriptionTransitionJson> businessSubscriptionTransitions;
+    private final Collection<BusinessInvoiceJson> businessInvoices;
+    private final Collection<BusinessInvoicePaymentJson> businessInvoicePayments;
+    private final Collection<BusinessOverdueStatusJson> businessOverdueStatuses;
+    private final Collection<BusinessTagJson> businessTags;
+    private final Collection<BusinessFieldJson> businessFields;
+
+    @JsonCreator
+    public BusinessSnapshotJson(@JsonProperty("businessAccount") final BusinessAccountJson businessAccount,
+                                @JsonProperty("businessSubscriptionTransitions") final Collection<BusinessSubscriptionTransitionJson> businessSubscriptionTransitions,
+                                @JsonProperty("businessInvoices") final Collection<BusinessInvoiceJson> businessInvoices,
+                                @JsonProperty("businessInvoicePayments") final Collection<BusinessInvoicePaymentJson> businessInvoicePayments,
+                                @JsonProperty("businessOverdueStatuses") final Collection<BusinessOverdueStatusJson> businessOverdueStatuses,
+                                @JsonProperty("businessTags") final Collection<BusinessTagJson> businessTags,
+                                @JsonProperty("businessFields") final Collection<BusinessFieldJson> businessFields) {
+        this.businessAccount = businessAccount;
+        this.businessSubscriptionTransitions = businessSubscriptionTransitions;
+        this.businessInvoices = businessInvoices;
+        this.businessInvoicePayments = businessInvoicePayments;
+        this.businessOverdueStatuses = businessOverdueStatuses;
+        this.businessTags = businessTags;
+        this.businessFields = businessFields;
+    }
+
+    public BusinessSnapshotJson(final BusinessSnapshot businessSnapshot) {
+        final Map<UUID, Integer> invoiceIdToNumber = new HashMap<UUID, Integer>();
+
+        this.businessAccount = new BusinessAccountJson(businessSnapshot.getBusinessAccount());
+        this.businessSubscriptionTransitions = ImmutableList.<BusinessSubscriptionTransitionJson>copyOf(Collections2.transform(businessSnapshot.getBusinessSubscriptionTransitions(), new Function<BusinessSubscriptionTransition, BusinessSubscriptionTransitionJson>() {
+            @Override
+            public BusinessSubscriptionTransitionJson apply(@Nullable final BusinessSubscriptionTransition input) {
+                return new BusinessSubscriptionTransitionJson(input);
+            }
+        }));
+        this.businessInvoices = ImmutableList.<BusinessInvoiceJson>copyOf(Collections2.transform(businessSnapshot.getBusinessInvoices(), new Function<BusinessInvoice, BusinessInvoiceJson>() {
+            @Override
+            public BusinessInvoiceJson apply(final BusinessInvoice input) {
+                invoiceIdToNumber.put(input.getInvoiceId(), input.getInvoiceNumber());
+                return new BusinessInvoiceJson(input);
+            }
+        }));
+        this.businessInvoicePayments = ImmutableList.<BusinessInvoicePaymentJson>copyOf(Collections2.transform(businessSnapshot.getBusinessInvoicePayments(), new Function<BusinessInvoicePayment, BusinessInvoicePaymentJson>() {
+            @Override
+            public BusinessInvoicePaymentJson apply(final BusinessInvoicePayment input) {
+                return new BusinessInvoicePaymentJson(input, invoiceIdToNumber.get(input.getInvoiceId()));
+            }
+        }));
+        this.businessOverdueStatuses = ImmutableList.<BusinessOverdueStatusJson>copyOf(Collections2.transform(businessSnapshot.getBusinessOverdueStatuses(), new Function<BusinessOverdueStatus, BusinessOverdueStatusJson>() {
+            @Override
+            public BusinessOverdueStatusJson apply(@Nullable final BusinessOverdueStatus input) {
+                return new BusinessOverdueStatusJson(input);
+            }
+        }));
+        this.businessTags = ImmutableList.<BusinessTagJson>copyOf(Collections2.transform(businessSnapshot.getBusinessTags(), new Function<BusinessTag, BusinessTagJson>() {
+            @Override
+            public BusinessTagJson apply(@Nullable final BusinessTag input) {
+                return new BusinessTagJson(input);
+            }
+        }));
+        this.businessFields = ImmutableList.<BusinessFieldJson>copyOf(Collections2.transform(businessSnapshot.getBusinessFields(), new Function<BusinessField, BusinessFieldJson>() {
+            @Override
+            public BusinessFieldJson apply(@Nullable final BusinessField input) {
+                return new BusinessFieldJson(input);
+            }
+        }));
+    }
+
+    public BusinessAccountJson getBusinessAccount() {
+        return businessAccount;
+    }
+
+    public Collection<BusinessSubscriptionTransitionJson> getBusinessSubscriptionTransitions() {
+        return businessSubscriptionTransitions;
+    }
+
+    public Collection<BusinessInvoiceJson> getBusinessInvoices() {
+        return businessInvoices;
+    }
+
+    public Collection<BusinessInvoicePaymentJson> getBusinessInvoicePayments() {
+        return businessInvoicePayments;
+    }
+
+    public Collection<BusinessOverdueStatusJson> getBusinessOverdueStatuses() {
+        return businessOverdueStatuses;
+    }
+
+    public Collection<BusinessTagJson> getBusinessTags() {
+        return businessTags;
+    }
+
+    public Collection<BusinessFieldJson> getBusinessFields() {
+        return businessFields;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessSnapshotJson");
+        sb.append("{businessAccount=").append(businessAccount);
+        sb.append(", businessSubscriptionTransitions=").append(businessSubscriptionTransitions);
+        sb.append(", businessInvoices=").append(businessInvoices);
+        sb.append(", businessInvoicePayments=").append(businessInvoicePayments);
+        sb.append(", businessOverdueStatuses=").append(businessOverdueStatuses);
+        sb.append(", businessTags=").append(businessTags);
+        sb.append(", businessFields=").append(businessFields);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessSnapshotJson that = (BusinessSnapshotJson) o;
+
+        if (businessAccount != null ? !businessAccount.equals(that.businessAccount) : that.businessAccount != null) {
+            return false;
+        }
+        if (businessFields != null ? !businessFields.equals(that.businessFields) : that.businessFields != null) {
+            return false;
+        }
+        if (businessInvoicePayments != null ? !businessInvoicePayments.equals(that.businessInvoicePayments) : that.businessInvoicePayments != null) {
+            return false;
+        }
+        if (businessInvoices != null ? !businessInvoices.equals(that.businessInvoices) : that.businessInvoices != null) {
+            return false;
+        }
+        if (businessOverdueStatuses != null ? !businessOverdueStatuses.equals(that.businessOverdueStatuses) : that.businessOverdueStatuses != null) {
+            return false;
+        }
+        if (businessSubscriptionTransitions != null ? !businessSubscriptionTransitions.equals(that.businessSubscriptionTransitions) : that.businessSubscriptionTransitions != null) {
+            return false;
+        }
+        if (businessTags != null ? !businessTags.equals(that.businessTags) : that.businessTags != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = businessAccount != null ? businessAccount.hashCode() : 0;
+        result = 31 * result + (businessSubscriptionTransitions != null ? businessSubscriptionTransitions.hashCode() : 0);
+        result = 31 * result + (businessInvoices != null ? businessInvoices.hashCode() : 0);
+        result = 31 * result + (businessInvoicePayments != null ? businessInvoicePayments.hashCode() : 0);
+        result = 31 * result + (businessOverdueStatuses != null ? businessOverdueStatuses.hashCode() : 0);
+        result = 31 * result + (businessTags != null ? businessTags.hashCode() : 0);
+        result = 31 * result + (businessFields != null ? businessFields.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessSubscriptionTransitionJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessSubscriptionTransitionJson.java
new file mode 100644
index 0000000..3d95ac7
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessSubscriptionTransitionJson.java
@@ -0,0 +1,496 @@
+/*
+ * Copyright 2010-2012 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.jaxrs.json;
+
+import java.math.BigDecimal;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.analytics.api.BusinessSubscriptionTransition;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class BusinessSubscriptionTransitionJson extends JsonBase {
+
+    private final Long totalOrdering;
+    private final String bundleId;
+    private final String externalKey;
+    private final String accountId;
+    private final String accountKey;
+    private final String subscriptionId;
+
+    private final DateTime requestedTimestamp;
+    private final String eventType;
+    private final String category;
+
+    private final String prevProductName;
+    private final String prevProductType;
+    private final String prevProductCategory;
+    private final String prevSlug;
+    private final String prevPhase;
+    private final String prevBillingPeriod;
+    private final BigDecimal prevPrice;
+    private final String prevPriceList;
+    private final BigDecimal prevMrr;
+    private final String prevCurrency;
+    private final DateTime prevStartDate;
+    private final String prevState;
+
+    private final String nextProductName;
+    private final String nextProductType;
+    private final String nextProductCategory;
+    private final String nextSlug;
+    private final String nextPhase;
+    private final String nextBillingPeriod;
+    private final BigDecimal nextPrice;
+    private final String nextPriceList;
+    private final BigDecimal nextMrr;
+    private final String nextCurrency;
+    private final DateTime nextStartDate;
+    private final String nextState;
+
+    @JsonCreator
+    public BusinessSubscriptionTransitionJson(@JsonProperty("totalOrdering") final Long totalOrdering,
+                                              @JsonProperty("bundleId") final String bundleId,
+                                              @JsonProperty("externalKey") final String externalKey,
+                                              @JsonProperty("accountId") final String accountId,
+                                              @JsonProperty("accountKey") final String accountKey,
+                                              @JsonProperty("subscriptionId") final String subscriptionId,
+                                              @JsonProperty("requestedTimestamp") final DateTime requestedTimestamp,
+                                              @JsonProperty("eventType") final String eventType,
+                                              @JsonProperty("category") final String category,
+                                              @JsonProperty("prevProductName") final String prevProductName,
+                                              @JsonProperty("prevProductType") final String prevProductType,
+                                              @JsonProperty("prevProductCategory") final String prevProductCategory,
+                                              @JsonProperty("prevSlug") final String prevSlug,
+                                              @JsonProperty("prevPhase") final String prevPhase,
+                                              @JsonProperty("prevBillingPeriod") final String prevBillingPeriod,
+                                              @JsonProperty("prevPrice") final BigDecimal prevPrice,
+                                              @JsonProperty("prevPriceList") final String prevPriceList,
+                                              @JsonProperty("prevMrr") final BigDecimal prevMrr,
+                                              @JsonProperty("prevCurrency") final String prevCurrency,
+                                              @JsonProperty("prevStartDate") final DateTime prevStartDate,
+                                              @JsonProperty("prevState") final String prevState,
+                                              @JsonProperty("nextProductName") final String nextProductName,
+                                              @JsonProperty("nextProductType") final String nextProductType,
+                                              @JsonProperty("nextProductCategory") final String nextProductCategory,
+                                              @JsonProperty("nextSlug") final String nextSlug,
+                                              @JsonProperty("nextPhase") final String nextPhase,
+                                              @JsonProperty("nextBillingPeriod") final String nextBillingPeriod,
+                                              @JsonProperty("nextPrice") final BigDecimal nextPrice,
+                                              @JsonProperty("nextPriceList") final String nextPriceList,
+                                              @JsonProperty("nextMrr") final BigDecimal nextMrr,
+                                              @JsonProperty("nextCurrency") final String nextCurrency,
+                                              @JsonProperty("nextStartDate") final DateTime nextStartDate,
+                                              @JsonProperty("nextState") final String nextState) {
+        this.totalOrdering = totalOrdering;
+        this.bundleId = bundleId;
+        this.externalKey = externalKey;
+        this.accountId = accountId;
+        this.accountKey = accountKey;
+        this.subscriptionId = subscriptionId;
+        this.requestedTimestamp = requestedTimestamp;
+        this.eventType = eventType;
+        this.category = category;
+        this.prevProductName = prevProductName;
+        this.prevProductType = prevProductType;
+        this.prevProductCategory = prevProductCategory;
+        this.prevSlug = prevSlug;
+        this.prevPhase = prevPhase;
+        this.prevBillingPeriod = prevBillingPeriod;
+        this.prevPrice = prevPrice;
+        this.prevPriceList = prevPriceList;
+        this.prevMrr = prevMrr;
+        this.prevCurrency = prevCurrency;
+        this.prevStartDate = prevStartDate;
+        this.prevState = prevState;
+        this.nextProductName = nextProductName;
+        this.nextProductType = nextProductType;
+        this.nextProductCategory = nextProductCategory;
+        this.nextSlug = nextSlug;
+        this.nextPhase = nextPhase;
+        this.nextBillingPeriod = nextBillingPeriod;
+        this.nextPrice = nextPrice;
+        this.nextPriceList = nextPriceList;
+        this.nextMrr = nextMrr;
+        this.nextCurrency = nextCurrency;
+        this.nextStartDate = nextStartDate;
+        this.nextState = nextState;
+    }
+
+    public BusinessSubscriptionTransitionJson(final BusinessSubscriptionTransition businessSubscriptionTransition) {
+        this(businessSubscriptionTransition.getTotalOrdering(),
+             businessSubscriptionTransition.getBundleId().toString(),
+             businessSubscriptionTransition.getExternalKey(),
+             businessSubscriptionTransition.getAccountId().toString(),
+             businessSubscriptionTransition.getAccountKey(),
+             businessSubscriptionTransition.getSubscriptionId().toString(),
+             businessSubscriptionTransition.getRequestedTimestamp(),
+             businessSubscriptionTransition.getEventType(),
+             businessSubscriptionTransition.getCategory(),
+             businessSubscriptionTransition.getPrevProductName(),
+             businessSubscriptionTransition.getPrevProductType(),
+             businessSubscriptionTransition.getPrevProductCategory(),
+             businessSubscriptionTransition.getPrevSlug(),
+             businessSubscriptionTransition.getPrevPhase(),
+             businessSubscriptionTransition.getPrevBillingPeriod(),
+             businessSubscriptionTransition.getPrevPrice(),
+             businessSubscriptionTransition.getPrevPriceList(),
+             businessSubscriptionTransition.getPrevMrr(),
+             businessSubscriptionTransition.getPrevCurrency(),
+             businessSubscriptionTransition.getPrevStartDate(),
+             businessSubscriptionTransition.getPrevState(),
+             businessSubscriptionTransition.getNextProductName(),
+             businessSubscriptionTransition.getNextProductType(),
+             businessSubscriptionTransition.getNextProductCategory(),
+             businessSubscriptionTransition.getNextSlug(),
+             businessSubscriptionTransition.getNextPhase(),
+             businessSubscriptionTransition.getNextBillingPeriod(),
+             businessSubscriptionTransition.getNextPrice(),
+             businessSubscriptionTransition.getNextPriceList(),
+             businessSubscriptionTransition.getNextMrr(),
+             businessSubscriptionTransition.getNextCurrency(),
+             businessSubscriptionTransition.getNextStartDate(),
+             businessSubscriptionTransition.getNextState());
+    }
+
+    public Long getTotalOrdering() {
+        return totalOrdering;
+    }
+
+    public String getBundleId() {
+        return bundleId;
+    }
+
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    public String getSubscriptionId() {
+        return subscriptionId;
+    }
+
+    public DateTime getRequestedTimestamp() {
+        return requestedTimestamp;
+    }
+
+    public String getEventType() {
+        return eventType;
+    }
+
+    public String getCategory() {
+        return category;
+    }
+
+    public String getPrevProductName() {
+        return prevProductName;
+    }
+
+    public String getPrevProductType() {
+        return prevProductType;
+    }
+
+    public String getPrevProductCategory() {
+        return prevProductCategory;
+    }
+
+    public String getPrevSlug() {
+        return prevSlug;
+    }
+
+    public String getPrevPhase() {
+        return prevPhase;
+    }
+
+    public String getPrevBillingPeriod() {
+        return prevBillingPeriod;
+    }
+
+    public BigDecimal getPrevPrice() {
+        return prevPrice;
+    }
+
+    public String getPrevPriceList() {
+        return prevPriceList;
+    }
+
+    public BigDecimal getPrevMrr() {
+        return prevMrr;
+    }
+
+    public String getPrevCurrency() {
+        return prevCurrency;
+    }
+
+    public DateTime getPrevStartDate() {
+        return prevStartDate;
+    }
+
+    public String getPrevState() {
+        return prevState;
+    }
+
+    public String getNextProductName() {
+        return nextProductName;
+    }
+
+    public String getNextProductType() {
+        return nextProductType;
+    }
+
+    public String getNextProductCategory() {
+        return nextProductCategory;
+    }
+
+    public String getNextSlug() {
+        return nextSlug;
+    }
+
+    public String getNextPhase() {
+        return nextPhase;
+    }
+
+    public String getNextBillingPeriod() {
+        return nextBillingPeriod;
+    }
+
+    public BigDecimal getNextPrice() {
+        return nextPrice;
+    }
+
+    public String getNextPriceList() {
+        return nextPriceList;
+    }
+
+    public BigDecimal getNextMrr() {
+        return nextMrr;
+    }
+
+    public String getNextCurrency() {
+        return nextCurrency;
+    }
+
+    public DateTime getNextStartDate() {
+        return nextStartDate;
+    }
+
+    public String getNextState() {
+        return nextState;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessSubscriptionTransitionJson");
+        sb.append("{totalOrdering=").append(totalOrdering);
+        sb.append(", bundleId='").append(bundleId).append('\'');
+        sb.append(", externalKey='").append(externalKey).append('\'');
+        sb.append(", accountId='").append(accountId).append('\'');
+        sb.append(", accountKey='").append(accountKey).append('\'');
+        sb.append(", subscriptionId='").append(subscriptionId).append('\'');
+        sb.append(", requestedTimestamp=").append(requestedTimestamp);
+        sb.append(", eventType='").append(eventType).append('\'');
+        sb.append(", category='").append(category).append('\'');
+        sb.append(", prevProductName='").append(prevProductName).append('\'');
+        sb.append(", prevProductType='").append(prevProductType).append('\'');
+        sb.append(", prevProductCategory='").append(prevProductCategory).append('\'');
+        sb.append(", prevSlug='").append(prevSlug).append('\'');
+        sb.append(", prevPhase='").append(prevPhase).append('\'');
+        sb.append(", prevBillingPeriod='").append(prevBillingPeriod).append('\'');
+        sb.append(", prevPrice=").append(prevPrice);
+        sb.append(", prevPriceList='").append(prevPriceList).append('\'');
+        sb.append(", prevMrr=").append(prevMrr);
+        sb.append(", prevCurrency='").append(prevCurrency).append('\'');
+        sb.append(", prevStartDate=").append(prevStartDate);
+        sb.append(", prevState='").append(prevState).append('\'');
+        sb.append(", nextProductName='").append(nextProductName).append('\'');
+        sb.append(", nextProductType='").append(nextProductType).append('\'');
+        sb.append(", nextProductCategory='").append(nextProductCategory).append('\'');
+        sb.append(", nextSlug='").append(nextSlug).append('\'');
+        sb.append(", nextPhase='").append(nextPhase).append('\'');
+        sb.append(", nextBillingPeriod='").append(nextBillingPeriod).append('\'');
+        sb.append(", nextPrice=").append(nextPrice);
+        sb.append(", nextPriceList='").append(nextPriceList).append('\'');
+        sb.append(", nextMrr=").append(nextMrr);
+        sb.append(", nextCurrency='").append(nextCurrency).append('\'');
+        sb.append(", nextStartDate=").append(nextStartDate);
+        sb.append(", nextState='").append(nextState).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessSubscriptionTransitionJson that = (BusinessSubscriptionTransitionJson) o;
+
+        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+            return false;
+        }
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (bundleId != null ? !bundleId.equals(that.bundleId) : that.bundleId != null) {
+            return false;
+        }
+        if (category != null ? !category.equals(that.category) : that.category != null) {
+            return false;
+        }
+        if (eventType != null ? !eventType.equals(that.eventType) : that.eventType != null) {
+            return false;
+        }
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+            return false;
+        }
+        if (nextBillingPeriod != null ? !nextBillingPeriod.equals(that.nextBillingPeriod) : that.nextBillingPeriod != null) {
+            return false;
+        }
+        if (nextCurrency != null ? !nextCurrency.equals(that.nextCurrency) : that.nextCurrency != null) {
+            return false;
+        }
+        if (nextMrr != null ? !nextMrr.equals(that.nextMrr) : that.nextMrr != null) {
+            return false;
+        }
+        if (nextPhase != null ? !nextPhase.equals(that.nextPhase) : that.nextPhase != null) {
+            return false;
+        }
+        if (nextPrice != null ? !nextPrice.equals(that.nextPrice) : that.nextPrice != null) {
+            return false;
+        }
+        if (nextPriceList != null ? !nextPriceList.equals(that.nextPriceList) : that.nextPriceList != null) {
+            return false;
+        }
+        if (nextProductCategory != null ? !nextProductCategory.equals(that.nextProductCategory) : that.nextProductCategory != null) {
+            return false;
+        }
+        if (nextProductName != null ? !nextProductName.equals(that.nextProductName) : that.nextProductName != null) {
+            return false;
+        }
+        if (nextProductType != null ? !nextProductType.equals(that.nextProductType) : that.nextProductType != null) {
+            return false;
+        }
+        if (nextSlug != null ? !nextSlug.equals(that.nextSlug) : that.nextSlug != null) {
+            return false;
+        }
+        if (nextStartDate != null ? !nextStartDate.equals(that.nextStartDate) : that.nextStartDate != null) {
+            return false;
+        }
+        if (nextState != null ? !nextState.equals(that.nextState) : that.nextState != null) {
+            return false;
+        }
+        if (prevBillingPeriod != null ? !prevBillingPeriod.equals(that.prevBillingPeriod) : that.prevBillingPeriod != null) {
+            return false;
+        }
+        if (prevCurrency != null ? !prevCurrency.equals(that.prevCurrency) : that.prevCurrency != null) {
+            return false;
+        }
+        if (prevMrr != null ? !prevMrr.equals(that.prevMrr) : that.prevMrr != null) {
+            return false;
+        }
+        if (prevPhase != null ? !prevPhase.equals(that.prevPhase) : that.prevPhase != null) {
+            return false;
+        }
+        if (prevPrice != null ? !prevPrice.equals(that.prevPrice) : that.prevPrice != null) {
+            return false;
+        }
+        if (prevPriceList != null ? !prevPriceList.equals(that.prevPriceList) : that.prevPriceList != null) {
+            return false;
+        }
+        if (prevProductCategory != null ? !prevProductCategory.equals(that.prevProductCategory) : that.prevProductCategory != null) {
+            return false;
+        }
+        if (prevProductName != null ? !prevProductName.equals(that.prevProductName) : that.prevProductName != null) {
+            return false;
+        }
+        if (prevProductType != null ? !prevProductType.equals(that.prevProductType) : that.prevProductType != null) {
+            return false;
+        }
+        if (prevSlug != null ? !prevSlug.equals(that.prevSlug) : that.prevSlug != null) {
+            return false;
+        }
+        if (prevStartDate != null ? !prevStartDate.equals(that.prevStartDate) : that.prevStartDate != null) {
+            return false;
+        }
+        if (prevState != null ? !prevState.equals(that.prevState) : that.prevState != null) {
+            return false;
+        }
+        if (requestedTimestamp != null ? !requestedTimestamp.equals(that.requestedTimestamp) : that.requestedTimestamp != null) {
+            return false;
+        }
+        if (subscriptionId != null ? !subscriptionId.equals(that.subscriptionId) : that.subscriptionId != null) {
+            return false;
+        }
+        if (totalOrdering != null ? !totalOrdering.equals(that.totalOrdering) : that.totalOrdering != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = totalOrdering != null ? totalOrdering.hashCode() : 0;
+        result = 31 * result + (bundleId != null ? bundleId.hashCode() : 0);
+        result = 31 * result + (externalKey != null ? externalKey.hashCode() : 0);
+        result = 31 * result + (accountId != null ? accountId.hashCode() : 0);
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
+        result = 31 * result + (subscriptionId != null ? subscriptionId.hashCode() : 0);
+        result = 31 * result + (requestedTimestamp != null ? requestedTimestamp.hashCode() : 0);
+        result = 31 * result + (eventType != null ? eventType.hashCode() : 0);
+        result = 31 * result + (category != null ? category.hashCode() : 0);
+        result = 31 * result + (prevProductName != null ? prevProductName.hashCode() : 0);
+        result = 31 * result + (prevProductType != null ? prevProductType.hashCode() : 0);
+        result = 31 * result + (prevProductCategory != null ? prevProductCategory.hashCode() : 0);
+        result = 31 * result + (prevSlug != null ? prevSlug.hashCode() : 0);
+        result = 31 * result + (prevPhase != null ? prevPhase.hashCode() : 0);
+        result = 31 * result + (prevBillingPeriod != null ? prevBillingPeriod.hashCode() : 0);
+        result = 31 * result + (prevPrice != null ? prevPrice.hashCode() : 0);
+        result = 31 * result + (prevPriceList != null ? prevPriceList.hashCode() : 0);
+        result = 31 * result + (prevMrr != null ? prevMrr.hashCode() : 0);
+        result = 31 * result + (prevCurrency != null ? prevCurrency.hashCode() : 0);
+        result = 31 * result + (prevStartDate != null ? prevStartDate.hashCode() : 0);
+        result = 31 * result + (prevState != null ? prevState.hashCode() : 0);
+        result = 31 * result + (nextProductName != null ? nextProductName.hashCode() : 0);
+        result = 31 * result + (nextProductType != null ? nextProductType.hashCode() : 0);
+        result = 31 * result + (nextProductCategory != null ? nextProductCategory.hashCode() : 0);
+        result = 31 * result + (nextSlug != null ? nextSlug.hashCode() : 0);
+        result = 31 * result + (nextPhase != null ? nextPhase.hashCode() : 0);
+        result = 31 * result + (nextBillingPeriod != null ? nextBillingPeriod.hashCode() : 0);
+        result = 31 * result + (nextPrice != null ? nextPrice.hashCode() : 0);
+        result = 31 * result + (nextPriceList != null ? nextPriceList.hashCode() : 0);
+        result = 31 * result + (nextMrr != null ? nextMrr.hashCode() : 0);
+        result = 31 * result + (nextCurrency != null ? nextCurrency.hashCode() : 0);
+        result = 31 * result + (nextStartDate != null ? nextStartDate.hashCode() : 0);
+        result = 31 * result + (nextState != null ? nextState.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessTagJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessTagJson.java
new file mode 100644
index 0000000..19e1cdb
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessTagJson.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010-2012 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.jaxrs.json;
+
+import com.ning.billing.analytics.api.BusinessTag;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class BusinessTagJson extends JsonBase {
+
+    private final String objectType;
+    private final String id;
+    private final String name;
+
+    @JsonCreator
+    public BusinessTagJson(@JsonProperty("objectType") final String objectType,
+                           @JsonProperty("id") final String id,
+                           @JsonProperty("name") final String name) {
+        this.objectType = objectType;
+        this.id = id;
+        this.name = name;
+    }
+
+    public BusinessTagJson(final BusinessTag businessTag) {
+        this(businessTag.getObjectType().toString(),
+             businessTag.getId().toString(),
+             businessTag.getName());
+    }
+
+    public String getObjectType() {
+        return objectType;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessTagJson");
+        sb.append("{objectType='").append(objectType).append('\'');
+        sb.append(", id='").append(id).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessTagJson that = (BusinessTagJson) o;
+
+        if (id != null ? !id.equals(that.id) : that.id != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        if (objectType != null ? !objectType.equals(that.objectType) : that.objectType != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = objectType != null ? objectType.hashCode() : 0;
+        result = 31 * result + (id != null ? id.hashCode() : 0);
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/JsonBase.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/JsonBase.java
index 315e74d..33cb38c 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/JsonBase.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/JsonBase.java
@@ -31,6 +31,10 @@ public abstract class JsonBase {
 
     protected List<AuditLogJson> auditLogs;
 
+    public JsonBase() {
+        this(null);
+    }
+
     public JsonBase(@Nullable final List<AuditLogJson> auditLogs) {
         this.auditLogs = auditLogs;
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AnalyticsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AnalyticsResource.java
index bbf996f..a258a19 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AnalyticsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AnalyticsResource.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.jaxrs.resources;
 
+import java.util.Collection;
 import java.util.UUID;
 
 import javax.inject.Inject;
@@ -33,8 +34,12 @@ import javax.ws.rs.core.Response.Status;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.analytics.api.BusinessSnapshot;
 import com.ning.billing.analytics.api.TimeSeriesData;
+import com.ning.billing.analytics.api.sanity.AnalyticsSanityApi;
 import com.ning.billing.analytics.api.user.AnalyticsUserApi;
+import com.ning.billing.jaxrs.json.AnalyticsSanityJson;
+import com.ning.billing.jaxrs.json.BusinessSnapshotJson;
 import com.ning.billing.jaxrs.json.TimeSeriesDataJson;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
@@ -42,6 +47,7 @@ import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TenantContext;
 
 import com.google.inject.Singleton;
 
@@ -53,10 +59,12 @@ public class AnalyticsResource extends JaxRsResourceBase {
 
     private final AccountUserApi accountUserApi;
     private final AnalyticsUserApi analyticsUserApi;
+    private final AnalyticsSanityApi analyticsSanityApi;
 
     @Inject
     public AnalyticsResource(final AccountUserApi accountUserApi,
                              final AnalyticsUserApi analyticsUserApi,
+                             final AnalyticsSanityApi analyticsSanityApi,
                              final JaxrsUriBuilder uriBuilder,
                              final TagUserApi tagUserApi,
                              final CustomFieldUserApi customFieldUserApi,
@@ -65,6 +73,38 @@ public class AnalyticsResource extends JaxRsResourceBase {
         super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
         this.accountUserApi = accountUserApi;
         this.analyticsUserApi = analyticsUserApi;
+        this.analyticsSanityApi = analyticsSanityApi;
+    }
+
+    @GET
+    @Path("/sanity")
+    @Produces(APPLICATION_JSON)
+    public Response checkSanity(@javax.ws.rs.core.Context final HttpServletRequest request) {
+        final TenantContext tenantContext = context.createContext(request);
+        final Collection<UUID> checkEntitlement = analyticsSanityApi.checkAnalyticsInSyncWithEntitlement(tenantContext);
+        final Collection<UUID> checkInvoice = analyticsSanityApi.checkAnalyticsInSyncWithInvoice(tenantContext);
+        final Collection<UUID> checkPayment = analyticsSanityApi.checkAnalyticsInSyncWithPayment(tenantContext);
+        final Collection<UUID> checkTag = analyticsSanityApi.checkAnalyticsInSyncWithTag(tenantContext);
+        final Collection<UUID> checkConsistency = analyticsSanityApi.checkAnalyticsConsistency(tenantContext);
+
+        final AnalyticsSanityJson json = new AnalyticsSanityJson(checkEntitlement,
+                                                                 checkInvoice,
+                                                                 checkPayment,
+                                                                 checkTag,
+                                                                 checkConsistency);
+        return Response.status(Status.OK).entity(json).build();
+    }
+
+    @GET
+    @Path("/{accountId:" + UUID_PATTERN + "}")
+    @Produces(APPLICATION_JSON)
+    public Response getBusinessSnapshotForAccount(@PathParam("accountId") final String accountId,
+                                                  @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
+        final TenantContext callContext = context.createContext(request);
+        final Account account = accountUserApi.getAccountById(UUID.fromString(accountId), callContext);
+        final BusinessSnapshot businessSnapshot = analyticsUserApi.getBusinessSnapshot(account, callContext);
+        final BusinessSnapshotJson json = new BusinessSnapshotJson(businessSnapshot);
+        return Response.status(Status.OK).entity(json).build();
     }
 
     @PUT