killbill-aplcache

analytics: export Business objects in api * Export interfaces *

10/31/2012 12:42:01 AM

Changes

Details

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..8bb7afa
--- /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.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.dao.ObjectType;
+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..c8540cc
--- /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.analytics.model.BusinessOverdueStatusModelDao;
+import com.ning.billing.util.dao.ObjectType;
+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..046f422
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/DefaultBusinessSubscriptionTransition.java
@@ -0,0 +1,492 @@
+/*
+ * 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();
+        this.category = bstModelDao.getEvent().getCategory().toString();
+
+        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..2e24f0c
--- /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.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.dao.ObjectType;
+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/model/BusinessAccountFieldModelDao.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccountFieldModelDao.java
index cbe99bd..f9a5f70 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccountFieldModelDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccountFieldModelDao.java
@@ -24,7 +24,7 @@ public class BusinessAccountFieldModelDao extends BusinessFieldModelDao {
     private final String accountKey;
 
     public BusinessAccountFieldModelDao(final UUID accountId, final String accountKey, final String name, final String value) {
-        super(name, value);
+        super(accountId, name, value);
         this.accountId = accountId;
         this.accountKey = accountKey;
     }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessFieldModelDao.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessFieldModelDao.java
index 56b2c94..6da47ba 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessFieldModelDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessFieldModelDao.java
@@ -16,6 +16,8 @@
 
 package com.ning.billing.analytics.model;
 
+import java.util.UUID;
+
 import com.ning.billing.util.entity.EntityBase;
 
 public abstract class BusinessFieldModelDao extends EntityBase {
@@ -23,7 +25,8 @@ public abstract class BusinessFieldModelDao extends EntityBase {
     private final String name;
     private final String value;
 
-    public BusinessFieldModelDao(final String name, final String value) {
+    public BusinessFieldModelDao(final UUID id, final String name, final String value) {
+        super(id);
         this.name = name;
         this.value = value;
     }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceFieldModelDao.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceFieldModelDao.java
index bae81c5..b13871d 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceFieldModelDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceFieldModelDao.java
@@ -23,7 +23,7 @@ public class BusinessInvoiceFieldModelDao extends BusinessFieldModelDao {
     private final UUID invoiceId;
 
     public BusinessInvoiceFieldModelDao(final UUID invoiceId, final String name, final String value) {
-        super(name, value);
+        super(invoiceId, name, value);
         this.invoiceId = invoiceId;
     }
 
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePaymentFieldModelDao.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePaymentFieldModelDao.java
index 827adc0..f4c23f1 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePaymentFieldModelDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePaymentFieldModelDao.java
@@ -23,7 +23,7 @@ public class BusinessInvoicePaymentFieldModelDao extends BusinessFieldModelDao {
     private final UUID paymentId;
 
     public BusinessInvoicePaymentFieldModelDao(final UUID paymentId, final String name, final String value) {
-        super(name, value);
+        super(paymentId, name, value);
         this.paymentId = paymentId;
     }
 
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscriptionTransitionFieldModelDao.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscriptionTransitionFieldModelDao.java
index 85d1054..c6b2f5f 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscriptionTransitionFieldModelDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscriptionTransitionFieldModelDao.java
@@ -26,7 +26,7 @@ public class BusinessSubscriptionTransitionFieldModelDao extends BusinessFieldMo
 
     public BusinessSubscriptionTransitionFieldModelDao(final String accountKey, final UUID bundleId, final String externalKey,
                                                        final String name, final String value) {
-        super(name, value);
+        super(bundleId, name, value);
         this.accountKey = accountKey;
         this.bundleId = bundleId;
         this.externalKey = externalKey;
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..77ad3ee
--- /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.util.dao.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..dd6b92e
--- /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.util.dao.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..1290582
--- /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.util.dao.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/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..e7aa77c
--- /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().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..d71d858
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessInvoicePaymentJson.java
@@ -0,0 +1,298 @@
+/*
+ * 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 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("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.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) {
+        this(businessInvoicePayment.getPaymentId().toString(),
+             businessInvoicePayment.getExtFirstPaymentRefId(),
+             businessInvoicePayment.getExtSecondPaymentRefId(),
+             businessInvoicePayment.getAccountKey(),
+             businessInvoicePayment.getInvoiceId().toString(),
+             businessInvoicePayment.getEffectiveDate(),
+             businessInvoicePayment.getAmount(),
+             businessInvoicePayment.getCurrency().toString(),
+             businessInvoicePayment.getPaymentError(),
+             businessInvoicePayment.getProcessingStatus(),
+             businessInvoicePayment.getRequestedAmount(),
+             businessInvoicePayment.getPluginName(),
+             businessInvoicePayment.getPaymentType(),
+             businessInvoicePayment.getPaymentMethod(),
+             businessInvoicePayment.getCardType(),
+             businessInvoicePayment.getInvoicePaymentType(),
+             businessInvoicePayment.getInvoicePaymentType(),
+             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 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(", 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 (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/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..4117a25
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BusinessSnapshotJson.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.util.Collection;
+
+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) {
+        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(@Nullable final BusinessInvoice input) {
+                return new BusinessInvoiceJson(input);
+            }
+        }));
+        this.businessInvoicePayments = ImmutableList.<BusinessInvoicePaymentJson>copyOf(Collections2.transform(businessSnapshot.getBusinessInvoicePayments(), new Function<BusinessInvoicePayment, BusinessInvoicePaymentJson>() {
+            @Override
+            public BusinessInvoicePaymentJson apply(@Nullable final BusinessInvoicePayment input) {
+                return new BusinessInvoicePaymentJson(input);
+            }
+        }));
+        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;
     }