killbill-memoizeit

Changes

Details

diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
index 225bcd8..dfe5ca5 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
@@ -31,6 +32,7 @@ import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.Refund;
+import com.ning.billing.util.audit.AuditLog;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -86,11 +88,16 @@ public class AccountTimelineJson {
     }
 
     public AccountTimelineJson(final Account account, final List<Invoice> invoices, final List<Payment> payments, final List<BundleTimeline> bundles,
-                               final Multimap<UUID, Refund> refundsByPayment, final Multimap<UUID, InvoicePayment> chargebacksByPayment) {
+                               final Multimap<UUID, Refund> refundsByPayment, final Multimap<UUID, InvoicePayment> chargebacksByPayment,
+                               final Map<UUID, List<AuditLog>> invoiceAuditLogs, final Map<UUID, List<AuditLog>> invoiceItemsAuditLogs,
+                               final Map<UUID, List<AuditLog>> paymentsAuditLogs, final Map<UUID, List<AuditLog>> refundsAuditLogs,
+                               final Map<UUID, List<AuditLog>> chargebacksAuditLogs, final Map<UUID, List<AuditLog>> bundlesAuditLogs) {
         this.account = new AccountJsonSimple(account.getId().toString(), account.getExternalKey());
         this.bundles = new LinkedList<BundleJsonWithSubscriptions>();
-        for (final BundleTimeline cur : bundles) {
-            this.bundles.add(new BundleJsonWithSubscriptions(account.getId(), cur));
+        for (final BundleTimeline bundle : bundles) {
+            final List<AuditLog> auditLogs = bundlesAuditLogs.get(bundle.getBundleId());
+            final BundleJsonWithSubscriptions jsonWithSubscriptions = new BundleJsonWithSubscriptions(account.getId(), bundle, auditLogs);
+            this.bundles.add(jsonWithSubscriptions);
         }
 
         this.invoices = new LinkedList<InvoiceJsonWithBundleKeys>();
@@ -99,24 +106,18 @@ public class AccountTimelineJson {
         for (final Invoice invoice : invoices) {
             for (final InvoiceItem invoiceItem : invoice.getInvoiceItems()) {
                 if (InvoiceItemType.CREDIT_ADJ.equals(invoiceItem.getInvoiceItemType())) {
-                    credits.add(new CreditJson(invoiceItem, account.getTimeZone()));
+                    final List<AuditLog> auditLogs = invoiceItemsAuditLogs.get(invoiceItem.getId());
+                    credits.add(new CreditJson(invoiceItem, account.getTimeZone(), auditLogs));
                 }
             }
         }
         // Create now the invoice json objects
         for (final Invoice invoice : invoices) {
-            this.invoices.add(new InvoiceJsonWithBundleKeys(invoice.getPaidAmount(),
-                                                            invoice.getCBAAmount(),
-                                                            invoice.getCreditAdjAmount(),
-                                                            invoice.getRefundAdjAmount(),
-                                                            invoice.getId().toString(),
-                                                            invoice.getInvoiceDate(),
-                                                            invoice.getTargetDate(),
-                                                            Integer.toString(invoice.getInvoiceNumber()),
-                                                            invoice.getBalance(),
-                                                            invoice.getAccountId().toString(),
+            final List<AuditLog> auditLogs = invoiceAuditLogs.get(invoice.getId());
+            this.invoices.add(new InvoiceJsonWithBundleKeys(invoice,
                                                             getBundleExternalKey(invoice, bundles),
-                                                            credits));
+                                                            credits,
+                                                            auditLogs));
         }
 
         this.payments = new LinkedList<PaymentJsonWithBundleKeys>();
@@ -131,18 +132,17 @@ public class AccountTimelineJson {
                 chargebacks.add(new ChargebackJson(chargeback));
             }
 
-            final int paymentAttemptSize = payment.getAttempts().size();
+            final int nbOfPaymentAttemps = payment.getAttempts().size();
             final String status = payment.getPaymentStatus().toString();
-            this.payments.add(new PaymentJsonWithBundleKeys(payment.getAmount(), payment.getPaidAmount(), account.getId().toString(),
-                                                            payment.getInvoiceId().toString(), payment.getId().toString(),
-                                                            payment.getPaymentMethodId().toString(),
-                                                            payment.getEffectiveDate(), payment.getEffectiveDate(),
-                                                            paymentAttemptSize, payment.getCurrency().toString(), status,
-                                                            payment.getAttempts().get(paymentAttemptSize - 1).getGatewayErrorCode(),
-                                                            payment.getAttempts().get(paymentAttemptSize - 1).getGatewayErrorMsg(),
-                                                            payment.getExtFirstPaymentIdRef(), payment.getExtSecondPaymentIdRef(),
+            final List<AuditLog> auditLogs = paymentsAuditLogs.get(payment.getId());
+            this.payments.add(new PaymentJsonWithBundleKeys(payment,
+                                                            status,
+                                                            nbOfPaymentAttemps,
                                                             getBundleExternalKey(payment.getInvoiceId(), invoices, bundles),
-                                                            refunds, chargebacks));
+                                                            account.getId(),
+                                                            refunds,
+                                                            chargebacks,
+                                                            auditLogs));
         }
     }
 
@@ -176,15 +176,27 @@ public class AccountTimelineJson {
 
     @Override
     public boolean equals(final Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
 
         final AccountTimelineJson that = (AccountTimelineJson) o;
 
-        if (account != null ? !account.equals(that.account) : that.account != null) return false;
-        if (bundles != null ? !bundles.equals(that.bundles) : that.bundles != null) return false;
-        if (invoices != null ? !invoices.equals(that.invoices) : that.invoices != null) return false;
-        if (payments != null ? !payments.equals(that.payments) : that.payments != null) return false;
+        if (account != null ? !account.equals(that.account) : that.account != null) {
+            return false;
+        }
+        if (bundles != null ? !bundles.equals(that.bundles) : that.bundles != null) {
+            return false;
+        }
+        if (invoices != null ? !invoices.equals(that.invoices) : that.invoices != null) {
+            return false;
+        }
+        if (payments != null ? !payments.equals(that.payments) : that.payments != null) {
+            return false;
+        }
 
         return true;
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonNoSubscriptions.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonNoSubscriptions.java
index 94e8a92..ded56fe 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonNoSubscriptions.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonNoSubscriptions.java
@@ -16,10 +16,14 @@
 
 package com.ning.billing.jaxrs.json;
 
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 
 public class BundleJsonNoSubscriptions extends BundleJsonSimple {
 
@@ -28,8 +32,10 @@ public class BundleJsonNoSubscriptions extends BundleJsonSimple {
     @JsonCreator
     public BundleJsonNoSubscriptions(@JsonProperty("bundleId") final String bundleId,
                                      @JsonProperty("accountId") final String accountId,
-                                     @JsonProperty("externalKey") final String externalKey) {
-        super(bundleId, externalKey);
+                                     @JsonProperty("externalKey") final String externalKey,
+                                     @JsonProperty("subscriptions") @Nullable final List<SubscriptionJsonWithEvents> subscriptions,
+                                     @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+        super(bundleId, externalKey, auditLogs);
         this.accountId = accountId;
     }
 
@@ -38,25 +44,20 @@ public class BundleJsonNoSubscriptions extends BundleJsonSimple {
     }
 
     public BundleJsonNoSubscriptions(final SubscriptionBundle bundle) {
-        super(bundle.getId().toString(), bundle.getKey());
+        super(bundle.getId().toString(), bundle.getKey(), null);
         this.accountId = bundle.getAccountId().toString();
     }
 
-    public BundleJsonNoSubscriptions() {
-        super(null, null);
-        this.accountId = null;
-    }
-
     @Override
     public int hashCode() {
         final int prime = 31;
         int result = 1;
         result = prime * result
-                + ((accountId == null) ? 0 : accountId.hashCode());
+                 + ((accountId == null) ? 0 : accountId.hashCode());
         result = prime * result
-                + ((bundleId == null) ? 0 : bundleId.hashCode());
+                 + ((bundleId == null) ? 0 : bundleId.hashCode());
         result = prime * result
-                + ((externalKey == null) ? 0 : externalKey.hashCode());
+                 + ((externalKey == null) ? 0 : externalKey.hashCode());
         return result;
     }
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonSimple.java
index 8c88959..08fcc40 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonSimple.java
@@ -13,14 +13,20 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs.json;
 
+import java.util.List;
+import java.util.UUID;
+
 import javax.annotation.Nullable;
 
+import com.ning.billing.util.audit.AuditLog;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class BundleJsonSimple {
+public class BundleJsonSimple extends JsonBase {
 
     protected final String bundleId;
 
@@ -28,13 +34,15 @@ public class BundleJsonSimple {
 
     @JsonCreator
     public BundleJsonSimple(@JsonProperty("bundleId") @Nullable final String bundleId,
-                            @JsonProperty("externalKey") @Nullable final String externalKey) {
+                            @JsonProperty("externalKey") @Nullable final String externalKey,
+                            @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+        super(auditLogs);
         this.bundleId = bundleId;
         this.externalKey = externalKey;
     }
 
-    public BundleJsonSimple() {
-        this(null, null);
+    public BundleJsonSimple(final UUID bundleId, final String externalKey, final List<AuditLog> auditLogs) {
+        this(bundleId.toString(), externalKey, toAuditLogJson(auditLogs));
     }
 
     @JsonProperty("bundleId")
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonWithSubscriptions.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonWithSubscriptions.java
index c2ca338..be03ceb 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonWithSubscriptions.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonWithSubscriptions.java
@@ -13,18 +13,21 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs.json;
 
-import javax.annotation.Nullable;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.Nullable;
+
 import com.ning.billing.entitlement.api.timeline.BundleTimeline;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.util.audit.AuditLog;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
 
 public class BundleJsonWithSubscriptions extends BundleJsonSimple {
 
@@ -33,8 +36,9 @@ public class BundleJsonWithSubscriptions extends BundleJsonSimple {
     @JsonCreator
     public BundleJsonWithSubscriptions(@JsonProperty("bundleId") @Nullable final String bundleId,
                                        @JsonProperty("externalKey") @Nullable final String externalKey,
-                                       @JsonProperty("subscriptions") @Nullable final List<SubscriptionJsonWithEvents> subscriptions) {
-        super(bundleId, externalKey);
+                                       @JsonProperty("subscriptions") @Nullable final List<SubscriptionJsonWithEvents> subscriptions,
+                                       @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+        super(bundleId, externalKey, auditLogs);
         this.subscriptions = subscriptions;
     }
 
@@ -43,23 +47,14 @@ public class BundleJsonWithSubscriptions extends BundleJsonSimple {
         return subscriptions;
     }
 
-    public BundleJsonWithSubscriptions(@Nullable final UUID accountId, final BundleTimeline bundle) {
-        super(bundle.getBundleId().toString(), bundle.getExternalKey());
+    public BundleJsonWithSubscriptions(@Nullable final UUID accountId, final BundleTimeline bundle, final List<AuditLog> auditLogs) {
+        super(bundle.getBundleId(), bundle.getExternalKey(), auditLogs);
         this.subscriptions = new LinkedList<SubscriptionJsonWithEvents>();
         for (final SubscriptionTimeline cur : bundle.getSubscriptions()) {
             this.subscriptions.add(new SubscriptionJsonWithEvents(bundle.getBundleId(), cur));
         }
     }
 
-    public BundleJsonWithSubscriptions(final SubscriptionBundle bundle) {
-        super(bundle.getId().toString(), bundle.getKey());
-        this.subscriptions = null;
-    }
-
-    public BundleJsonWithSubscriptions() {
-        this(null, null, null);
-    }
-
     @Override
     public boolean equals(final Object o) {
         if (this == o) {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java
index ab5221e..458e277 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java
@@ -17,17 +17,21 @@
 package com.ning.billing.jaxrs.json;
 
 import java.math.BigDecimal;
+import java.util.List;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
 import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.util.audit.AuditLog;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class CreditJson {
+public class CreditJson extends JsonBase {
 
     private final BigDecimal creditAmount;
     private final UUID invoiceId;
@@ -44,7 +48,9 @@ public class CreditJson {
                       @JsonProperty("requestedDate") final DateTime requestedDate,
                       @JsonProperty("effectiveDate") final DateTime effectiveDate,
                       @JsonProperty("reason") final String reason,
-                      @JsonProperty("accountId") final UUID accountId) {
+                      @JsonProperty("accountId") final UUID accountId,
+                      @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+        super(auditLogs);
         this.creditAmount = creditAmount;
         this.invoiceId = invoiceId;
         this.invoiceNumber = invoiceNumber;
@@ -54,7 +60,8 @@ public class CreditJson {
         this.accountId = accountId;
     }
 
-    public CreditJson(final InvoiceItem credit, final DateTimeZone accountTimeZone) {
+    public CreditJson(final InvoiceItem credit, final DateTimeZone accountTimeZone, final List<AuditLog> auditLogs) {
+        super(toAuditLogJson(auditLogs));
         this.creditAmount = credit.getAmount();
         this.invoiceId = credit.getInvoiceId();
         this.invoiceNumber = null;
@@ -64,6 +71,10 @@ public class CreditJson {
         this.accountId = credit.getAccountId();
     }
 
+    public CreditJson(final InvoiceItem credit, final DateTimeZone timeZone) {
+        this(credit, timeZone, null);
+    }
+
     public BigDecimal getCreditAmount() {
         return creditAmount;
     }
@@ -93,6 +104,21 @@ public class CreditJson {
     }
 
     @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("CreditJson");
+        sb.append("{creditAmount=").append(creditAmount);
+        sb.append(", invoiceId=").append(invoiceId);
+        sb.append(", invoiceNumber='").append(invoiceNumber).append('\'');
+        sb.append(", requestedDate=").append(requestedDate);
+        sb.append(", effectiveDate=").append(effectiveDate);
+        sb.append(", reason='").append(reason).append('\'');
+        sb.append(", accountId=").append(accountId);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
     public boolean equals(final Object o) {
         if (this == o) {
             return true;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java
index 195c7d4..7775008 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java
@@ -17,17 +17,19 @@
 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.invoice.api.Invoice;
+import com.ning.billing.util.audit.AuditLog;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class InvoiceJsonSimple {
+public class InvoiceJsonSimple extends JsonBase {
 
     private final BigDecimal amount;
     private final String invoiceId;
@@ -40,10 +42,6 @@ public class InvoiceJsonSimple {
     private final BigDecimal cba;
     private final String accountId;
 
-    public InvoiceJsonSimple() {
-        this(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, null, null, null, null, BigDecimal.ZERO, null);
-    }
-
     @JsonCreator
     public InvoiceJsonSimple(@JsonProperty("amount") final BigDecimal amount,
                              @JsonProperty("cba") final BigDecimal cba,
@@ -54,7 +52,9 @@ public class InvoiceJsonSimple {
                              @JsonProperty("targetDate") @Nullable final LocalDate targetDate,
                              @JsonProperty("invoiceNumber") @Nullable final String invoiceNumber,
                              @JsonProperty("balance") final BigDecimal balance,
-                             @JsonProperty("accountId") @Nullable final String accountId) {
+                             @JsonProperty("accountId") @Nullable final String accountId,
+                             @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+        super(auditLogs);
         this.amount = amount;
         this.cba = cba;
         this.creditAdj = creditAdj;
@@ -67,9 +67,14 @@ public class InvoiceJsonSimple {
         this.accountId = accountId;
     }
 
+    public InvoiceJsonSimple(final Invoice input, final List<AuditLog> auditLogs) {
+        this(input.getChargedAmount(), input.getCBAAmount(), input.getCreditAdjAmount(), input.getRefundAdjAmount(),
+             input.getId().toString(), input.getInvoiceDate(), input.getTargetDate(), String.valueOf(input.getInvoiceNumber()),
+             input.getBalance(), input.getAccountId().toString(), toAuditLogJson(auditLogs));
+    }
+
     public InvoiceJsonSimple(final Invoice input) {
-        this(input.getChargedAmount(), input.getCBAAmount(), input.getCreditAdjAmount(), input.getRefundAdjAmount(), input.getId().toString(), input.getInvoiceDate(),
-             input.getTargetDate(), String.valueOf(input.getInvoiceNumber()), input.getBalance(), input.getAccountId().toString());
+        this(input, null);
     }
 
     public BigDecimal getAmount() {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithBundleKeys.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithBundleKeys.java
index 5279507..e07729a 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithBundleKeys.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithBundleKeys.java
@@ -19,25 +19,21 @@ 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.invoice.api.Invoice;
+import com.ning.billing.util.audit.AuditLog;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.collect.ImmutableList;
 
 public class InvoiceJsonWithBundleKeys extends InvoiceJsonSimple {
 
     private final String bundleKeys;
     private final List<CreditJson> credits;
 
-    public InvoiceJsonWithBundleKeys() {
-        super();
-        this.bundleKeys = null;
-        this.credits = ImmutableList.<CreditJson>of();
-    }
-
     @JsonCreator
     public InvoiceJsonWithBundleKeys(@JsonProperty("amount") final BigDecimal amount,
                                      @JsonProperty("cba") final BigDecimal cba,
@@ -50,14 +46,15 @@ public class InvoiceJsonWithBundleKeys extends InvoiceJsonSimple {
                                      @JsonProperty("balance") final BigDecimal balance,
                                      @JsonProperty("accountId") final String accountId,
                                      @JsonProperty("externalBundleKeys") final String bundleKeys,
-                                     @JsonProperty("credits") final List<CreditJson> credits) {
-        super(amount, cba, creditAdj, refundAdj, invoiceId, invoiceDate, targetDate, invoiceNumber, balance, accountId);
+                                     @JsonProperty("credits") final List<CreditJson> credits,
+                                     @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+        super(amount, cba, creditAdj, refundAdj, invoiceId, invoiceDate, targetDate, invoiceNumber, balance, accountId, auditLogs);
         this.bundleKeys = bundleKeys;
         this.credits = credits;
     }
 
-    public InvoiceJsonWithBundleKeys(final Invoice input, final String bundleKeys, final List<CreditJson> credits) {
-        super(input);
+    public InvoiceJsonWithBundleKeys(final Invoice input, final String bundleKeys, final List<CreditJson> credits, final List<AuditLog> auditLogs) {
+        super(input, auditLogs);
         this.bundleKeys = bundleKeys;
         this.credits = credits;
     }
@@ -82,14 +79,24 @@ public class InvoiceJsonWithBundleKeys extends InvoiceJsonSimple {
 
     @Override
     public boolean equals(final Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        if (!super.equals(o)) return false;
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
 
         final InvoiceJsonWithBundleKeys that = (InvoiceJsonWithBundleKeys) o;
 
-        if (bundleKeys != null ? !bundleKeys.equals(that.bundleKeys) : that.bundleKeys != null) return false;
-        if (credits != null ? !credits.equals(that.credits) : that.credits != null) return false;
+        if (bundleKeys != null ? !bundleKeys.equals(that.bundleKeys) : that.bundleKeys != null) {
+            return false;
+        }
+        if (credits != null ? !credits.equals(that.credits) : that.credits != null) {
+            return false;
+        }
 
         return true;
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithItems.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithItems.java
index 0f73274..b866f3c 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithItems.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonWithItems.java
@@ -21,6 +21,8 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.LocalDate;
 
 import com.ning.billing.invoice.api.Invoice;
@@ -44,8 +46,9 @@ public class InvoiceJsonWithItems extends InvoiceJsonSimple {
                                 @JsonProperty("invoiceNumber") final String invoiceNumber,
                                 @JsonProperty("balance") final BigDecimal balance,
                                 @JsonProperty("accountId") final String accountId,
-                                @JsonProperty("items") final List<InvoiceItemJsonSimple> items) {
-        super(amount, cba, creditAdj, refundAdj, invoiceId, invoiceDate, targetDate, invoiceNumber, balance, accountId);
+                                @JsonProperty("items") final List<InvoiceItemJsonSimple> items,
+                                @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+        super(amount, cba, creditAdj, refundAdj, invoiceId, invoiceDate, targetDate, invoiceNumber, balance, accountId, auditLogs);
         this.items = new ArrayList<InvoiceItemJsonSimple>(items);
     }
 
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
new file mode 100644
index 0000000..26fd3f5
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/JsonBase.java
@@ -0,0 +1,53 @@
+/*
+ * 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.List;
+
+import javax.annotation.Nullable;
+
+import com.ning.billing.util.audit.AuditLog;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+
+public abstract class JsonBase {
+
+    protected List<AuditLogJson> auditLogs;
+
+    public JsonBase(@Nullable final List<AuditLogJson> auditLogs) {
+        this.auditLogs = auditLogs;
+    }
+
+    protected static ImmutableList<AuditLogJson> toAuditLogJson(@Nullable final List<AuditLog> auditLogs) {
+        if (auditLogs == null) {
+            return null;
+        }
+
+        return ImmutableList.<AuditLogJson>copyOf(Collections2.transform(auditLogs, new Function<AuditLog, AuditLogJson>() {
+            @Override
+            public AuditLogJson apply(@Nullable final AuditLog input) {
+                return new AuditLogJson(input);
+            }
+        }));
+    }
+
+    public List<AuditLogJson> getAuditLogs() {
+        return auditLogs;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java
index 85fb420..360202b 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java
@@ -19,15 +19,19 @@ package com.ning.billing.jaxrs.json;
 import java.math.BigDecimal;
 import java.util.List;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.payment.api.Payment;
-import com.ning.billing.payment.api.Payment.PaymentAttempt;
+import com.ning.billing.util.audit.AuditLog;
 import com.ning.billing.util.clock.DefaultClock;
 
-public class PaymentJsonSimple {
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class PaymentJsonSimple extends JsonBase {
+
     private final BigDecimal paidAmount;
 
     private final BigDecimal amount;
@@ -58,25 +62,6 @@ public class PaymentJsonSimple {
 
     private final String extSecondPaymentIdRef;
 
-    public PaymentJsonSimple() {
-        this.amount = null;
-        this.paidAmount = null;
-        this.invoiceId = null;
-        this.accountId = null;
-        this.paymentId = null;
-        this.paymentMethodId = null;
-        this.requestedDate = null;
-        this.effectiveDate = null;
-        this.currency = null;
-        this.retryCount = null;
-        this.status = null;
-        this.gatewayErrorCode = null;
-        this.gatewayErrorMsg = null;
-        this.extFirstPaymentIdRef = null;
-        this.extSecondPaymentIdRef = null;
-
-    }
-
     @JsonCreator
     public PaymentJsonSimple(@JsonProperty("amount") final BigDecimal amount,
                              @JsonProperty("paidAmount") final BigDecimal paidAmount,
@@ -92,8 +77,9 @@ public class PaymentJsonSimple {
                              @JsonProperty("gatewayErrorCode") final String gatewayErrorCode,
                              @JsonProperty("gatewayErrorMsg") final String gatewayErrorMsg,
                              @JsonProperty("extFirstPaymentIdRef") final String extFirstPaymentIdRef,
-                             @JsonProperty("extSecondPaymentIdRef") final String extSecondPaymentIdRef) {
-        super();
+                             @JsonProperty("extSecondPaymentIdRef") final String extSecondPaymentIdRef,
+                             @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+        super(auditLogs);
         this.amount = amount;
         this.paidAmount = paidAmount;
         this.invoiceId = invoiceId;
@@ -111,22 +97,16 @@ public class PaymentJsonSimple {
         this.extSecondPaymentIdRef = extSecondPaymentIdRef;
     }
 
-    public PaymentJsonSimple(final Payment src) {
-        this.amount = src.getAmount();
-        this.paidAmount =  src.getPaidAmount();
-        this.invoiceId = src.getInvoiceId().toString();
-        this.accountId = src.getAccountId().toString();
-        this.paymentId = src.getId().toString();
-        this.paymentMethodId =src.getPaymentMethodId().toString();
-        this.requestedDate = src.getEffectiveDate();
-        this.effectiveDate = src.getEffectiveDate();
-        this.currency = src.getCurrency().toString();
-        this.retryCount = src.getAttempts().size();
-        this.gatewayErrorCode = src.getAttempts().get(retryCount - 1).getGatewayErrorCode();
-        this.gatewayErrorMsg = src.getAttempts().get(retryCount - 1).getGatewayErrorMsg();;
-        this.status = src.getPaymentStatus().toString();
-        this.extFirstPaymentIdRef = src.getExtFirstPaymentIdRef();
-        this.extSecondPaymentIdRef = src.getExtSecondPaymentIdRef();
+    public PaymentJsonSimple(final Payment src, final List<AuditLog> auditLogs) {
+        this(src.getAmount(), src.getPaidAmount(), src.getAccountId().toString(), src.getInvoiceId().toString(),
+             src.getId().toString(), src.getPaymentMethodId().toString(), src.getEffectiveDate(), src.getEffectiveDate(),
+             src.getAttempts().size(), src.getCurrency().toString(), src.getPaymentStatus().toString(),
+             src.getAttempts().get(src.getAttempts().size() - 1).getGatewayErrorCode(), src.getAttempts().get(src.getAttempts().size() - 1).getGatewayErrorMsg(),
+             src.getExtFirstPaymentIdRef(), src.getExtSecondPaymentIdRef(), toAuditLogJson(auditLogs));
+    }
+
+    public PaymentJsonSimple(final Payment payment) {
+        this(payment, null);
     }
 
     public BigDecimal getPaidAmount() {
@@ -137,7 +117,6 @@ public class PaymentJsonSimple {
         return invoiceId;
     }
 
-
     public String getPaymentId() {
         return paymentId;
     }
@@ -205,28 +184,28 @@ public class PaymentJsonSimple {
             return false;
         }
         if (!((amount == null && that.amount == null) ||
-                (amount != null && that.amount != null && amount.compareTo(that.amount) == 0))) {
+              (amount != null && that.amount != null && amount.compareTo(that.amount) == 0))) {
             return false;
         }
         if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
             return false;
         }
         if (!((effectiveDate == null && that.effectiveDate == null) ||
-                (effectiveDate != null && that.effectiveDate != null && effectiveDate.compareTo(that.effectiveDate) == 0))) {
+              (effectiveDate != null && that.effectiveDate != null && effectiveDate.compareTo(that.effectiveDate) == 0))) {
             return false;
         }
         if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
             return false;
         }
         if (!((paidAmount == null && that.paidAmount == null) ||
-                (paidAmount != null && that.paidAmount != null && paidAmount.compareTo(that.paidAmount) == 0))) {
+              (paidAmount != null && that.paidAmount != null && paidAmount.compareTo(that.paidAmount) == 0))) {
             return false;
         }
         if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
             return false;
         }
         if (!((requestedDate == null && that.requestedDate == null) ||
-                (requestedDate != null && that.requestedDate != null && requestedDate.compareTo(that.requestedDate) == 0))) {
+              (requestedDate != null && that.requestedDate != null && requestedDate.compareTo(that.requestedDate) == 0))) {
             return false;
         }
         if (retryCount != null ? !retryCount.equals(that.retryCount) : that.retryCount != null) {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonWithBundleKeys.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonWithBundleKeys.java
index ec87e78..d7029dc 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonWithBundleKeys.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonWithBundleKeys.java
@@ -18,12 +18,17 @@ package com.ning.billing.jaxrs.json;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
 
 import org.joda.time.DateTime;
 
+import com.ning.billing.payment.api.Payment;
+import com.ning.billing.util.audit.AuditLog;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.collect.ImmutableList;
 
 public class PaymentJsonWithBundleKeys extends PaymentJsonSimple {
 
@@ -31,13 +36,6 @@ public class PaymentJsonWithBundleKeys extends PaymentJsonSimple {
     private final List<RefundJson> refunds;
     private final List<ChargebackJson> chargebacks;
 
-    public PaymentJsonWithBundleKeys() {
-        super();
-        this.bundleKeys = null;
-        this.refunds = ImmutableList.<RefundJson>of();
-        this.chargebacks = ImmutableList.<ChargebackJson>of();
-    }
-
     @JsonCreator
     public PaymentJsonWithBundleKeys(@JsonProperty("amount") final BigDecimal amount,
                                      @JsonProperty("paidAmount") final BigDecimal paidAmount,
@@ -56,14 +54,30 @@ public class PaymentJsonWithBundleKeys extends PaymentJsonSimple {
                                      @JsonProperty("extSecondPaymentIdRef") final String extSecondPaymentIdRef,
                                      @JsonProperty("externalBundleKeys") final String bundleKeys,
                                      @JsonProperty("refunds") final List<RefundJson> refunds,
-                                     @JsonProperty("chargebacks") final List<ChargebackJson> chargebacks) {
-        super(amount, paidAmount, accountId, invoiceId, paymentId, paymentMethodId, requestedDate, effectiveDate, retryCount, currency, status, gatewayErrorCode, gatewayErrorMsg,
-                extFirstPaymentIdRef, extSecondPaymentIdRef);
+                                     @JsonProperty("chargebacks") final List<ChargebackJson> chargebacks,
+                                     @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+        super(amount, paidAmount, accountId, invoiceId, paymentId, paymentMethodId, requestedDate, effectiveDate,
+              retryCount, currency, status, gatewayErrorCode, gatewayErrorMsg, extFirstPaymentIdRef,
+              extSecondPaymentIdRef, auditLogs);
         this.bundleKeys = bundleKeys;
         this.refunds = refunds;
         this.chargebacks = chargebacks;
     }
 
+    public PaymentJsonWithBundleKeys(final Payment payment, final String status, final int nbOfPaymentAttempts, final String bundleExternalKey,
+                                     final UUID accountId, final List<RefundJson> refunds, final List<ChargebackJson> chargebacks,
+                                     final List<AuditLog> auditLogs) {
+        this(payment.getAmount(), payment.getPaidAmount(), accountId.toString(),
+             payment.getInvoiceId().toString(), payment.getId().toString(),
+             payment.getPaymentMethodId().toString(),
+             payment.getEffectiveDate(), payment.getEffectiveDate(),
+             nbOfPaymentAttempts, payment.getCurrency().toString(), status,
+             payment.getAttempts().get(nbOfPaymentAttempts - 1).getGatewayErrorCode(),
+             payment.getAttempts().get(nbOfPaymentAttempts - 1).getGatewayErrorMsg(),
+             payment.getExtFirstPaymentIdRef(), payment.getExtSecondPaymentIdRef(),
+             bundleExternalKey, refunds, chargebacks, toAuditLogJson(auditLogs));
+    }
+
     public String getBundleKeys() {
         return bundleKeys;
     }
@@ -89,15 +103,27 @@ public class PaymentJsonWithBundleKeys extends PaymentJsonSimple {
 
     @Override
     public boolean equals(final Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        if (!super.equals(o)) return false;
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
 
         final PaymentJsonWithBundleKeys that = (PaymentJsonWithBundleKeys) o;
 
-        if (bundleKeys != null ? !bundleKeys.equals(that.bundleKeys) : that.bundleKeys != null) return false;
-        if (chargebacks != null ? !chargebacks.equals(that.chargebacks) : that.chargebacks != null) return false;
-        if (refunds != null ? !refunds.equals(that.refunds) : that.refunds != null) return false;
+        if (bundleKeys != null ? !bundleKeys.equals(that.bundleKeys) : that.bundleKeys != null) {
+            return false;
+        }
+        if (chargebacks != null ? !chargebacks.equals(that.chargebacks) : that.chargebacks != null) {
+            return false;
+        }
+        if (refunds != null ? !refunds.equals(that.refunds) : that.refunds != null) {
+            return false;
+        }
 
         return true;
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
index 20d0320..c2621ff 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
@@ -18,8 +18,10 @@ package com.ning.billing.jaxrs.resources;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import javax.ws.rs.Consumes;
@@ -50,6 +52,7 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.invoice.api.InvoiceUserApi;
@@ -69,10 +72,12 @@ import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentMethod;
 import com.ning.billing.payment.api.Refund;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.audit.AuditLog;
 import com.ning.billing.util.dao.ObjectType;
 
 import com.google.common.base.Function;
@@ -107,9 +112,10 @@ public class AccountResource extends JaxRsResourceBase {
                            final PaymentApi paymentApi,
                            final EntitlementTimelineApi timelineApi,
                            final TagUserApi tagUserApi,
+                           final AuditUserApi auditUserApi,
                            final CustomFieldUserApi customFieldUserApi,
                            final Context context) {
-        super(uriBuilder, tagUserApi, customFieldUserApi);
+        super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi);
         this.accountApi = accountApi;
         this.entitlementApi = entitlementApi;
         this.invoiceApi = invoiceApi;
@@ -133,7 +139,7 @@ public class AccountResource extends JaxRsResourceBase {
     @Path("/{accountId:" + UUID_PATTERN + "}/" + BUNDLES)
     @Produces(APPLICATION_JSON)
     public Response getAccountBundles(@PathParam("accountId") final String accountId, @QueryParam(QUERY_EXTERNAL_KEY) final String externalKey)
-        throws AccountApiException, EntitlementUserApiException {
+            throws AccountApiException, EntitlementUserApiException {
 
         final UUID uuid = UUID.fromString(accountId);
         accountApi.getAccountById(uuid);
@@ -210,50 +216,75 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + TIMELINE)
     @Produces(APPLICATION_JSON)
-    public Response getAccountTimeline(@PathParam("accountId") final String accountIdString) throws AccountApiException, PaymentApiException, EntitlementRepairException {
+    public Response getAccountTimeline(@PathParam("accountId") final String accountIdString,
+                                       @QueryParam("audit") @DefaultValue("false") final Boolean withAudit) throws AccountApiException, PaymentApiException, EntitlementRepairException {
         final UUID accountId = UUID.fromString(accountIdString);
         final Account account = accountApi.getAccountById(accountId);
 
         // Get the invoices
         final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
+        final Map<UUID, List<AuditLog>> invoiceAuditLogs = new HashMap<UUID, List<AuditLog>>();
+        final Map<UUID, List<AuditLog>> invoiceItemsAuditLogs = new HashMap<UUID, List<AuditLog>>();
+        if (withAudit) {
+            for (final Invoice invoice : invoices) {
+                invoiceAuditLogs.put(invoice.getId(), auditUserApi.getAuditLogs(invoice.getId(), ObjectType.INVOICE));
+                for (final InvoiceItem invoiceItem : invoice.getInvoiceItems()) {
+                    invoiceItemsAuditLogs.put(invoiceItem.getId(), auditUserApi.getAuditLogs(invoiceItem.getId(), ObjectType.INVOICE_ITEM));
+                }
+            }
+        }
 
         // Get the payments
         final List<Payment> payments = paymentApi.getAccountPayments(accountId);
+        final Map<UUID, List<AuditLog>> paymentsAuditLogs = new HashMap<UUID, List<AuditLog>>();
+        if (withAudit) {
+            for (final Payment payment : payments) {
+                paymentsAuditLogs.put(payment.getId(), auditUserApi.getAuditLogs(payment.getId(), ObjectType.PAYMENT));
+            }
+        }
 
         // Get the refunds
         final List<Refund> refunds = paymentApi.getAccountRefunds(account);
+        final Map<UUID, List<AuditLog>> refundsAuditLogs = new HashMap<UUID, List<AuditLog>>();
         final Multimap<UUID, Refund> refundsByPayment = ArrayListMultimap.<UUID, Refund>create();
         for (final Refund refund : refunds) {
+            if (withAudit) {
+                refundsAuditLogs.put(refund.getId(), auditUserApi.getAuditLogs(refund.getId(), ObjectType.REFUND));
+            }
             refundsByPayment.put(refund.getPaymentId(), refund);
         }
 
         // Get the chargebacks
         final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(accountId);
+        final Map<UUID, List<AuditLog>> chargebacksAuditLogs = new HashMap<UUID, List<AuditLog>>();
         final Multimap<UUID, InvoicePayment> chargebacksByPayment = ArrayListMultimap.<UUID, InvoicePayment>create();
         for (final InvoicePayment chargeback : chargebacks) {
+            chargebacksAuditLogs.put(chargeback.getId(), auditUserApi.getAuditLogs(chargeback.getId(), ObjectType.INVOICE_PAYMENT));
             chargebacksByPayment.put(chargeback.getPaymentId(), chargeback);
         }
 
         // Get the bundles
         final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(account.getId());
+        final Map<UUID, List<AuditLog>> bundlesAuditLogs = new HashMap<UUID, List<AuditLog>>();
         final List<BundleTimeline> bundlesTimeline = new LinkedList<BundleTimeline>();
-        for (final SubscriptionBundle cur : bundles) {
-            bundlesTimeline.add(timelineApi.getBundleTimeline(cur.getId()));
+        for (final SubscriptionBundle bundle : bundles) {
+            if (withAudit) {
+                bundlesAuditLogs.put(bundle.getId(), auditUserApi.getAuditLogs(bundle.getId(), ObjectType.BUNDLE));
+            }
+            bundlesTimeline.add(timelineApi.getBundleTimeline(bundle.getId()));
         }
 
         final AccountTimelineJson json = new AccountTimelineJson(account, invoices, payments, bundlesTimeline,
-                                                                 refundsByPayment, chargebacksByPayment);
+                                                                 refundsByPayment, chargebacksByPayment, invoiceAuditLogs,
+                                                                 invoiceItemsAuditLogs, paymentsAuditLogs, refundsAuditLogs,
+                                                                 chargebacksAuditLogs, bundlesAuditLogs);
 
         return Response.status(Status.OK).entity(json).build();
     }
 
-
-
-
-
     /*
-     * ************************** EMAIL NOTIFICATIONS FOR INVOICES ********************************
-     */
+    * ************************** EMAIL NOTIFICATIONS FOR INVOICES ********************************
+    */
 
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + EMAIL_NOTIFICATIONS)
@@ -296,8 +327,8 @@ public class AccountResource extends JaxRsResourceBase {
                                 @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) throws PaymentApiException {
         final List<Payment> payments = paymentApi.getAccountPayments(UUID.fromString(accountId));
         final List<PaymentJsonSimple> result = new ArrayList<PaymentJsonSimple>(payments.size());
-        for (final Payment cur : payments) {
-            result.add(new PaymentJsonSimple(cur));
+        for (final Payment payment : payments) {
+            result.add(new PaymentJsonSimple(payment));
         }
         return Response.status(Status.OK).entity(result).build();
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
index 20560e6..a824149 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
@@ -115,8 +115,8 @@ public class InvoiceResource extends JaxRsResourceBase {
 
         final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(UUID.fromString(accountId));
         final List<InvoiceJsonSimple> result = new LinkedList<InvoiceJsonSimple>();
-        for (final Invoice cur : invoices) {
-            result.add(new InvoiceJsonSimple(cur));
+        for (final Invoice invoice : invoices) {
+            result.add(new InvoiceJsonSimple(invoice));
         }
 
         return Response.status(Status.OK).entity(result).build();
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
index 5443667..6f2d2f1 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
 
 import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.AuditUserApi;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.api.TagDefinitionApiException;
@@ -55,17 +56,26 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
     protected final JaxrsUriBuilder uriBuilder;
     protected final TagUserApi tagUserApi;
     protected final CustomFieldUserApi customFieldUserApi;
-
-    protected abstract ObjectType getObjectType();
+    protected final AuditUserApi auditUserApi;
 
     protected final DateTimeFormatter DATE_TIME_FORMATTER = ISODateTimeFormat.dateTime();
 
     public JaxRsResourceBase(final JaxrsUriBuilder uriBuilder,
                              final TagUserApi tagUserApi,
-                             final CustomFieldUserApi customFieldUserApi) {
+                             final CustomFieldUserApi customFieldUserApi,
+                             final AuditUserApi auditUserApi) {
         this.uriBuilder = uriBuilder;
         this.tagUserApi = tagUserApi;
         this.customFieldUserApi = customFieldUserApi;
+        this.auditUserApi = auditUserApi;
+    }
+
+    protected abstract ObjectType getObjectType();
+
+    public JaxRsResourceBase(final JaxrsUriBuilder uriBuilder,
+                             final TagUserApi tagUserApi,
+                             final CustomFieldUserApi customFieldUserApi) {
+        this(uriBuilder, tagUserApi, customFieldUserApi, null);
     }
 
     protected Response getTags(final UUID id) throws TagDefinitionApiException {
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/JaxrsTestSuite.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/JaxrsTestSuite.java
index 51e2ac7..9018ab0 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/JaxrsTestSuite.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/JaxrsTestSuite.java
@@ -16,7 +16,37 @@
 
 package com.ning.billing.jaxrs;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
 import com.ning.billing.KillbillTestSuite;
+import com.ning.billing.jaxrs.json.AuditLogJson;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.ClockMock;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.joda.JodaModule;
 
 public abstract class JaxrsTestSuite extends KillbillTestSuite {
+
+    private final Clock clock = new ClockMock();
+
+    protected static final ObjectMapper mapper = new ObjectMapper();
+
+    static {
+        mapper.registerModule(new JodaModule());
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+    }
+
+    protected List<AuditLogJson> createAuditLogsJson() {
+        final List<AuditLogJson> auditLogs = new ArrayList<AuditLogJson>();
+        for (int i = 0; i < 20; i++) {
+            auditLogs.add(new AuditLogJson(UUID.randomUUID().toString(), clock.getUTCNow(), UUID.randomUUID().toString(),
+                                           UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString()));
+        }
+
+        return auditLogs;
+    }
 }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonNoSubscriptions.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonNoSubscriptions.java
index 4c819e8..d87274a 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonNoSubscriptions.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonNoSubscriptions.java
@@ -16,34 +16,31 @@
 
 package com.ning.billing.jaxrs.json;
 
+import java.util.List;
 import java.util.UUID;
 
 import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.jaxrs.JaxrsTestSuite;
 
 public class TestBundleJsonNoSubscriptions extends JaxrsTestSuite {
-    private static final ObjectMapper mapper = new ObjectMapper();
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
         final String bundleId = UUID.randomUUID().toString();
         final String accountId = UUID.randomUUID().toString();
         final String externalKey = UUID.randomUUID().toString();
-        final BundleJsonNoSubscriptions bundleJsonNoSubscriptions = new BundleJsonNoSubscriptions(bundleId, accountId, externalKey);
+        final List<AuditLogJson> auditLogs = createAuditLogsJson();
+        final BundleJsonNoSubscriptions bundleJsonNoSubscriptions = new BundleJsonNoSubscriptions(bundleId, accountId, externalKey, null, auditLogs);
         Assert.assertEquals(bundleJsonNoSubscriptions.getBundleId(), bundleId);
         Assert.assertEquals(bundleJsonNoSubscriptions.getAccountId(), accountId);
         Assert.assertEquals(bundleJsonNoSubscriptions.getExternalKey(), externalKey);
+        Assert.assertEquals(bundleJsonNoSubscriptions.getAuditLogs(), auditLogs);
 
         final String asJson = mapper.writeValueAsString(bundleJsonNoSubscriptions);
-        Assert.assertEquals(asJson, "{\"bundleId\":\"" + bundleJsonNoSubscriptions.getBundleId() + "\"," +
-                "\"accountId\":\"" + bundleJsonNoSubscriptions.getAccountId() + "\"," +
-                "\"externalKey\":\"" + bundleJsonNoSubscriptions.getExternalKey() + "\"}");
-
         final BundleJsonNoSubscriptions fromJson = mapper.readValue(asJson, BundleJsonNoSubscriptions.class);
         Assert.assertEquals(fromJson, bundleJsonNoSubscriptions);
     }
@@ -62,5 +59,6 @@ public class TestBundleJsonNoSubscriptions extends JaxrsTestSuite {
         Assert.assertEquals(bundleJsonNoSubscriptions.getBundleId(), bundleId.toString());
         Assert.assertEquals(bundleJsonNoSubscriptions.getExternalKey(), externalKey);
         Assert.assertEquals(bundleJsonNoSubscriptions.getAccountId(), accountId.toString());
+        Assert.assertNull(bundleJsonNoSubscriptions.getAuditLogs());
     }
 }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonSimple.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonSimple.java
index e00ed56..62e56d3 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonSimple.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonSimple.java
@@ -16,29 +16,27 @@
 
 package com.ning.billing.jaxrs.json;
 
+import java.util.List;
 import java.util.UUID;
 
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.ning.billing.jaxrs.JaxrsTestSuite;
 
 public class TestBundleJsonSimple extends JaxrsTestSuite {
-    private static final ObjectMapper mapper = new ObjectMapper();
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
         final String bundleId = UUID.randomUUID().toString();
         final String externalKey = UUID.randomUUID().toString();
-        final BundleJsonSimple bundleJsonSimple = new BundleJsonSimple(bundleId, externalKey);
+        final List<AuditLogJson> auditLogs = createAuditLogsJson();
+        final BundleJsonSimple bundleJsonSimple = new BundleJsonSimple(bundleId, externalKey, auditLogs);
         Assert.assertEquals(bundleJsonSimple.getBundleId(), bundleId);
         Assert.assertEquals(bundleJsonSimple.getExternalKey(), externalKey);
+        Assert.assertEquals(bundleJsonSimple.getAuditLogs(), auditLogs);
 
         final String asJson = mapper.writeValueAsString(bundleJsonSimple);
-        Assert.assertEquals(asJson, "{\"bundleId\":\"" + bundleJsonSimple.getBundleId() + "\"," +
-                "\"externalKey\":\"" + bundleJsonSimple.getExternalKey() + "\"}");
-
         final BundleJsonSimple fromJson = mapper.readValue(asJson, BundleJsonSimple.class);
         Assert.assertEquals(fromJson, bundleJsonSimple);
     }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
index 84cac3c..36e328b 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.jaxrs.json;
 
+import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -24,10 +25,6 @@ import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.datatype.joda.JodaModule;
-import com.google.common.collect.ImmutableList;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
@@ -35,17 +32,12 @@ import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.timeline.BundleTimeline;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.jaxrs.JaxrsTestSuite;
 import com.ning.billing.util.clock.DefaultClock;
 
-public class TestBundleJsonWithSubscriptions extends JaxrsTestSuite {
-    private static final ObjectMapper mapper = new ObjectMapper();
+import com.google.common.collect.ImmutableList;
 
-    static {
-        mapper.registerModule(new JodaModule());
-        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
-    }
+public class TestBundleJsonWithSubscriptions extends JaxrsTestSuite {
 
     @Test(groups = "fast")
     public void testJson() throws Exception {
@@ -67,24 +59,14 @@ public class TestBundleJsonWithSubscriptions extends JaxrsTestSuite {
         final UUID bundleId = UUID.randomUUID();
         final String externalKey = UUID.randomUUID().toString();
         final SubscriptionJsonWithEvents subscription = new SubscriptionJsonWithEvents(bundleId, subscriptionTimeline);
-        final BundleJsonWithSubscriptions bundleJsonWithSubscriptions = new BundleJsonWithSubscriptions(bundleId.toString(), externalKey, ImmutableList.<SubscriptionJsonWithEvents>of(subscription));
+        final List<AuditLogJson> auditLogs = createAuditLogsJson();
+        final BundleJsonWithSubscriptions bundleJsonWithSubscriptions = new BundleJsonWithSubscriptions(bundleId.toString(), externalKey, ImmutableList.<SubscriptionJsonWithEvents>of(subscription), auditLogs);
         Assert.assertEquals(bundleJsonWithSubscriptions.getBundleId(), bundleId.toString());
         Assert.assertEquals(bundleJsonWithSubscriptions.getExternalKey(), externalKey);
         Assert.assertEquals(bundleJsonWithSubscriptions.getSubscriptions().size(), 1);
+        Assert.assertEquals(bundleJsonWithSubscriptions.getAuditLogs(), auditLogs);
 
         final String asJson = mapper.writeValueAsString(bundleJsonWithSubscriptions);
-        Assert.assertEquals(asJson, "{\"bundleId\":\"" + bundleJsonWithSubscriptions.getBundleId() + "\"," +
-                "\"externalKey\":\"" + bundleJsonWithSubscriptions.getExternalKey() + "\"," +
-                "\"subscriptions\":[{\"events\":[{\"eventId\":\"" + event.getEventId().toString() + "\"," +
-                "\"billingPeriod\":\"" + event.getPlanPhaseSpecifier().getBillingPeriod().toString() + "\"," +
-                "\"product\":\"" + event.getPlanPhaseSpecifier().getProductName() + "\"," +
-                "\"priceList\":\"" + event.getPlanPhaseSpecifier().getPriceListName() + "\"," +
-                "\"eventType\":\"" + event.getSubscriptionTransitionType().toString() + "\"," +
-                "\"phase\":\"" + event.getPlanPhaseSpecifier().getPhaseType() + "\"," +
-                "\"requestedDate\":null," +
-                "\"effectiveDate\":\"" + event.getEffectiveDate().toDateTimeISO().toString() + "\"}]," +
-                "\"subscriptionId\":\"" + subscriptionTimeline.getId().toString() + "\",\"deletedEvents\":null,\"newEvents\":null}]}");
-
         final BundleJsonWithSubscriptions fromJson = mapper.readValue(asJson, BundleJsonWithSubscriptions.class);
         Assert.assertEquals(fromJson, bundleJsonWithSubscriptions);
     }
@@ -113,7 +95,7 @@ public class TestBundleJsonWithSubscriptions extends JaxrsTestSuite {
         Mockito.when(bundleTimeline.getExternalKey()).thenReturn(externalKey);
         Mockito.when(bundleTimeline.getSubscriptions()).thenReturn(ImmutableList.<SubscriptionTimeline>of(subscriptionTimeline));
 
-        final BundleJsonWithSubscriptions bundleJsonWithSubscriptions = new BundleJsonWithSubscriptions(null, bundleTimeline);
+        final BundleJsonWithSubscriptions bundleJsonWithSubscriptions = new BundleJsonWithSubscriptions(null, bundleTimeline, null);
         Assert.assertEquals(bundleJsonWithSubscriptions.getBundleId(), bundleId.toString());
         Assert.assertEquals(bundleJsonWithSubscriptions.getExternalKey(), externalKey);
         Assert.assertEquals(bundleJsonWithSubscriptions.getSubscriptions().size(), 1);
@@ -124,19 +106,21 @@ public class TestBundleJsonWithSubscriptions extends JaxrsTestSuite {
         // Note - ms are truncated
         Assert.assertEquals(events.getEvents().get(0).getEffectiveDate(), DefaultClock.toUTCDateTime(effectiveDate));
         Assert.assertEquals(events.getEvents().get(0).getEventId(), eventId.toString());
+        Assert.assertNull(bundleJsonWithSubscriptions.getAuditLogs());
     }
 
     @Test(groups = "fast")
     public void testFromSubscriptionBundle() throws Exception {
-        final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
+        final BundleTimeline bundle = Mockito.mock(BundleTimeline.class);
         final UUID bundleId = UUID.randomUUID();
         final String externalKey = UUID.randomUUID().toString();
-        Mockito.when(bundle.getId()).thenReturn(bundleId);
-        Mockito.when(bundle.getKey()).thenReturn(externalKey);
+        Mockito.when(bundle.getBundleId()).thenReturn(bundleId);
+        Mockito.when(bundle.getExternalKey()).thenReturn(externalKey);
 
-        final BundleJsonWithSubscriptions bundleJsonWithSubscriptions = new BundleJsonWithSubscriptions(bundle);
+        final BundleJsonWithSubscriptions bundleJsonWithSubscriptions = new BundleJsonWithSubscriptions(null, bundle, null);
         Assert.assertEquals(bundleJsonWithSubscriptions.getBundleId(), bundleId.toString());
         Assert.assertEquals(bundleJsonWithSubscriptions.getExternalKey(), externalKey);
-        Assert.assertNull(bundleJsonWithSubscriptions.getSubscriptions());
+        Assert.assertEquals(bundleJsonWithSubscriptions.getSubscriptions().size(), 0);
+        Assert.assertNull(bundleJsonWithSubscriptions.getAuditLogs());
     }
 }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleTimelineJson.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleTimelineJson.java
index c798b24..17df65d 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleTimelineJson.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleTimelineJson.java
@@ -35,22 +35,12 @@ import com.ning.billing.jaxrs.JaxrsTestSuite;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.datatype.joda.JodaModule;
 import com.google.common.collect.ImmutableList;
 
 public class TestBundleTimelineJson extends JaxrsTestSuite {
 
-    private static final ObjectMapper mapper = new ObjectMapper();
-
     private final Clock clock = new DefaultClock();
 
-    static {
-        mapper.registerModule(new JodaModule());
-        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
-    }
-
     @Test(groups = "fast")
     public void testJson() throws Exception {
         final String viewId = UUID.randomUUID().toString();
@@ -59,63 +49,15 @@ public class TestBundleTimelineJson extends JaxrsTestSuite {
         final BundleJsonWithSubscriptions bundleJsonWithSubscriptions = createBundleWithSubscriptions();
         final InvoiceJsonSimple invoiceJsonSimple = createInvoice();
         final PaymentJsonSimple paymentJsonSimple = createPayment(UUID.fromString(invoiceJsonSimple.getAccountId()),
-                UUID.fromString(invoiceJsonSimple.getInvoiceId()));
+                                                                  UUID.fromString(invoiceJsonSimple.getInvoiceId()));
 
         final BundleTimelineJson bundleTimelineJson = new BundleTimelineJson(viewId,
-                bundleJsonWithSubscriptions,
-                ImmutableList.<PaymentJsonSimple>of(paymentJsonSimple),
-                ImmutableList.<InvoiceJsonSimple>of(invoiceJsonSimple),
-                reason);
+                                                                             bundleJsonWithSubscriptions,
+                                                                             ImmutableList.<PaymentJsonSimple>of(paymentJsonSimple),
+                                                                             ImmutableList.<InvoiceJsonSimple>of(invoiceJsonSimple),
+                                                                             reason);
 
         final String asJson = mapper.writeValueAsString(bundleTimelineJson);
-
-        final SubscriptionJsonWithEvents subscription = bundleTimelineJson.getBundle().getSubscriptions().get(0);
-        final SubscriptionJsonWithEvents.SubscriptionReadEventJson event = subscription.getEvents().get(0);
-        final PaymentJsonSimple payment = bundleTimelineJson.getPayments().get(0);
-        final InvoiceJsonSimple invoice = bundleTimelineJson.getInvoices().get(0);
-
-        Assert.assertEquals(asJson, "{\"viewId\":\"" + bundleTimelineJson.getViewId() + "\"," +
-            "\"bundle\":{\"bundleId\":\"" + bundleTimelineJson.getBundle().getBundleId() + "\"," +
-            "\"externalKey\":\"" + bundleTimelineJson.getBundle().getExternalKey() + "\"," +
-            "\"subscriptions\":" +
-            "[{\"events\":[{\"eventId\":\"" + event.getEventId() + "\"," +
-            "\"billingPeriod\":\"" + event.getBillingPeriod() + "\"," +
-            "\"product\":\"" + event.getProduct() + "\"," +
-            "\"priceList\":\"" + event.getPriceList() + "\"," +
-            "\"eventType\":\"" + event.getEventType() + "\"," +
-            "\"phase\":\"" + event.getPhase() + "\"," +
-            "\"requestedDate\":null," +
-            "\"effectiveDate\":\"" + event.getEffectiveDate().toDateTimeISO().toString() + "\"}]," +
-            "\"subscriptionId\":\"" + subscription.getSubscriptionId() + "\"," +
-            "\"deletedEvents\":null," +
-            "\"newEvents\":null}]}," +
-            "\"payments\":[{\"amount\":" + payment.getAmount() + "," +
-            "\"paidAmount\":" + payment.getPaidAmount() + "," +
-            "\"accountId\":\"" + payment.getAccountId() + "\"," +
-            "\"invoiceId\":\"" + payment.getInvoiceId() + "\"," +
-            "\"paymentId\":\"" + payment.getPaymentId() + "\"," +
-            "\"paymentMethodId\":\"" + payment.getPaymentMethodId() + "\"," +
-            "\"requestedDate\":\"" + payment.getRequestedDate().toDateTimeISO().toString() + "\"," +
-            "\"effectiveDate\":\"" + payment.getEffectiveDate().toDateTimeISO().toString() + "\"," +
-            "\"retryCount\":" + payment.getRetryCount() + "," +
-            "\"currency\":\"" + payment.getCurrency() + "\"," +
-            "\"status\":\"" + payment.getStatus() + "\"," +
-            "\"gatewayErrorCode\":\"" + payment.getGatewayErrorCode() + "\"," +
-            "\"gatewayErrorMsg\":\"" + payment.getGatewayErrorMsg() + "\"," +
-            "\"extFirstPaymentIdRef\":\"" + payment.getExtFirstPaymentIdRef() + "\"," +
-            "\"extSecondPaymentIdRef\":\"" + payment.getExtSecondPaymentIdRef() + "\"}]," +
-            "\"invoices\":[{\"amount\":" + invoice.getAmount() + "," +
-            "\"cba\":" + invoice.getCBA() + "," +
-            "\"creditAdj\":" + invoice.getCreditAdj() + "," +
-            "\"refundAdj\":" + invoice.getRefundAdj() + "," +
-            "\"invoiceId\":\"" + invoice.getInvoiceId() + "\"," +
-            "\"invoiceDate\":\"" + invoice.getInvoiceDate().toString() + "\"," +
-            "\"targetDate\":\"" + invoice.getTargetDate() + "\"," +
-            "\"invoiceNumber\":\"" + invoice.getInvoiceNumber() + "\"," +
-            "\"balance\":" + invoice.getBalance() + "," +
-            "\"accountId\":\"" + invoice.getAccountId() + "\"}]," +
-            "\"reasonForChange\":\"" + reason + "\"}");
-
         final BundleTimelineJson fromJson = mapper.readValue(asJson, BundleTimelineJson.class);
         Assert.assertEquals(fromJson, bundleTimelineJson);
     }
@@ -125,8 +67,8 @@ public class TestBundleTimelineJson extends JaxrsTestSuite {
         final DateTime effectiveDate = clock.getUTCNow();
         final UUID eventId = UUID.randomUUID();
         final PlanPhaseSpecifier planPhaseSpecifier = new PlanPhaseSpecifier(UUID.randomUUID().toString(), ProductCategory.BASE,
-                BillingPeriod.NO_BILLING_PERIOD, UUID.randomUUID().toString(),
-                PhaseType.EVERGREEN);
+                                                                             BillingPeriod.NO_BILLING_PERIOD, UUID.randomUUID().toString(),
+                                                                             PhaseType.EVERGREEN);
         Mockito.when(event.getEffectiveDate()).thenReturn(effectiveDate);
         Mockito.when(event.getEventId()).thenReturn(eventId);
         Mockito.when(event.getSubscriptionTransitionType()).thenReturn(SubscriptionTransitionType.CREATE);
@@ -140,7 +82,7 @@ public class TestBundleTimelineJson extends JaxrsTestSuite {
         final String externalKey = UUID.randomUUID().toString();
         final SubscriptionJsonWithEvents subscription = new SubscriptionJsonWithEvents(bundleId, subscriptionTimeline);
 
-        return new BundleJsonWithSubscriptions(bundleId.toString(), externalKey, ImmutableList.<SubscriptionJsonWithEvents>of(subscription));
+        return new BundleJsonWithSubscriptions(bundleId.toString(), externalKey, ImmutableList.<SubscriptionJsonWithEvents>of(subscription), null);
     }
 
     private InvoiceJsonSimple createInvoice() {
@@ -156,7 +98,7 @@ public class TestBundleTimelineJson extends JaxrsTestSuite {
         final BigDecimal balance = BigDecimal.ZERO;
 
         return new InvoiceJsonSimple(invoiceAmount, cba, creditAdj, refundAdj, invoiceId.toString(), invoiceDate,
-                targetDate, invoiceNumber, balance, accountId.toString());
+                                     targetDate, invoiceNumber, balance, accountId.toString(), null);
     }
 
     private PaymentJsonSimple createPayment(final UUID accountId, final UUID invoiceId) {
@@ -175,6 +117,7 @@ public class TestBundleTimelineJson extends JaxrsTestSuite {
         final String extSecondPaymentIdRef = UUID.randomUUID().toString();
 
         return new PaymentJsonSimple(amount, paidAmount, accountId.toString(), invoiceId.toString(), paymentId.toString(),
-                paymentMethodId.toString(), paymentRequestedDate, paymentEffectiveDate, retryCount, currency, status, gatewayErrorCode, gatewayErrorMsg, extFirstPaymentIdRef, extSecondPaymentIdRef);
+                                     paymentMethodId.toString(), paymentRequestedDate, paymentEffectiveDate, retryCount, currency, status,
+                                     gatewayErrorCode, gatewayErrorMsg, extFirstPaymentIdRef, extSecondPaymentIdRef, null);
     }
 }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestCreditCollectionJson.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestCreditCollectionJson.java
index 0579cac..04e8177 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestCreditCollectionJson.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestCreditCollectionJson.java
@@ -17,6 +17,7 @@
 package com.ning.billing.jaxrs.json;
 
 import java.math.BigDecimal;
+import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -27,22 +28,12 @@ import com.ning.billing.jaxrs.JaxrsTestSuite;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.datatype.joda.JodaModule;
 import com.google.common.collect.ImmutableList;
 
 public class TestCreditCollectionJson extends JaxrsTestSuite {
 
-    private static final ObjectMapper mapper = new ObjectMapper();
-
     private final Clock clock = new DefaultClock();
 
-    static {
-        mapper.registerModule(new JodaModule());
-        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
-    }
-
     @Test(groups = "fast")
     public void testJson() throws Exception {
         final UUID accountId = UUID.randomUUID();
@@ -53,23 +44,17 @@ public class TestCreditCollectionJson extends JaxrsTestSuite {
         final DateTime requestedDate = clock.getUTCNow();
         final DateTime effectiveDate = clock.getUTCNow();
         final String reason = UUID.randomUUID().toString();
-        final CreditJson creditJson = new CreditJson(creditAmount, invoiceId, invoiceNumber, requestedDate, effectiveDate, reason, accountId);
+        final List<AuditLogJson> auditLogs = createAuditLogsJson();
+        final CreditJson creditJson = new CreditJson(creditAmount, invoiceId, invoiceNumber, requestedDate,
+                                                     effectiveDate, reason, accountId, auditLogs);
 
         final CreditCollectionJson creditCollectionJson = new CreditCollectionJson(accountId, ImmutableList.<CreditJson>of(creditJson));
         Assert.assertEquals(creditCollectionJson.getAccountId(), accountId);
         Assert.assertEquals(creditCollectionJson.getCredits().size(), 1);
         Assert.assertEquals(creditCollectionJson.getCredits().get(0), creditJson);
+        Assert.assertEquals(creditCollectionJson.getCredits().get(0).getAuditLogs(), auditLogs);
 
         final String asJson = mapper.writeValueAsString(creditCollectionJson);
-        Assert.assertEquals(asJson, "{\"accountId\":\"" + accountId.toString() + "\"," +
-                                    "\"credits\":[{\"creditAmount\":" + creditJson.getCreditAmount() + "," +
-                                    "\"invoiceId\":\"" + creditJson.getInvoiceId().toString() + "\"," +
-                                    "\"invoiceNumber\":\"" + creditJson.getInvoiceNumber() + "\"," +
-                                    "\"requestedDate\":\"" + creditJson.getRequestedDate().toDateTimeISO().toString() + "\"," +
-                                    "\"effectiveDate\":\"" + creditJson.getEffectiveDate().toDateTimeISO().toString() + "\"," +
-                                    "\"reason\":\"" + creditJson.getReason() + "\"," +
-                                    "\"accountId\":\"" + creditJson.getAccountId().toString() + "\"}]}");
-
         final CreditCollectionJson fromJson = mapper.readValue(asJson, CreditCollectionJson.class);
         Assert.assertEquals(fromJson, creditCollectionJson);
     }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestCreditJson.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestCreditJson.java
index b18156c..913c5ec 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestCreditJson.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestCreditJson.java
@@ -17,6 +17,7 @@
 package com.ning.billing.jaxrs.json;
 
 import java.math.BigDecimal;
+import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -27,21 +28,10 @@ import com.ning.billing.jaxrs.JaxrsTestSuite;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.datatype.joda.JodaModule;
-
 public class TestCreditJson extends JaxrsTestSuite {
 
-    private static final ObjectMapper mapper = new ObjectMapper();
-
     private final Clock clock = new DefaultClock();
 
-    static {
-        mapper.registerModule(new JodaModule());
-        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
-    }
-
     @Test(groups = "fast")
     public void testJson() throws Exception {
         final BigDecimal creditAmount = BigDecimal.TEN;
@@ -51,8 +41,9 @@ public class TestCreditJson extends JaxrsTestSuite {
         final DateTime effectiveDate = clock.getUTCNow();
         final String reason = UUID.randomUUID().toString();
         final UUID accountId = UUID.randomUUID();
-
-        final CreditJson creditJson = new CreditJson(creditAmount, invoiceId, invoiceNumber, requestedDate, effectiveDate, reason, accountId);
+        final List<AuditLogJson> auditLogs = createAuditLogsJson();
+        final CreditJson creditJson = new CreditJson(creditAmount, invoiceId, invoiceNumber, requestedDate, effectiveDate,
+                                                     reason, accountId, auditLogs);
         Assert.assertEquals(creditJson.getRequestedDate(), requestedDate);
         Assert.assertEquals(creditJson.getEffectiveDate(), effectiveDate);
         Assert.assertEquals(creditJson.getCreditAmount(), creditAmount);
@@ -62,14 +53,6 @@ public class TestCreditJson extends JaxrsTestSuite {
         Assert.assertEquals(creditJson.getAccountId(), accountId);
 
         final String asJson = mapper.writeValueAsString(creditJson);
-        Assert.assertEquals(asJson, "{\"creditAmount\":" + creditJson.getCreditAmount() + "," +
-                                    "\"invoiceId\":\"" + creditJson.getInvoiceId().toString() + "\"," +
-                                    "\"invoiceNumber\":\"" + creditJson.getInvoiceNumber() + "\"," +
-                                    "\"requestedDate\":\"" + creditJson.getRequestedDate().toDateTimeISO().toString() + "\"," +
-                                    "\"effectiveDate\":\"" + creditJson.getEffectiveDate().toDateTimeISO().toString() + "\"," +
-                                    "\"reason\":\"" + creditJson.getReason() + "\"," +
-                                    "\"accountId\":\"" + creditJson.getAccountId().toString() + "\"}");
-
         final CreditJson fromJson = mapper.readValue(asJson, CreditJson.class);
         Assert.assertEquals(fromJson, creditJson);
     }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonSimple.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonSimple.java
index b517039..0e2ade2 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonSimple.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonSimple.java
@@ -17,6 +17,7 @@
 package com.ning.billing.jaxrs.json;
 
 import java.math.BigDecimal;
+import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.LocalDate;
@@ -29,21 +30,10 @@ import com.ning.billing.jaxrs.JaxrsTestSuite;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.datatype.joda.JodaModule;
-
 public class TestInvoiceJsonSimple extends JaxrsTestSuite {
 
-    private static final ObjectMapper mapper = new ObjectMapper();
-
     private final Clock clock = new DefaultClock();
 
-    static {
-        mapper.registerModule(new JodaModule());
-        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
-    }
-
     @Test(groups = "fast")
     public void testJson() throws Exception {
         final BigDecimal amount = BigDecimal.TEN;
@@ -56,8 +46,9 @@ public class TestInvoiceJsonSimple extends JaxrsTestSuite {
         final String invoiceNumber = UUID.randomUUID().toString();
         final BigDecimal balance = BigDecimal.ZERO;
         final String accountId = UUID.randomUUID().toString();
+        final List<AuditLogJson> auditLogs = createAuditLogsJson();
         final InvoiceJsonSimple invoiceJsonSimple = new InvoiceJsonSimple(amount, cba, creditAdj, refundAdj, invoiceId, invoiceDate,
-                                                                          targetDate, invoiceNumber, balance, accountId);
+                                                                          targetDate, invoiceNumber, balance, accountId, auditLogs);
         Assert.assertEquals(invoiceJsonSimple.getAmount(), amount);
         Assert.assertEquals(invoiceJsonSimple.getCBA(), cba);
         Assert.assertEquals(invoiceJsonSimple.getCreditAdj(), creditAdj);
@@ -68,19 +59,9 @@ public class TestInvoiceJsonSimple extends JaxrsTestSuite {
         Assert.assertEquals(invoiceJsonSimple.getInvoiceNumber(), invoiceNumber);
         Assert.assertEquals(invoiceJsonSimple.getBalance(), balance);
         Assert.assertEquals(invoiceJsonSimple.getAccountId(), accountId);
+        Assert.assertEquals(invoiceJsonSimple.getAuditLogs(), auditLogs);
 
         final String asJson = mapper.writeValueAsString(invoiceJsonSimple);
-        Assert.assertEquals(asJson, "{\"amount\":" + invoiceJsonSimple.getAmount().toString() + "," +
-                                    "\"cba\":" + invoiceJsonSimple.getCBA().toString() + "," +
-                                    "\"creditAdj\":" + invoiceJsonSimple.getCreditAdj().toString() + "," +
-                                    "\"refundAdj\":" + invoiceJsonSimple.getRefundAdj().toString() + "," +
-                                    "\"invoiceId\":\"" + invoiceJsonSimple.getInvoiceId() + "\"," +
-                                    "\"invoiceDate\":\"" + invoiceJsonSimple.getInvoiceDate().toString() + "\"," +
-                                    "\"targetDate\":\"" + invoiceJsonSimple.getTargetDate().toString() + "\"," +
-                                    "\"invoiceNumber\":\"" + invoiceJsonSimple.getInvoiceNumber() + "\"," +
-                                    "\"balance\":" + invoiceJsonSimple.getBalance().toString() + "," +
-                                    "\"accountId\":\"" + invoiceJsonSimple.getAccountId() + "\"}");
-
         final InvoiceJsonSimple fromJson = mapper.readValue(asJson, InvoiceJsonSimple.class);
         Assert.assertEquals(fromJson, invoiceJsonSimple);
     }
@@ -110,5 +91,6 @@ public class TestInvoiceJsonSimple extends JaxrsTestSuite {
         Assert.assertEquals(invoiceJsonSimple.getInvoiceNumber(), String.valueOf(invoice.getInvoiceNumber()));
         Assert.assertEquals(invoiceJsonSimple.getBalance(), invoice.getBalance());
         Assert.assertEquals(invoiceJsonSimple.getAccountId(), invoice.getAccountId().toString());
+        Assert.assertNull(invoiceJsonSimple.getAuditLogs());
     }
 }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
index 5c2ca0b..d312294 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
@@ -31,22 +31,12 @@ import com.ning.billing.jaxrs.JaxrsTestSuite;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.datatype.joda.JodaModule;
 import com.google.common.collect.ImmutableList;
 
 public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuite {
 
-    private static final ObjectMapper mapper = new ObjectMapper();
-
     private final Clock clock = new DefaultClock();
 
-    static {
-        mapper.registerModule(new JodaModule());
-        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
-    }
-
     @Test(groups = "fast")
     public void testJson() throws Exception {
         final BigDecimal amount = BigDecimal.TEN;
@@ -60,11 +50,12 @@ public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuite {
         final BigDecimal balance = BigDecimal.ZERO;
         final String accountId = UUID.randomUUID().toString();
         final String bundleKeys = UUID.randomUUID().toString();
-        CreditJson creditJson = createCreditJson();
+        final CreditJson creditJson = createCreditJson();
         final List<CreditJson> credits = ImmutableList.<CreditJson>of(creditJson);
+        final List<AuditLogJson> auditLogs = createAuditLogsJson();
         final InvoiceJsonWithBundleKeys invoiceJsonSimple = new InvoiceJsonWithBundleKeys(amount, cba, creditAdj, refundAdj, invoiceId, invoiceDate,
                                                                                           targetDate, invoiceNumber, balance, accountId, bundleKeys,
-                                                                                          credits);
+                                                                                          credits, auditLogs);
         Assert.assertEquals(invoiceJsonSimple.getAmount(), amount);
         Assert.assertEquals(invoiceJsonSimple.getCBA(), cba);
         Assert.assertEquals(invoiceJsonSimple.getCreditAdj(), creditAdj);
@@ -77,28 +68,9 @@ public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuite {
         Assert.assertEquals(invoiceJsonSimple.getAccountId(), accountId);
         Assert.assertEquals(invoiceJsonSimple.getBundleKeys(), bundleKeys);
         Assert.assertEquals(invoiceJsonSimple.getCredits(), credits);
+        Assert.assertEquals(invoiceJsonSimple.getAuditLogs(), auditLogs);
 
         final String asJson = mapper.writeValueAsString(invoiceJsonSimple);
-        Assert.assertEquals(asJson, "{\"amount\":" + invoiceJsonSimple.getAmount().toString() + "," +
-                                    "\"cba\":" + invoiceJsonSimple.getCBA().toString() + "," +
-                                    "\"creditAdj\":" + invoiceJsonSimple.getCreditAdj().toString() + "," +
-                                    "\"refundAdj\":" + invoiceJsonSimple.getRefundAdj().toString() + "," +
-                                    "\"invoiceId\":\"" + invoiceJsonSimple.getInvoiceId() + "\"," +
-                                    "\"invoiceDate\":\"" + invoiceJsonSimple.getInvoiceDate().toString() + "\"," +
-                                    "\"targetDate\":\"" + invoiceJsonSimple.getTargetDate().toString() + "\"," +
-                                    "\"invoiceNumber\":\"" + invoiceJsonSimple.getInvoiceNumber() + "\"," +
-                                    "\"balance\":" + invoiceJsonSimple.getBalance().toString() + "," +
-                                    "\"accountId\":\"" + invoiceJsonSimple.getAccountId() + "\"," +
-                                    "\"credits\":[" +
-                                    "{\"creditAmount\":" + creditJson.getCreditAmount() + "," +
-                                    "\"invoiceId\":\"" + creditJson.getInvoiceId().toString() + "\"," +
-                                    "\"invoiceNumber\":\"" + creditJson.getInvoiceNumber() + "\"," +
-                                    "\"requestedDate\":\"" + creditJson.getRequestedDate().toDateTimeISO().toString() + "\"," +
-                                    "\"effectiveDate\":\"" + creditJson.getEffectiveDate().toDateTimeISO().toString() + "\"," +
-                                    "\"reason\":\"" + creditJson.getReason() + "\"," +
-                                    "\"accountId\":\"" + creditJson.getAccountId().toString() + "\"}]," +
-                                    "\"bundleKeys\":\"" + invoiceJsonSimple.getBundleKeys() + "\"}");
-
         final InvoiceJsonWithBundleKeys fromJson = mapper.readValue(asJson, InvoiceJsonWithBundleKeys.class);
         Assert.assertEquals(fromJson, invoiceJsonSimple);
     }
@@ -120,7 +92,7 @@ public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuite {
         final String bundleKeys = UUID.randomUUID().toString();
         final List<CreditJson> credits = ImmutableList.<CreditJson>of(createCreditJson());
 
-        final InvoiceJsonWithBundleKeys invoiceJsonWithBundleKeys = new InvoiceJsonWithBundleKeys(invoice, bundleKeys, credits);
+        final InvoiceJsonWithBundleKeys invoiceJsonWithBundleKeys = new InvoiceJsonWithBundleKeys(invoice, bundleKeys, credits, null);
         Assert.assertEquals(invoiceJsonWithBundleKeys.getAmount(), invoice.getChargedAmount());
         Assert.assertEquals(invoiceJsonWithBundleKeys.getCBA(), invoice.getCBAAmount());
         Assert.assertEquals(invoiceJsonWithBundleKeys.getCreditAdj(), invoice.getCreditAdjAmount());
@@ -133,6 +105,7 @@ public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuite {
         Assert.assertEquals(invoiceJsonWithBundleKeys.getAccountId(), invoice.getAccountId().toString());
         Assert.assertEquals(invoiceJsonWithBundleKeys.getBundleKeys(), bundleKeys);
         Assert.assertEquals(invoiceJsonWithBundleKeys.getCredits(), credits);
+        Assert.assertNull(invoiceJsonWithBundleKeys.getAuditLogs());
     }
 
     private CreditJson createCreditJson() {
@@ -143,6 +116,6 @@ public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuite {
         final DateTime effectiveDate = clock.getUTCNow();
         final String reason = UUID.randomUUID().toString();
         final UUID accountId = UUID.randomUUID();
-        return new CreditJson(creditAmount, invoiceId, invoiceNumber, requestedDate, effectiveDate, reason, accountId);
+        return new CreditJson(creditAmount, invoiceId, invoiceNumber, requestedDate, effectiveDate, reason, accountId, null);
     }
 }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonWithItems.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonWithItems.java
index e849f0e..c66bc4f 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonWithItems.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceJsonWithItems.java
@@ -17,6 +17,7 @@
 package com.ning.billing.jaxrs.json;
 
 import java.math.BigDecimal;
+import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.LocalDate;
@@ -31,22 +32,12 @@ import com.ning.billing.jaxrs.JaxrsTestSuite;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.datatype.joda.JodaModule;
 import com.google.common.collect.ImmutableList;
 
 public class TestInvoiceJsonWithItems extends JaxrsTestSuite {
 
-    private static final ObjectMapper mapper = new ObjectMapper();
-
     private final Clock clock = new DefaultClock();
 
-    static {
-        mapper.registerModule(new JodaModule());
-        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
-    }
-
     @Test(groups = "fast")
     public void testJson() throws Exception {
         final BigDecimal amount = BigDecimal.TEN;
@@ -60,9 +51,10 @@ public class TestInvoiceJsonWithItems extends JaxrsTestSuite {
         final BigDecimal balance = BigDecimal.ZERO;
         final String accountId = UUID.randomUUID().toString();
         final InvoiceItemJsonSimple invoiceItemJsonSimple = createInvoiceItemJson();
+        final List<AuditLogJson> auditLogs = createAuditLogsJson();
         final InvoiceJsonWithItems invoiceJsonWithItems = new InvoiceJsonWithItems(amount, cba, creditAdj, refundAdj, invoiceId, invoiceDate,
                                                                                    targetDate, invoiceNumber, balance, accountId,
-                                                                                   ImmutableList.<InvoiceItemJsonSimple>of(invoiceItemJsonSimple));
+                                                                                   ImmutableList.<InvoiceItemJsonSimple>of(invoiceItemJsonSimple), auditLogs);
         Assert.assertEquals(invoiceJsonWithItems.getAmount(), amount);
         Assert.assertEquals(invoiceJsonWithItems.getCBA(), cba);
         Assert.assertEquals(invoiceJsonWithItems.getCreditAdj(), creditAdj);
@@ -75,30 +67,9 @@ public class TestInvoiceJsonWithItems extends JaxrsTestSuite {
         Assert.assertEquals(invoiceJsonWithItems.getAccountId(), accountId);
         Assert.assertEquals(invoiceJsonWithItems.getItems().size(), 1);
         Assert.assertEquals(invoiceJsonWithItems.getItems().get(0), invoiceItemJsonSimple);
+        Assert.assertEquals(invoiceJsonWithItems.getAuditLogs(), auditLogs);
 
         final String asJson = mapper.writeValueAsString(invoiceJsonWithItems);
-        Assert.assertEquals(asJson, "{\"amount\":" + invoiceJsonWithItems.getAmount().toString() + "," +
-                                    "\"cba\":" + invoiceJsonWithItems.getCBA().toString() + "," +
-                                    "\"creditAdj\":" + invoiceJsonWithItems.getCreditAdj().toString() + "," +
-                                    "\"refundAdj\":" + invoiceJsonWithItems.getRefundAdj().toString() + "," +
-                                    "\"invoiceId\":\"" + invoiceJsonWithItems.getInvoiceId() + "\"," +
-                                    "\"invoiceDate\":\"" + invoiceJsonWithItems.getInvoiceDate().toString() + "\"," +
-                                    "\"targetDate\":\"" + invoiceJsonWithItems.getTargetDate().toString() + "\"," +
-                                    "\"invoiceNumber\":\"" + invoiceJsonWithItems.getInvoiceNumber() + "\"," +
-                                    "\"balance\":" + invoiceJsonWithItems.getBalance().toString() + "," +
-                                    "\"accountId\":\"" + invoiceJsonWithItems.getAccountId() + "\"," +
-                                    "\"items\":[{\"invoiceId\":\"" + invoiceItemJsonSimple.getInvoiceId().toString() + "\"," +
-                                    "\"accountId\":\"" + invoiceItemJsonSimple.getAccountId().toString() + "\"," +
-                                    "\"bundleId\":\"" + invoiceItemJsonSimple.getBundleId().toString() + "\"," +
-                                    "\"subscriptionId\":\"" + invoiceItemJsonSimple.getSubscriptionId().toString() + "\"," +
-                                    "\"planName\":\"" + invoiceItemJsonSimple.getPlanName() + "\"," +
-                                    "\"phaseName\":\"" + invoiceItemJsonSimple.getPhaseName() + "\"," +
-                                    "\"description\":\"" + invoiceItemJsonSimple.getDescription() + "\"," +
-                                    "\"startDate\":\"" + invoiceItemJsonSimple.getStartDate().toString() + "\"," +
-                                    "\"endDate\":\"" + invoiceItemJsonSimple.getEndDate().toString() + "\"," +
-                                    "\"amount\":" + invoiceItemJsonSimple.getAmount().toString() + "," +
-                                    "\"currency\":\"" + invoiceItemJsonSimple.getCurrency().toString() + "\"}]}");
-
         final InvoiceJsonWithItems fromJson = mapper.readValue(asJson, InvoiceJsonWithItems.class);
         Assert.assertEquals(fromJson, invoiceJsonWithItems);
     }
@@ -125,6 +96,8 @@ public class TestInvoiceJsonWithItems extends JaxrsTestSuite {
         Assert.assertEquals(invoiceJsonWithItems.getBalance(), invoice.getBalance());
         Assert.assertEquals(invoiceJsonWithItems.getAccountId(), invoice.getAccountId().toString());
         Assert.assertEquals(invoiceJsonWithItems.getItems().size(), 1);
+        Assert.assertNull(invoiceJsonWithItems.getAuditLogs());
+
         final InvoiceItemJsonSimple invoiceItemJsonSimple = invoiceJsonWithItems.getItems().get(0);
         Assert.assertEquals(invoiceItemJsonSimple.getInvoiceId(), invoiceItem.getInvoiceId());
         Assert.assertEquals(invoiceItemJsonSimple.getAccountId(), invoiceItem.getAccountId());
diff --git a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
index fda58c0..32ff962 100644
--- a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
+++ b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
@@ -41,6 +41,7 @@ import com.ning.billing.junction.glue.DefaultJunctionModule;
 import com.ning.billing.payment.glue.PaymentModule;
 import com.ning.billing.util.email.EmailModule;
 import com.ning.billing.util.email.templates.TemplateModule;
+import com.ning.billing.util.glue.AuditModule;
 import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.CallContextModule;
 import com.ning.billing.util.glue.ClockModule;
@@ -91,6 +92,7 @@ public class KillbillServerModule extends AbstractModule {
         install(new GlobalLockerModule());
         install(new CustomFieldModule());
         install(new TagStoreModule());
+        install(new AuditModule());
         install(new CatalogModule());
         install(new BusModule());
         install(new NotificationQueueModule());
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java b/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
index 4b8fefe..94ae280 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
@@ -129,7 +129,7 @@ public class TestBundle extends TestJaxrsBase {
 
         final AccountJson newAccount = createAccountWithDefaultPaymentMethod("dst", "dst", "dst@yahoo.com");
 
-        final BundleJsonNoSubscriptions newBundleInput = new BundleJsonNoSubscriptions(null, newAccount.getAccountId(), null);
+        final BundleJsonNoSubscriptions newBundleInput = new BundleJsonNoSubscriptions(null, newAccount.getAccountId(), null, null, null);
         final String newBundleInputJson = mapper.writeValueAsString(newBundleInput);
         final String uri = JaxrsResource.BUNDLES_PATH + "/" + bundleJson.getBundleId();
         Response response = doPut(uri, newBundleInputJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -141,6 +141,4 @@ public class TestBundle extends TestJaxrsBase {
         response = doGetWithUrl(locationCC, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
     }
-
-
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java b/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
index dc67b41..d7b5dca 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
@@ -62,7 +62,8 @@ public class TestCredit extends TestJaxrsBase {
         final InvoiceJsonSimple invoice = createInvoice();
         final CreditJson input = new CreditJson(BigDecimal.TEN, UUID.fromString(invoice.getInvoiceId()), UUID.randomUUID().toString(),
                                                 requestedDate, effectiveDate,
-                                                UUID.randomUUID().toString(), UUID.fromString(accountJson.getAccountId()));
+                                                UUID.randomUUID().toString(), UUID.fromString(accountJson.getAccountId()),
+                                                null);
         final String jsonInput = mapper.writeValueAsString(input);
 
         // Create the credit
@@ -121,7 +122,7 @@ public class TestCredit extends TestJaxrsBase {
         final DateTime effectiveDate = clock.getUTCNow();
         final CreditJson input = new CreditJson(BigDecimal.TEN, UUID.randomUUID(), UUID.randomUUID().toString(),
                                                 requestedDate, effectiveDate,
-                                                UUID.randomUUID().toString(), UUID.randomUUID());
+                                                UUID.randomUUID().toString(), UUID.randomUUID(), null);
         final String jsonInput = mapper.writeValueAsString(input);
 
         // Try to create the credit
@@ -131,7 +132,7 @@ public class TestCredit extends TestJaxrsBase {
 
     @Test(groups = "slow")
     public void testBadRequest() throws Exception {
-        final CreditJson input = new CreditJson(null, null, null, null, null, null, null);
+        final CreditJson input = new CreditJson(null, null, null, null, null, null, null, null);
         final String jsonInput = mapper.writeValueAsString(input);
 
         // Try to create the credit
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
index 4efe6cb..4dfc5ab 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
@@ -209,7 +209,8 @@ public class TestInvoice extends TestJaxrsBase {
             }
 
             // CREATE INSTA PAYMENT
-            final PaymentJsonSimple payment = new PaymentJsonSimple(cur.getAmount(), BigDecimal.ZERO, accountJson.getAccountId(), cur.getInvoiceId(), null, null, null, null, 0, null, null, null, null, null, null);
+            final PaymentJsonSimple payment = new PaymentJsonSimple(cur.getAmount(), BigDecimal.ZERO, accountJson.getAccountId(),
+                                                                    cur.getInvoiceId(), null, null, null, null, 0, null, null, null, null, null, null, null);
             final String postJson = mapper.writeValueAsString(payment);
 
             uri = JaxrsResource.INVOICES_PATH + "/" + cur.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
@@ -267,7 +268,7 @@ public class TestInvoice extends TestJaxrsBase {
         final BigDecimal paidAmount = BigDecimal.TEN;
         final PaymentJsonSimple payment = new PaymentJsonSimple(paidAmount, BigDecimal.ZERO, accountJson.getAccountId(),
                                                                 invoiceId, null, null, null, null, 0,
-                                                                null, null, null, null, null, null);
+                                                                null, null, null, null, null, null, null);
         final String postJson = mapper.writeValueAsString(payment);
         final String paymentURI = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.PAYMENTS;
         final Response paymentResponse = doPost(paymentURI, postJson, ImmutableMap.<String, String>of("externalPayment", "true"), DEFAULT_HTTP_TIMEOUT_SEC);
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
index f59c748..aba8426 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -81,6 +81,7 @@ import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.email.EmailModule;
 import com.ning.billing.util.email.templates.TemplateModule;
+import com.ning.billing.util.glue.AuditModule;
 import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.CallContextModule;
 import com.ning.billing.util.glue.CustomFieldModule;
@@ -209,6 +210,7 @@ public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
             install(new GlobalLockerModule());
             install(new CustomFieldModule());
             install(new TagStoreModule());
+            install(new AuditModule());
             install(new CatalogModule());
             install(new BusModule());
             install(new NotificationQueueModule());
@@ -370,7 +372,7 @@ public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
 
 
     protected BundleJsonNoSubscriptions createBundle(final String accountId, final String key) throws Exception {
-        final BundleJsonNoSubscriptions input = new BundleJsonNoSubscriptions(null, accountId, key);
+        final BundleJsonNoSubscriptions input = new BundleJsonNoSubscriptions(null, accountId, key, null, null);
         String baseJson = mapper.writeValueAsString(input);
         Response response = doPost(JaxrsResource.BUNDLES_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
diff --git a/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java b/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java
index 7f38dee..6d4a827 100644
--- a/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java
+++ b/util/src/main/java/com/ning/billing/util/audit/dao/DefaultAuditDao.java
@@ -40,7 +40,7 @@ public class DefaultAuditDao implements AuditDao {
 
     @Override
     public List<AuditLog> getAuditLogsForRecordId(final TableName tableName, final UUID objectId) {
-        final Long recordId = auditSqlDao.getRecordIdForTable(tableName, objectId.toString());
+        final Long recordId = auditSqlDao.getRecordIdForTable(tableName.getTableName().toLowerCase(), objectId.toString());
         if (recordId == null) {
             return ImmutableList.<AuditLog>of();
         } else {
diff --git a/util/src/main/java/com/ning/billing/util/dao/AuditLogMapper.java b/util/src/main/java/com/ning/billing/util/dao/AuditLogMapper.java
index 89ca281..188ea71 100644
--- a/util/src/main/java/com/ning/billing/util/dao/AuditLogMapper.java
+++ b/util/src/main/java/com/ning/billing/util/dao/AuditLogMapper.java
@@ -41,10 +41,10 @@ public class AuditLogMapper extends MapperBase implements ResultSetMapper<AuditL
         final String changedBy = r.getString("changed_by");
         final String reasonCode = r.getString("reason_code");
         final String comments = r.getString("comments");
-        final String userToken = r.getString("user_token");
+        final UUID userToken = getUUID(r, "user_token");
 
         final EntityAudit entityAudit = new EntityAudit(TableName.valueOf(tableName), recordId, ChangeType.valueOf(changeType));
-        final CallContext callContext = new DefaultCallContext(changedBy, changeDate, reasonCode, comments, UUID.fromString(userToken));
+        final CallContext callContext = new DefaultCallContext(changedBy, changeDate, reasonCode, comments, userToken);
         return new DefaultAuditLog(entityAudit, callContext);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java b/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java
index 2e5d353..58a08c6 100644
--- a/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/AuditSqlDao.java
@@ -50,7 +50,7 @@ public interface AuditSqlDao {
     public Long getRecordId(@Bind("id") final String id);
 
     @SqlQuery
-    public Long getRecordIdForTable(@Define("tableName") final TableName tableName,
+    public Long getRecordIdForTable(@Define("tableName") final String tableName,
                                     @Bind("id") final String id);
 
     @SqlQuery
diff --git a/util/src/main/java/com/ning/billing/util/glue/AuditModule.java b/util/src/main/java/com/ning/billing/util/glue/AuditModule.java
index 0a1e8fb..2fa9310 100644
--- a/util/src/main/java/com/ning/billing/util/glue/AuditModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/AuditModule.java
@@ -16,6 +16,8 @@
 
 package com.ning.billing.util.glue;
 
+import com.ning.billing.util.api.AuditUserApi;
+import com.ning.billing.util.audit.api.DefaultAuditUserApi;
 import com.ning.billing.util.audit.dao.AuditDao;
 import com.ning.billing.util.audit.dao.DefaultAuditDao;
 
@@ -27,8 +29,13 @@ public class AuditModule extends AbstractModule {
         bind(AuditDao.class).to(DefaultAuditDao.class).asEagerSingleton();
     }
 
+    protected void installUserApi() {
+        bind(AuditUserApi.class).to(DefaultAuditUserApi.class).asEagerSingleton();
+    }
+
     @Override
     protected void configure() {
         installDaos();
+        installUserApi();
     }
 }