killbill-memoizeit

Merge from upstream

7/1/2012 8:36:48 PM

Changes

account/pom.xml 16(+6 -10)

account/src/test/resources/log4j.xml 36(+0 -36)

analytics/pom.xml 17(+6 -11)

analytics/src/test/java/com/ning/billing/analytics/MockAccount.java 148(+0 -148)

analytics/src/test/java/com/ning/billing/analytics/MockAccountUserApi.java 102(+0 -102)

analytics/src/test/resources/log4j.xml 31(+0 -31)

api/pom.xml 10(+1 -9)

beatrix/pom.xml 25(+15 -10)

beatrix/src/test/resources/log4j.xml 44(+0 -44)

catalog/pom.xml 13(+7 -6)

catalog/src/test/resources/log4j.xml 36(+0 -36)

entitlement/pom.xml 18(+7 -11)

entitlement/src/test/resources/log4j.xml 36(+0 -36)

invoice/pom.xml 19(+7 -12)

invoice/src/test/resources/log4j.xml 36(+0 -36)

jaxrs/pom.xml 6(+3 -3)

jaxrs/src/test/resources/log4j.xml 36(+0 -36)

junction/pom.xml 15(+7 -8)

junction/src/test/resources/log4j.xml 40(+0 -40)

overdue/pom.xml 19(+7 -12)

overdue/src/test/resources/log4j.xml 40(+0 -40)

payment/pom.xml 22(+7 -15)

payment/src/test/resources/log4j.xml 30(+0 -30)

pom.xml 60(+19 -41)

server/pom.xml 831(+422 -409)

server/src/test/resources/log4j.xml 39(+0 -39)

util/pom.xml 25(+11 -14)

util/src/test/resources/log4j.xml 36(+0 -36)

Details

account/pom.xml 16(+6 -10)

diff --git a/account/pom.xml b/account/pom.xml
index 593fb57..1bf852c 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-account</artifactId>
@@ -56,10 +56,6 @@
             <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.antlr</groupId>
             <artifactId>stringtemplate</artifactId>
             <scope>runtime</scope>
@@ -69,6 +65,11 @@
             <artifactId>guava</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-mxj</artifactId>
             <scope>test</scope>
@@ -88,11 +89,6 @@
             <artifactId>testng</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java b/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
index 00477dd..c2273de 100644
--- a/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
+++ b/account/src/main/java/com/ning/billing/account/api/DefaultAccount.java
@@ -18,56 +18,69 @@ package com.ning.billing.account.api;
 
 import java.util.UUID;
 
-import com.ning.billing.util.entity.EntityBase;
 import org.joda.time.DateTimeZone;
 
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.util.entity.EntityBase;
 
 public class DefaultAccount extends EntityBase implements Account {
+    // Default values. When updating an account object, null values are
+    // interpreted as "no change". You can use these defaults to reset
+    // some fields
+    public static final String DEFAULT_STRING_VALUE = "";
+    public static final Integer DEFAULT_INTEGER_VALUE = 0;
+    public static final Integer DEFAULT_BCD_VALUE = DEFAULT_INTEGER_VALUE;
+    public static final Currency DEFAULT_CURRENCY_VALUE = Currency.USD;
+    public static final DateTimeZone DEFAULT_TIMEZONE_VALUE = DateTimeZone.UTC;
+    private static final Boolean DEFAULT_MIGRATED_VALUE = true;
+    private static final Boolean DEFAULT_NOTIFIED_FOR_INVOICES_VALUE = false;
+
     private final String externalKey;
-	private final String email;
-	private final String name;
-	private final int firstNameLength;
-	private final Currency currency;
-	private final int billCycleDay;
-	private final UUID paymentMethodId;
-	private final DateTimeZone timeZone;
-	private final String locale;
-	private final String address1;
-	private final String address2;
-	private final String companyName;
-	private final String city;
-	private final String stateOrProvince;
-	private final String country;
-	private final String postalCode;
-	private final String phone;
+    private final String email;
+    private final String name;
+    private final int firstNameLength;
+    private final Currency currency;
+    private final int billCycleDay;
+    private final UUID paymentMethodId;
+    private final DateTimeZone timeZone;
+    private final String locale;
+    private final String address1;
+    private final String address2;
+    private final String companyName;
+    private final String city;
+    private final String stateOrProvince;
+    private final String country;
+    private final String postalCode;
+    private final String phone;
     private final boolean isMigrated;
     private final boolean isNotifiedForInvoices;
 
     public DefaultAccount(final AccountData data) {
-		this(UUID.randomUUID(), data);
-	}
-
-	/**
-	 * This call is used to update an existing account
-	 *
-	 * @param id UUID id of the existing account to update
-	 * @param data AccountData new data for the existing account
-	 */
-	public DefaultAccount(final UUID id, final AccountData data) {
-		this(id, data.getExternalKey(), data.getEmail(), data.getName(), data.getFirstNameLength(),
-				data.getCurrency(), data.getBillCycleDay(), data.getPaymentMethodId(),
-				data.getTimeZone(), data.getLocale(),
-				data.getAddress1(), data.getAddress2(), data.getCompanyName(),
-				data.getCity(), data.getStateOrProvince(), data.getCountry(),
-				data.getPostalCode(), data.getPhone(), data.isMigrated(), data.isNotifiedForInvoices());
-	}
-
-	/*
-	 * This call is used for testing and update from an existing account
+        this(UUID.randomUUID(), data);
+    }
+
+    /**
+     * This call is used to update an existing account
+     *
+     * @param id   UUID id of the existing account to update
+     * @param data AccountData new data for the existing account
      */
-	public DefaultAccount(final UUID id, final String externalKey, final String email,
+    public DefaultAccount(final UUID id, final AccountData data) {
+        this(id, data.getExternalKey(), data.getEmail(), data.getName(), data.getFirstNameLength(),
+             data.getCurrency(), data.getBillCycleDay(), data.getPaymentMethodId(),
+             data.getTimeZone(), data.getLocale(),
+             data.getAddress1(), data.getAddress2(), data.getCompanyName(),
+             data.getCity(), data.getStateOrProvince(), data.getCountry(),
+             data.getPostalCode(), data.getPhone(), data.isMigrated(), data.isNotifiedForInvoices());
+    }
+
+    /*
+    * This call is used for testing and update from an existing account
+    */
+    public DefaultAccount(final UUID id, final String externalKey, final String email,
                           final String name, final int firstNameLength,
                           final Currency currency, final int billCycleDay, final UUID paymentMethodId,
                           final DateTimeZone timeZone, final String locale,
@@ -75,152 +88,180 @@ public class DefaultAccount extends EntityBase implements Account {
                           final String city, final String stateOrProvince, final String country,
                           final String postalCode, final String phone,
                           final boolean isMigrated, final boolean isNotifiedForInvoices) {
-		super(id);
-		this.externalKey = externalKey;
-		this.email = email;
-		this.name = name;
-		this.firstNameLength = firstNameLength;
-		this.currency = currency;
-		this.billCycleDay = billCycleDay;
-		this.paymentMethodId = paymentMethodId;
-		this.timeZone = timeZone;
-		this.locale = locale;
-		this.address1 = address1;
-		this.address2 = address2;
-		this.companyName = companyName;
-		this.city = city;
-		this.stateOrProvince = stateOrProvince;
-		this.postalCode = postalCode;
-		this.country = country;
-		this.phone = phone;
+        super(id);
+        this.externalKey = externalKey;
+        this.email = email;
+        this.name = name;
+        this.firstNameLength = firstNameLength;
+        this.currency = currency;
+        this.billCycleDay = billCycleDay;
+        this.paymentMethodId = paymentMethodId;
+        this.timeZone = timeZone;
+        this.locale = locale;
+        this.address1 = address1;
+        this.address2 = address2;
+        this.companyName = companyName;
+        this.city = city;
+        this.stateOrProvince = stateOrProvince;
+        this.postalCode = postalCode;
+        this.country = country;
+        this.phone = phone;
         this.isMigrated = isMigrated;
         this.isNotifiedForInvoices = isNotifiedForInvoices;
-	}
+    }
+
+    @Override
+    public String getExternalKey() {
+        return Objects.firstNonNull(externalKey, DEFAULT_STRING_VALUE);
+    }
+
+    @Override
+    public String getName() {
+        return Objects.firstNonNull(name, DEFAULT_STRING_VALUE);
+    }
 
-	@Override
-	public String getExternalKey() {
-		return externalKey;
-	}
+    @Override
+    public String getEmail() {
+        return Objects.firstNonNull(email, DEFAULT_STRING_VALUE);
+    }
 
-	@Override
-	public String getName() {
-		return name;
-	}
+    @Override
+    public Integer getFirstNameLength() {
+        return Objects.firstNonNull(firstNameLength, DEFAULT_INTEGER_VALUE);
+    }
 
-	@Override
-	public String getEmail() {
-		return email;
-	}
+    @Override
+    public Currency getCurrency() {
+        return Objects.firstNonNull(currency, DEFAULT_CURRENCY_VALUE);
+    }
 
-	@Override
-	public int getFirstNameLength() {
-		return firstNameLength;
-	}
+    @Override
+    public Integer getBillCycleDay() {
+        return Objects.firstNonNull(billCycleDay, DEFAULT_BCD_VALUE);
+    }
 
-	@Override
-	public Currency getCurrency() {
-		return currency;
-	}
+    @Override
+    public UUID getPaymentMethodId() {
+        // Null if non specified
+        return paymentMethodId;
+    }
 
-	@Override
-	public int getBillCycleDay() {
-		return billCycleDay;
-	}
+    @Override
+    public DateTimeZone getTimeZone() {
+        return Objects.firstNonNull(timeZone, DEFAULT_TIMEZONE_VALUE);
+    }
 
-	@Override
-	public UUID getPaymentMethodId() {
-		return paymentMethodId;
-	}
+    @Override
+    public String getLocale() {
+        return Objects.firstNonNull(locale, DEFAULT_STRING_VALUE);
+    }
 
-	@Override
-	public DateTimeZone getTimeZone() {
-		return timeZone;
-	}
+    @Override
+    public String getAddress1() {
+        return Objects.firstNonNull(address1, DEFAULT_STRING_VALUE);
+    }
 
-	@Override
-	public String getLocale() {
-		return locale;
-	}
+    @Override
+    public String getAddress2() {
+        return Objects.firstNonNull(address2, DEFAULT_STRING_VALUE);
+    }
 
-	@Override
-	public String getAddress1() {
-		return address1;
-	}
+    @Override
+    public String getCompanyName() {
+        return Objects.firstNonNull(companyName, DEFAULT_STRING_VALUE);
+    }
 
-	@Override
-	public String getAddress2() {
-		return address2;
-	}
+    @Override
+    public String getCity() {
+        return Objects.firstNonNull(city, DEFAULT_STRING_VALUE);
+    }
 
-	@Override
-	public String getCompanyName() {
-		return companyName;
-	}
+    @Override
+    public String getStateOrProvince() {
+        return Objects.firstNonNull(stateOrProvince, DEFAULT_STRING_VALUE);
+    }
 
-	@Override
-	public String getCity() {
-		return city;
-	}
+    @Override
+    public String getPostalCode() {
+        return Objects.firstNonNull(postalCode, DEFAULT_STRING_VALUE);
+    }
 
-	@Override
-	public String getStateOrProvince() {
-		return stateOrProvince;
-	}
+    @Override
+    public String getCountry() {
+        return Objects.firstNonNull(country, DEFAULT_STRING_VALUE);
+    }
 
-	@Override
-	public String getPostalCode() {
-		return postalCode;
-	}
+    @Override
+    public Boolean isMigrated() {
+        return Objects.firstNonNull(this.isMigrated, DEFAULT_MIGRATED_VALUE);
+    }
 
-	@Override
-	public String getCountry() {
-		return country;
-	}
+    @Override
+    public Boolean isNotifiedForInvoices() {
+        return Objects.firstNonNull(isNotifiedForInvoices, DEFAULT_NOTIFIED_FOR_INVOICES_VALUE);
+    }
 
     @Override
-    public boolean isMigrated() {
-        return this.isMigrated;
+    public String getPhone() {
+        return Objects.firstNonNull(phone, DEFAULT_STRING_VALUE);
     }
 
     @Override
-    public boolean isNotifiedForInvoices() {
-        return isNotifiedForInvoices;
+    public MutableAccountData toMutableAccountData() {
+        return new DefaultMutableAccountData(this);
     }
 
     @Override
-	public String getPhone() {
-		return phone;
-	}
+    public Account mergeWithDelegate(final Account delegate) {
+        final DefaultMutableAccountData accountData = new DefaultMutableAccountData(this);
+        accountData.setExternalKey(Objects.firstNonNull(externalKey, delegate.getExternalKey()));
+        accountData.setEmail(Objects.firstNonNull(email, delegate.getEmail()));
+        accountData.setName(Objects.firstNonNull(name, delegate.getName()));
+        accountData.setFirstNameLength(Objects.firstNonNull(firstNameLength, delegate.getFirstNameLength()));
+        accountData.setCurrency(Objects.firstNonNull(currency, delegate.getCurrency()));
+        accountData.setBillCycleDay(Objects.firstNonNull(billCycleDay, delegate.getBillCycleDay()));
+        accountData.setPaymentMethodId(Optional.<UUID>fromNullable(paymentMethodId)
+                                               .or(Optional.<UUID>fromNullable(delegate.getPaymentMethodId())).orNull());
+        accountData.setTimeZone(Objects.firstNonNull(timeZone, delegate.getTimeZone()));
+        accountData.setLocale(Objects.firstNonNull(locale, delegate.getLocale()));
+        accountData.setAddress1(Objects.firstNonNull(address1, delegate.getAddress1()));
+        accountData.setAddress2(Objects.firstNonNull(address2, delegate.getAddress2()));
+        accountData.setCompanyName(Objects.firstNonNull(companyName, delegate.getCompanyName()));
+        accountData.setCity(Objects.firstNonNull(city, delegate.getCity()));
+        accountData.setStateOrProvince(Objects.firstNonNull(stateOrProvince, delegate.getStateOrProvince()));
+        accountData.setCountry(Objects.firstNonNull(country, delegate.getCountry()));
+        accountData.setPostalCode(Objects.firstNonNull(postalCode, delegate.getPostalCode()));
+        accountData.setPhone(Objects.firstNonNull(phone, delegate.getPhone()));
+        accountData.setIsMigrated(Objects.firstNonNull(isMigrated, delegate.isMigrated()));
+        accountData.setIsNotifiedForInvoices(Objects.firstNonNull(isNotifiedForInvoices, delegate.isNotifiedForInvoices()));
+
+        return new DefaultAccount(delegate.getId(), accountData);
+    }
 
     @Override
-	public MutableAccountData toMutableAccountData() {
-	    return new DefaultMutableAccountData(this);
-	}
-    
-	@Override
-	public String toString() {
-		return "DefaultAccount [externalKey=" + externalKey +
+    public String toString() {
+        return "DefaultAccount [externalKey=" + externalKey +
                 ", email=" + email +
-				", name=" + name +
-				", firstNameLength=" + firstNameLength +
-				", phone=" + phone +
-				", currency=" + currency +
-				", billCycleDay=" + billCycleDay +
-				", paymentMethodId=" + paymentMethodId +
-				", timezone=" + timeZone +
-				", locale=" +  locale +
-				", address1=" + address1 +
-				", address2=" + address2 +
-				", companyName=" + companyName +
-				", city=" + city +
-				", stateOrProvince=" + stateOrProvince +
-				", postalCode=" + postalCode +
-				", country=" + country +
-				"]";
-	}
-
-	@Override
-	public BlockingState getBlockingState() {
-	    throw new UnsupportedOperationException();
-	}
-}
\ No newline at end of file
+                ", name=" + name +
+                ", firstNameLength=" + firstNameLength +
+                ", phone=" + phone +
+                ", currency=" + currency +
+                ", billCycleDay=" + billCycleDay +
+                ", paymentMethodId=" + paymentMethodId +
+                ", timezone=" + timeZone +
+                ", locale=" + locale +
+                ", address1=" + address1 +
+                ", address2=" + address2 +
+                ", companyName=" + companyName +
+                ", city=" + city +
+                ", stateOrProvince=" + stateOrProvince +
+                ", postalCode=" + postalCode +
+                ", country=" + country +
+                "]";
+    }
+
+    @Override
+    public BlockingState getBlockingState() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/account/src/main/java/com/ning/billing/account/api/DefaultAccountEmail.java b/account/src/main/java/com/ning/billing/account/api/DefaultAccountEmail.java
index 9ae0760..2be4a58 100644
--- a/account/src/main/java/com/ning/billing/account/api/DefaultAccountEmail.java
+++ b/account/src/main/java/com/ning/billing/account/api/DefaultAccountEmail.java
@@ -16,25 +16,25 @@
 
 package com.ning.billing.account.api;
 
-import com.ning.billing.util.entity.UpdatableEntityBase;
-
 import java.util.UUID;
 
+import com.ning.billing.util.entity.UpdatableEntityBase;
+
 public class DefaultAccountEmail extends UpdatableEntityBase implements AccountEmail {
     private final UUID accountId;
     private final String email;
 
-    public DefaultAccountEmail(UUID accountId, String email) {
+    public DefaultAccountEmail(final UUID accountId, final String email) {
         super();
         this.accountId = accountId;
         this.email = email;
     }
 
-    public DefaultAccountEmail(AccountEmail source, String newEmail) {
+    public DefaultAccountEmail(final AccountEmail source, final String newEmail) {
         this(source.getAccountId(), newEmail);
     }
 
-    public DefaultAccountEmail(UUID id, UUID accountId, String email) {
+    public DefaultAccountEmail(final UUID id, final UUID accountId, final String email) {
         super(id);
         this.accountId = accountId;
         this.email = email;
@@ -51,22 +51,40 @@ public class DefaultAccountEmail extends UpdatableEntityBase implements AccountE
     }
 
     @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("DefaultAccountEmail");
+        sb.append("{accountId=").append(accountId);
+        sb.append(", email='").append(email).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
 
-        DefaultAccountEmail that = (DefaultAccountEmail) o;
+        final DefaultAccountEmail that = (DefaultAccountEmail) o;
 
-        if (!accountId.equals(that.accountId)) return false;
-        if (!email.equals(that.email)) return false;
+        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+            return false;
+        }
+        if (email != null ? !email.equals(that.email) : that.email != null) {
+            return false;
+        }
 
         return true;
     }
 
     @Override
     public int hashCode() {
-        int result = accountId.hashCode();
-        result = 31 * result + email.hashCode();
+        int result = accountId != null ? accountId.hashCode() : 0;
+        result = 31 * result + (email != null ? email.hashCode() : 0);
         return result;
     }
 }
diff --git a/account/src/main/java/com/ning/billing/account/api/DefaultAccountService.java b/account/src/main/java/com/ning/billing/account/api/DefaultAccountService.java
index af3d2a7..9b0cfc1 100644
--- a/account/src/main/java/com/ning/billing/account/api/DefaultAccountService.java
+++ b/account/src/main/java/com/ning/billing/account/api/DefaultAccountService.java
@@ -21,7 +21,7 @@ public class DefaultAccountService implements AccountService {
 
     private static final String ACCOUNT_SERVICE_NAME = "account-service";
 
-   @Override
+    @Override
     public String getName() {
         return ACCOUNT_SERVICE_NAME;
     }
diff --git a/account/src/main/java/com/ning/billing/account/api/DefaultChangedField.java b/account/src/main/java/com/ning/billing/account/api/DefaultChangedField.java
index 89a65f6..8501b9f 100644
--- a/account/src/main/java/com/ning/billing/account/api/DefaultChangedField.java
+++ b/account/src/main/java/com/ning/billing/account/api/DefaultChangedField.java
@@ -16,35 +16,36 @@
 
 package com.ning.billing.account.api;
 
+import org.joda.time.DateTime;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import org.joda.time.DateTime;
 
 public class DefaultChangedField implements ChangedField {
-    
+
     private final String fieldName;
     private final String oldValue;
     private final String newValue;
     private final DateTime changeDate;
 
     @JsonCreator
-    public DefaultChangedField(@JsonProperty("fieldName") String fieldName,
-            @JsonProperty("oldValue") String oldValue,
-            @JsonProperty("newValue") String newValue,
-            @JsonProperty("changeDate") DateTime changeDate) {
+    public DefaultChangedField(@JsonProperty("fieldName") final String fieldName,
+                               @JsonProperty("oldValue") final String oldValue,
+                               @JsonProperty("newValue") final String newValue,
+                               @JsonProperty("changeDate") final DateTime changeDate) {
         this.changeDate = changeDate;
         this.fieldName = fieldName;
         this.oldValue = oldValue;
         this.newValue = newValue;
     }
 
-    public DefaultChangedField(String fieldName,
-            String oldValue,
-            String newValue) {
+    public DefaultChangedField(final String fieldName,
+                               final String oldValue,
+                               final String newValue) {
         this(fieldName, oldValue, newValue, new DateTime());
     }
 
-    
+
     @Override
     public String getFieldName() {
         return fieldName;
@@ -81,35 +82,46 @@ public class DefaultChangedField implements ChangedField {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        DefaultChangedField other = (DefaultChangedField) obj;
+        }
+        final DefaultChangedField other = (DefaultChangedField) obj;
         if (changeDate == null) {
-            if (other.changeDate != null)
+            if (other.changeDate != null) {
                 return false;
-        } else if (changeDate.compareTo(other.changeDate) != 0)
+            }
+        } else if (changeDate.compareTo(other.changeDate) != 0) {
             return false;
+        }
         if (fieldName == null) {
-            if (other.fieldName != null)
+            if (other.fieldName != null) {
                 return false;
-        } else if (!fieldName.equals(other.fieldName))
+            }
+        } else if (!fieldName.equals(other.fieldName)) {
             return false;
+        }
         if (newValue == null) {
-            if (other.newValue != null)
+            if (other.newValue != null) {
                 return false;
-        } else if (!newValue.equals(other.newValue))
+            }
+        } else if (!newValue.equals(other.newValue)) {
             return false;
+        }
         if (oldValue == null) {
-            if (other.oldValue != null)
+            if (other.oldValue != null) {
                 return false;
-        } else if (!oldValue.equals(other.oldValue))
+            }
+        } else if (!oldValue.equals(other.oldValue)) {
             return false;
+        }
         return true;
     }
-    
+
 }
diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountChangeEvent.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountChangeEvent.java
index 412bc5e..e8ceefb 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountChangeEvent.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountChangeEvent.java
@@ -16,6 +16,10 @@
 
 package com.ning.billing.account.api.user;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -25,21 +29,17 @@ import com.ning.billing.account.api.AccountChangeEvent;
 import com.ning.billing.account.api.ChangedField;
 import com.ning.billing.account.api.DefaultChangedField;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
 public class DefaultAccountChangeEvent implements AccountChangeEvent {
-	
-	private final UUID userToken;
+
+    private final UUID userToken;
     private final List<ChangedField> changedFields;
     private final UUID accountId;
 
-    
+
     @JsonCreator
-    public DefaultAccountChangeEvent(@JsonProperty("userToken") UUID userToken,
-            @JsonProperty("changeFields") List<ChangedField> changedFields,
-            @JsonProperty("accountId") UUID accountId) {
+    public DefaultAccountChangeEvent(@JsonProperty("userToken") final UUID userToken,
+                                     @JsonProperty("changeFields") final List<ChangedField> changedFields,
+                                     @JsonProperty("accountId") final UUID accountId) {
         super();
         this.userToken = userToken;
         this.accountId = accountId;
@@ -48,22 +48,22 @@ public class DefaultAccountChangeEvent implements AccountChangeEvent {
         //this.changedFields.addAll(changedFields);
     }
 
-    public DefaultAccountChangeEvent(UUID id, UUID userToken, Account oldData, Account newData) {
+    public DefaultAccountChangeEvent(final UUID id, final UUID userToken, final Account oldData, final Account newData) {
         this.accountId = id;
         this.userToken = userToken;
         this.changedFields = calculateChangedFields(oldData, newData);
     }
 
     @JsonIgnore
-	@Override
-	public BusEventType getBusEventType() {
-		return BusEventType.ACCOUNT_CHANGE;
-	}
+    @Override
+    public BusEventType getBusEventType() {
+        return BusEventType.ACCOUNT_CHANGE;
+    }
 
     @Override
     public UUID getUserToken() {
         return userToken;
-	}
+    }
 
     @Override
     public UUID getAccountId() {
@@ -96,62 +96,71 @@ public class DefaultAccountChangeEvent implements AccountChangeEvent {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        DefaultAccountChangeEvent other = (DefaultAccountChangeEvent) obj;
+        }
+        final DefaultAccountChangeEvent other = (DefaultAccountChangeEvent) obj;
         if (accountId == null) {
-            if (other.accountId != null)
+            if (other.accountId != null) {
                 return false;
-        } else if (!accountId.equals(other.accountId))
+            }
+        } else if (!accountId.equals(other.accountId)) {
             return false;
+        }
         if (changedFields == null) {
-            if (other.changedFields != null)
+            if (other.changedFields != null) {
                 return false;
-        } else if (!changedFields.equals(other.changedFields))
+            }
+        } else if (!changedFields.equals(other.changedFields)) {
             return false;
+        }
         if (userToken == null) {
-            if (other.userToken != null)
+            if (other.userToken != null) {
                 return false;
-        } else if (!userToken.equals(other.userToken))
+            }
+        } else if (!userToken.equals(other.userToken)) {
             return false;
+        }
         return true;
     }
 
-    private List<ChangedField> calculateChangedFields(Account oldData, Account newData) {
+    private List<ChangedField> calculateChangedFields(final Account oldData, final Account newData) {
 
-        List<ChangedField> tmpChangedFields = new ArrayList<ChangedField>();
+        final List<ChangedField> tmpChangedFields = new ArrayList<ChangedField>();
 
         addIfValueChanged(tmpChangedFields, "externalKey",
-                oldData.getExternalKey(), newData.getExternalKey());
+                          oldData.getExternalKey(), newData.getExternalKey());
 
         addIfValueChanged(tmpChangedFields, "email",
-                oldData.getEmail(), newData.getEmail());
+                          oldData.getEmail(), newData.getEmail());
 
         addIfValueChanged(tmpChangedFields, "firstName",
-                oldData.getName(), newData.getName());
+                          oldData.getName(), newData.getName());
 
         addIfValueChanged(tmpChangedFields, "currency",
-                (oldData.getCurrency() != null) ? oldData.getCurrency().toString() : null,
-                 (newData.getCurrency() != null) ? newData.getCurrency().toString() : null);
+                          (oldData.getCurrency() != null) ? oldData.getCurrency().toString() : null,
+                          (newData.getCurrency() != null) ? newData.getCurrency().toString() : null);
 
         addIfValueChanged(tmpChangedFields,
-                "billCycleDay",
-                Integer.toString(oldData.getBillCycleDay()), Integer.toString(newData.getBillCycleDay()));
+                          "billCycleDay",
+                          Integer.toString(oldData.getBillCycleDay()), Integer.toString(newData.getBillCycleDay()));
 
-        addIfValueChanged(tmpChangedFields,"paymentMethodId",
-                (oldData.getPaymentMethodId() != null) ? oldData.getPaymentMethodId().toString() : null,
-                (newData.getPaymentMethodId() != null) ? newData.getPaymentMethodId().toString(): null);
+        addIfValueChanged(tmpChangedFields, "paymentMethodId",
+                          (oldData.getPaymentMethodId() != null) ? oldData.getPaymentMethodId().toString() : null,
+                          (newData.getPaymentMethodId() != null) ? newData.getPaymentMethodId().toString() : null);
 
         addIfValueChanged(tmpChangedFields, "locale", oldData.getLocale(), newData.getLocale());
 
         addIfValueChanged(tmpChangedFields, "timeZone",
-                (oldData.getTimeZone() == null) ? null : oldData.getTimeZone().toString(),
-                (newData.getTimeZone() == null) ? null : newData.getTimeZone().toString());
+                          (oldData.getTimeZone() == null) ? null : oldData.getTimeZone().toString(),
+                          (newData.getTimeZone() == null) ? null : newData.getTimeZone().toString());
 
         addIfValueChanged(tmpChangedFields, "address1", oldData.getAddress1(), newData.getAddress1());
         addIfValueChanged(tmpChangedFields, "address2", oldData.getAddress2(), newData.getAddress2());
@@ -164,14 +173,13 @@ public class DefaultAccountChangeEvent implements AccountChangeEvent {
         return tmpChangedFields;
     }
 
-    private void addIfValueChanged(List<ChangedField> inputList, String key, String oldData, String newData) {
+    private void addIfValueChanged(final List<ChangedField> inputList, final String key, final String oldData, final String newData) {
         // If both null => no changes
         if (newData == null && oldData == null) {
-            return;
-        // If only one is null
+            // If only one is null
         } else if (newData == null || oldData == null) {
             inputList.add(new DefaultChangedField(key, oldData, newData));
-        // If neither are null we can safely compare values
+            // If neither are null we can safely compare values
         } else if (!newData.equals(oldData)) {
             inputList.add(new DefaultChangedField(key, oldData, newData));
         }
diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountCreationEvent.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountCreationEvent.java
index 57f2504..025ff14 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountCreationEvent.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountCreationEvent.java
@@ -16,6 +16,10 @@
 
 package com.ning.billing.account.api.user;
 
+import java.util.UUID;
+
+import org.joda.time.DateTimeZone;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -24,41 +28,38 @@ import com.ning.billing.account.api.AccountCreationEvent;
 import com.ning.billing.account.api.AccountData;
 import com.ning.billing.catalog.api.Currency;
 
-import java.util.UUID;
-
-import org.joda.time.DateTimeZone;
-
 public class DefaultAccountCreationEvent implements AccountCreationEvent {
-	
-	private final UUID userToken;	
+
+    private final UUID userToken;
     private final UUID id;
     private final AccountData data;
 
     @JsonCreator
-    public DefaultAccountCreationEvent(@JsonProperty("data") DefaultAccountData data,
-            @JsonProperty("userToken") UUID userToken,
-            @JsonProperty("id") UUID id) {
+    public DefaultAccountCreationEvent(@JsonProperty("data") final DefaultAccountData data,
+                                       @JsonProperty("userToken") final UUID userToken,
+                                       @JsonProperty("id") final UUID id) {
         this.id = id;
         this.userToken = userToken;
         this.data = data;
     }
-    
-    public DefaultAccountCreationEvent(Account data, UUID userToken) {
+
+    public DefaultAccountCreationEvent(final Account data, final UUID userToken) {
         this.id = data.getId();
         this.data = new DefaultAccountData(data);
         this.userToken = userToken;
     }
 
     @JsonIgnore
-	@Override
-	public BusEventType getBusEventType() {
-		return BusEventType.ACCOUNT_CREATE;
-	}
+    @Override
+    public BusEventType getBusEventType() {
+        return BusEventType.ACCOUNT_CREATE;
+    }
 
     @Override
     public UUID getUserToken() {
-    	return userToken;
+        return userToken;
     }
+
     @Override
     public UUID getId() {
         return id;
@@ -68,8 +69,8 @@ public class DefaultAccountCreationEvent implements AccountCreationEvent {
     public AccountData getData() {
         return data;
     }
-    
-    
+
+
     @Override
     public int hashCode() {
         final int prime = 31;
@@ -82,35 +83,43 @@ public class DefaultAccountCreationEvent implements AccountCreationEvent {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        DefaultAccountCreationEvent other = (DefaultAccountCreationEvent) obj;
+        }
+        final DefaultAccountCreationEvent other = (DefaultAccountCreationEvent) obj;
         if (data == null) {
-            if (other.data != null)
+            if (other.data != null) {
                 return false;
-        } else if (!data.equals(other.data))
+            }
+        } else if (!data.equals(other.data)) {
             return false;
+        }
         if (id == null) {
-            if (other.id != null)
+            if (other.id != null) {
                 return false;
-        } else if (!id.equals(other.id))
+            }
+        } else if (!id.equals(other.id)) {
             return false;
+        }
         if (userToken == null) {
-            if (other.userToken != null)
+            if (other.userToken != null) {
                 return false;
-        } else if (!userToken.equals(other.userToken))
+            }
+        } else if (!userToken.equals(other.userToken)) {
             return false;
+        }
         return true;
     }
 
 
     public static class DefaultAccountData implements AccountData {
-
         private final String externalKey;
         private final String name;
         private final Integer firstNameLength;
@@ -130,50 +139,49 @@ public class DefaultAccountCreationEvent implements AccountCreationEvent {
         private final String phone;
         private final boolean isMigrated;
         private final boolean isNotifiedForInvoices;
-        
-        
-        public DefaultAccountData(Account d) {
-            this(d.getExternalKey() != null ?  d.getExternalKey().toString() : null,
-                    d.getName(),
-                    d.getFirstNameLength(),
-                    d.getEmail(),
-                    d.getBillCycleDay(),
-                    d.getCurrency() != null ?  d.getCurrency().name() : null,
-                    d.getPaymentMethodId(), 
-                    d.getTimeZone() != null ?  d.getTimeZone().getID() : null,
-                    d.getLocale(),
-                    d.getAddress1(),
-                    d.getAddress2(),
-                    d.getCompanyName(),
-                    d.getCity(),
-                    d.getStateOrProvince(),
-                    d.getPostalCode(),
-                    d.getCountry(),
-                    d.getPhone(),
-                    d.isMigrated(),
-                    d.isNotifiedForInvoices());
+
+        public DefaultAccountData(final Account d) {
+            this(d.getExternalKey() != null ? d.getExternalKey() : null,
+                 d.getName(),
+                 d.getFirstNameLength(),
+                 d.getEmail(),
+                 d.getBillCycleDay(),
+                 d.getCurrency() != null ? d.getCurrency().name() : null,
+                 d.getPaymentMethodId(),
+                 d.getTimeZone() != null ? d.getTimeZone().getID() : null,
+                 d.getLocale(),
+                 d.getAddress1(),
+                 d.getAddress2(),
+                 d.getCompanyName(),
+                 d.getCity(),
+                 d.getStateOrProvince(),
+                 d.getPostalCode(),
+                 d.getCountry(),
+                 d.getPhone(),
+                 d.isMigrated(),
+                 d.isNotifiedForInvoices());
         }
-        
+
         @JsonCreator
-        public DefaultAccountData(@JsonProperty("externalKey") String externalKey,
-                @JsonProperty("name") String name,
-                @JsonProperty("firstNameLength") Integer firstNameLength,
-                @JsonProperty("email") String email,
-                @JsonProperty("billCycleDay") Integer billCycleDay,
-                @JsonProperty("currency") String currency,
-                @JsonProperty("paymentMethodId") UUID paymentMethodId,
-                @JsonProperty("timeZone") String timeZone,
-                @JsonProperty("locale") String locale,
-                @JsonProperty("address1") String address1,
-                @JsonProperty("address2") String address2,
-                @JsonProperty("companyName") String companyName,
-                @JsonProperty("city") String city,
-                @JsonProperty("stateOrProvince") String stateOrProvince,
-                @JsonProperty("postalCode") String postalCode,
-                @JsonProperty("country") String country,
-                @JsonProperty("phone") String phone,
-                @JsonProperty("isMigrated") boolean isMigrated,
-                @JsonProperty("isNotifiedForInvoices") boolean isNotifiedForInvoices) {
+        public DefaultAccountData(@JsonProperty("externalKey") final String externalKey,
+                                  @JsonProperty("name") final String name,
+                                  @JsonProperty("firstNameLength") final Integer firstNameLength,
+                                  @JsonProperty("email") final String email,
+                                  @JsonProperty("billCycleDay") final Integer billCycleDay,
+                                  @JsonProperty("currency") final String currency,
+                                  @JsonProperty("paymentMethodId") final UUID paymentMethodId,
+                                  @JsonProperty("timeZone") final String timeZone,
+                                  @JsonProperty("locale") final String locale,
+                                  @JsonProperty("address1") final String address1,
+                                  @JsonProperty("address2") final String address2,
+                                  @JsonProperty("companyName") final String companyName,
+                                  @JsonProperty("city") final String city,
+                                  @JsonProperty("stateOrProvince") final String stateOrProvince,
+                                  @JsonProperty("postalCode") final String postalCode,
+                                  @JsonProperty("country") final String country,
+                                  @JsonProperty("phone") final String phone,
+                                  @JsonProperty("isMigrated") final boolean isMigrated,
+                                  @JsonProperty("isNotifiedForInvoices") final boolean isNotifiedForInvoices) {
             super();
             this.externalKey = externalKey;
             this.name = name;
@@ -207,7 +215,7 @@ public class DefaultAccountCreationEvent implements AccountCreationEvent {
         }
 
         @Override
-        public int getFirstNameLength() {
+        public Integer getFirstNameLength() {
             return firstNameLength;
         }
 
@@ -217,7 +225,7 @@ public class DefaultAccountCreationEvent implements AccountCreationEvent {
         }
 
         @Override
-        public int getBillCycleDay() {
+        public Integer getBillCycleDay() {
             return billCycleDay;
         }
 
@@ -231,7 +239,7 @@ public class DefaultAccountCreationEvent implements AccountCreationEvent {
         public DateTimeZone getTimeZone() {
             return DateTimeZone.forID(timeZone);
         }
-        
+
         @JsonProperty("timeZone")
         public String getTimeZoneString() {
             return timeZone;
@@ -289,13 +297,13 @@ public class DefaultAccountCreationEvent implements AccountCreationEvent {
 
         @Override
         @JsonIgnore
-        public boolean isMigrated() {
+        public Boolean isMigrated() {
             return isMigrated;
         }
 
         @Override
         @JsonIgnore
-        public boolean isNotifiedForInvoices() {
+        public Boolean isNotifiedForInvoices() {
             return isNotifiedForInvoices;
         }
 
@@ -322,120 +330,157 @@ public class DefaultAccountCreationEvent implements AccountCreationEvent {
             result = prime
                     * result
                     + ((firstNameLength == null) ? 0 : firstNameLength
-                            .hashCode());
+                    .hashCode());
             result = prime * result
                     + ((locale == null) ? 0 : locale.hashCode());
             result = prime * result + ((name == null) ? 0 : name.hashCode());
             result = prime
                     * result
                     + ((paymentMethodId == null) ? 0 : paymentMethodId
-                            .hashCode());
+                    .hashCode());
             result = prime * result + ((phone == null) ? 0 : phone.hashCode());
             result = prime * result
                     + ((postalCode == null) ? 0 : postalCode.hashCode());
             result = prime
                     * result
                     + ((stateOrProvince == null) ? 0 : stateOrProvince
-                            .hashCode());
+                    .hashCode());
             result = prime * result
                     + ((timeZone == null) ? 0 : timeZone.hashCode());
             return result;
         }
 
         @Override
-        public boolean equals(Object obj) {
-            if (this == obj)
+        public boolean equals(final Object obj) {
+            if (this == obj) {
                 return true;
-            if (obj == null)
+            }
+            if (obj == null) {
                 return false;
-            if (getClass() != obj.getClass())
+            }
+            if (getClass() != obj.getClass()) {
                 return false;
-            DefaultAccountData other = (DefaultAccountData) obj;
+            }
+            final DefaultAccountData other = (DefaultAccountData) obj;
             if (address1 == null) {
-                if (other.address1 != null)
+                if (other.address1 != null) {
                     return false;
-            } else if (!address1.equals(other.address1))
+                }
+            } else if (!address1.equals(other.address1)) {
                 return false;
+            }
             if (address2 == null) {
-                if (other.address2 != null)
+                if (other.address2 != null) {
                     return false;
-            } else if (!address2.equals(other.address2))
+                }
+            } else if (!address2.equals(other.address2)) {
                 return false;
+            }
             if (billCycleDay == null) {
-                if (other.billCycleDay != null)
+                if (other.billCycleDay != null) {
                     return false;
-            } else if (!billCycleDay.equals(other.billCycleDay))
+                }
+            } else if (!billCycleDay.equals(other.billCycleDay)) {
                 return false;
+            }
             if (city == null) {
-                if (other.city != null)
+                if (other.city != null) {
                     return false;
-            } else if (!city.equals(other.city))
+                }
+            } else if (!city.equals(other.city)) {
                 return false;
+            }
             if (companyName == null) {
-                if (other.companyName != null)
+                if (other.companyName != null) {
                     return false;
-            } else if (!companyName.equals(other.companyName))
+                }
+            } else if (!companyName.equals(other.companyName)) {
                 return false;
+            }
             if (country == null) {
-                if (other.country != null)
+                if (other.country != null) {
                     return false;
-            } else if (!country.equals(other.country))
+                }
+            } else if (!country.equals(other.country)) {
                 return false;
+            }
             if (currency == null) {
-                if (other.currency != null)
+                if (other.currency != null) {
                     return false;
-            } else if (!currency.equals(other.currency))
+                }
+            } else if (!currency.equals(other.currency)) {
                 return false;
+            }
             if (email == null) {
-                if (other.email != null)
+                if (other.email != null) {
                     return false;
-            } else if (!email.equals(other.email))
+                }
+            } else if (!email.equals(other.email)) {
                 return false;
+            }
             if (externalKey == null) {
-                if (other.externalKey != null)
+                if (other.externalKey != null) {
                     return false;
-            } else if (!externalKey.equals(other.externalKey))
+                }
+            } else if (!externalKey.equals(other.externalKey)) {
                 return false;
+            }
             if (firstNameLength == null) {
-                if (other.firstNameLength != null)
+                if (other.firstNameLength != null) {
                     return false;
-            } else if (!firstNameLength.equals(other.firstNameLength))
+                }
+            } else if (!firstNameLength.equals(other.firstNameLength)) {
                 return false;
+            }
             if (locale == null) {
-                if (other.locale != null)
+                if (other.locale != null) {
                     return false;
-            } else if (!locale.equals(other.locale))
+                }
+            } else if (!locale.equals(other.locale)) {
                 return false;
+            }
             if (name == null) {
-                if (other.name != null)
+                if (other.name != null) {
                     return false;
-            } else if (!name.equals(other.name))
+                }
+            } else if (!name.equals(other.name)) {
                 return false;
+            }
             if (paymentMethodId == null) {
-                if (other.paymentMethodId != null)
+                if (other.paymentMethodId != null) {
                     return false;
-            } else if (!paymentMethodId.equals(other.paymentMethodId))
+                }
+            } else if (!paymentMethodId.equals(other.paymentMethodId)) {
                 return false;
+            }
             if (phone == null) {
-                if (other.phone != null)
+                if (other.phone != null) {
                     return false;
-            } else if (!phone.equals(other.phone))
+                }
+            } else if (!phone.equals(other.phone)) {
                 return false;
+            }
             if (postalCode == null) {
-                if (other.postalCode != null)
+                if (other.postalCode != null) {
                     return false;
-            } else if (!postalCode.equals(other.postalCode))
+                }
+            } else if (!postalCode.equals(other.postalCode)) {
                 return false;
+            }
             if (stateOrProvince == null) {
-                if (other.stateOrProvince != null)
+                if (other.stateOrProvince != null) {
                     return false;
-            } else if (!stateOrProvince.equals(other.stateOrProvince))
+                }
+            } else if (!stateOrProvince.equals(other.stateOrProvince)) {
                 return false;
+            }
             if (timeZone == null) {
-                if (other.timeZone != null)
+                if (other.timeZone != null) {
                     return false;
-            } else if (!timeZone.equals(other.timeZone))
+                }
+            } else if (!timeZone.equals(other.timeZone)) {
                 return false;
+            }
             return true;
         }
     }
diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
index d7d8049..057aaf6 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
@@ -145,4 +145,14 @@ public class DefaultAccountUserApi implements AccountUserApi {
     public void saveEmails(final UUID accountId, final List<AccountEmail> newEmails, final CallContext context) {
         accountEmailDao.saveEmails(accountId, newEmails, context);
     }
+
+    @Override
+    public void addEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+        accountEmailDao.addEmail(accountId, email, context);
+    }
+
+    @Override
+    public void removeEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+        accountEmailDao.removeEmail(accountId, email, context);
+    }
 }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java b/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java
index 67c707a..a170b64 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java
@@ -16,19 +16,20 @@
 
 package com.ning.billing.account.dao;
 
-import com.ning.billing.account.api.Account;
-import com.ning.billing.catalog.api.Currency;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
 import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.sqlobject.Binder;
 import org.skife.jdbi.v2.sqlobject.BinderFactory;
 import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
 
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.catalog.api.Currency;
 
 @BindingAnnotation(AccountBinder.AccountBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
@@ -36,20 +37,20 @@ import java.lang.annotation.Target;
 public @interface AccountBinder {
     public static class AccountBinderFactory implements BinderFactory {
         @Override
-        public Binder<AccountBinder, Account> build(Annotation annotation) {
+        public Binder<AccountBinder, Account> build(final Annotation annotation) {
             return new Binder<AccountBinder, Account>() {
                 @Override
-                public void bind(@SuppressWarnings("rawtypes") SQLStatement q, AccountBinder bind, Account account) {
+                public void bind(@SuppressWarnings("rawtypes") final SQLStatement q, final AccountBinder bind, final Account account) {
                     q.bind("id", account.getId().toString());
                     q.bind("externalKey", account.getExternalKey());
                     q.bind("email", account.getEmail());
                     q.bind("name", account.getName());
                     q.bind("firstNameLength", account.getFirstNameLength());
-                    Currency currency = account.getCurrency();
+                    final Currency currency = account.getCurrency();
                     q.bind("currency", (currency == null) ? null : currency.toString());
                     q.bind("billingCycleDay", account.getBillCycleDay());
                     q.bind("paymentMethodId", account.getPaymentMethodId() != null ? account.getPaymentMethodId().toString() : null);
-                    DateTimeZone timeZone = account.getTimeZone();
+                    final DateTimeZone timeZone = account.getTimeZone();
                     q.bind("timeZone", (timeZone == null) ? null : timeZone.toString());
                     q.bind("locale", account.getLocale());
                     q.bind("address1", account.getAddress1());
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
index 67474ab..2f3cd25 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
@@ -16,22 +16,19 @@
 
 package com.ning.billing.account.dao;
 
-import java.util.List;
 import java.util.UUID;
+
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
-import com.ning.billing.account.api.AccountEmail;
-import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.entity.dao.UpdatableEntityDao;
 
 public interface AccountDao extends UpdatableEntityDao<Account> {
     public Account getAccountByKey(String key);
 
-    /***
-     *
+    /**
      * @param externalKey
      * @return
      * @throws AccountApiException when externalKey is null
      */
     public UUID getIdFromKey(String externalKey) throws AccountApiException;
-}
\ No newline at end of file
+}
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountEmailBinder.java b/account/src/main/java/com/ning/billing/account/dao/AccountEmailBinder.java
index bd71364..bf2cb77 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountEmailBinder.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountEmailBinder.java
@@ -16,28 +16,29 @@
 
 package com.ning.billing.account.dao;
 
-import com.ning.billing.account.api.AccountEmail;
-import org.skife.jdbi.v2.SQLStatement;
-import org.skife.jdbi.v2.sqlobject.Binder;
-import org.skife.jdbi.v2.sqlobject.BinderFactory;
-import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import com.ning.billing.account.api.AccountEmail;
+
 @BindingAnnotation(AccountEmailBinder.AccountEmailBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface AccountEmailBinder {
     public static class AccountEmailBinderFactory implements BinderFactory {
         @Override
-        public Binder<AccountEmailBinder, AccountEmail> build(Annotation annotation) {
+        public Binder<AccountEmailBinder, AccountEmail> build(final Annotation annotation) {
             return new Binder<AccountEmailBinder, AccountEmail>() {
                 @Override
-                public void bind(@SuppressWarnings("rawtypes") SQLStatement q, AccountEmailBinder bind, AccountEmail accountEmail) {
+                public void bind(@SuppressWarnings("rawtypes") final SQLStatement q, final AccountEmailBinder bind, final AccountEmail accountEmail) {
                     q.bind("id", accountEmail.getId().toString());
                     q.bind("accountId", accountEmail.getAccountId().toString());
                     q.bind("email", accountEmail.getEmail());
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountEmailDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountEmailDao.java
index c0c4174..09f2cda 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountEmailDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountEmailDao.java
@@ -16,16 +16,27 @@
 
 package com.ning.billing.account.dao;
 
-import com.ning.billing.account.api.AccountEmail;
-import com.ning.billing.util.callcontext.CallContext;
-
 import java.util.List;
 import java.util.UUID;
 
+import com.ning.billing.account.api.AccountEmail;
+import com.ning.billing.util.callcontext.CallContext;
+
 public interface AccountEmailDao {
     public List<AccountEmail> getEmails(UUID accountId);
 
+    /**
+     * Add, remove or update the list of emails in this account.
+     *
+     * @param accountId id of the account
+     * @param emails    the final list of emails
+     * @param context   the call context
+     */
     public void saveEmails(UUID accountId, List<AccountEmail> emails, CallContext context);
 
+    public void addEmail(UUID accountId, AccountEmail email, CallContext context);
+
+    public void removeEmail(UUID accountId, AccountEmail email, CallContext context);
+
     public void test();
 }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountEmailHistoryBinder.java b/account/src/main/java/com/ning/billing/account/dao/AccountEmailHistoryBinder.java
index 01344b3..a704198 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountEmailHistoryBinder.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountEmailHistoryBinder.java
@@ -16,33 +16,34 @@
 
 package com.ning.billing.account.dao;
 
-import com.ning.billing.account.api.AccountEmail;
-import com.ning.billing.util.dao.EntityHistory;
-import org.skife.jdbi.v2.SQLStatement;
-import org.skife.jdbi.v2.sqlobject.Binder;
-import org.skife.jdbi.v2.sqlobject.BinderFactory;
-import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import com.ning.billing.account.api.AccountEmail;
+import com.ning.billing.util.dao.EntityHistory;
+
 @BindingAnnotation(AccountEmailHistoryBinder.AccountEmailHistoryBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface AccountEmailHistoryBinder {
     public static class AccountEmailHistoryBinderFactory implements BinderFactory {
         @Override
-        public Binder<AccountEmailHistoryBinder, EntityHistory<AccountEmail>> build(Annotation annotation) {
+        public Binder<AccountEmailHistoryBinder, EntityHistory<AccountEmail>> build(final Annotation annotation) {
             return new Binder<AccountEmailHistoryBinder, EntityHistory<AccountEmail>>() {
                 @Override
-                public void bind(SQLStatement q, AccountEmailHistoryBinder bind, EntityHistory<AccountEmail> history) {
+                public void bind(final SQLStatement<?> q, final AccountEmailHistoryBinder bind, final EntityHistory<AccountEmail> history) {
                     q.bind("recordId", history.getValue());
                     q.bind("changeType", history.getChangeType().toString());
 
-                    AccountEmail accountEmail = history.getEntity();
+                    final AccountEmail accountEmail = history.getEntity();
                     q.bind("id", accountEmail.getId().toString());
                     q.bind("accountId", accountEmail.getAccountId().toString());
                     q.bind("email", accountEmail.getEmail());
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountEmailMapper.java b/account/src/main/java/com/ning/billing/account/dao/AccountEmailMapper.java
index 9a46344..9bfcbee 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountEmailMapper.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountEmailMapper.java
@@ -16,23 +16,23 @@
 
 package com.ning.billing.account.dao;
 
-import com.ning.billing.account.api.AccountEmail;
-import com.ning.billing.account.api.DefaultAccountEmail;
-import com.ning.billing.util.dao.MapperBase;
-import org.joda.time.DateTime;
-import org.skife.jdbi.v2.StatementContext;
-import org.skife.jdbi.v2.tweak.ResultSetMapper;
-
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.UUID;
 
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.account.api.AccountEmail;
+import com.ning.billing.account.api.DefaultAccountEmail;
+import com.ning.billing.util.dao.MapperBase;
+
 public class AccountEmailMapper extends MapperBase implements ResultSetMapper<AccountEmail> {
     @Override
-    public AccountEmail map(int index, ResultSet result, StatementContext context) throws SQLException {
-        UUID id = UUID.fromString(result.getString("id"));
-        UUID accountId = UUID.fromString(result.getString("account_id"));
-        String email = result.getString("email");
+    public AccountEmail map(final int index, final ResultSet result, final StatementContext context) throws SQLException {
+        final UUID id = UUID.fromString(result.getString("id"));
+        final UUID accountId = UUID.fromString(result.getString("account_id"));
+        final String email = result.getString("email");
 
         return new DefaultAccountEmail(id, accountId, email);
     }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountEmailSqlDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountEmailSqlDao.java
index e2cc293..589a028 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountEmailSqlDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountEmailSqlDao.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * 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
@@ -38,64 +38,30 @@ import com.ning.billing.util.entity.collection.dao.UpdatableEntityCollectionSqlD
 @RegisterMapper(AccountEmailMapper.class)
 public interface AccountEmailSqlDao extends UpdatableEntityCollectionSqlDao<AccountEmail>, Transactional<AccountEmailSqlDao>, Transmogrifier {
     @Override
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void insertFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @AccountEmailBinder final Collection<AccountEmail> entities,
                                       @CallContextBinder final CallContext context);
 
     @Override
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void updateFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @AccountEmailBinder final Collection<AccountEmail> entities,
                                       @CallContextBinder final CallContext context);
 
     @Override
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void deleteFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @AccountEmailBinder final Collection<AccountEmail> entities,
                                       @CallContextBinder final CallContext context);
 
     @Override
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void addHistoryFromTransaction(@Bind("objectId") final String objectId,
-                                               @ObjectTypeBinder final ObjectType objectType,
-                                               @AccountEmailHistoryBinder final List<EntityHistory<AccountEmail>> entities,
-                                               @CallContextBinder final CallContext context);
-//    @Override
-//    @SqlUpdate
-//    public void create(@AccountEmailBinder final AccountEmail accountEmail,
-//                       @CallContextBinder final CallContext context);
-
-//    @SqlBatch(transactional = false)
-//    public void create(@AccountEmailBinder final List<AccountEmail> accountEmailList,
-//                       @CallContextBinder final CallContext context);
-
-//    @Override
-//    @SqlUpdate
-//    public void update(@AccountEmailBinder final AccountEmail accountEmail,
-//                       @CallContextBinder final CallContext context);
-//
-//    @SqlBatch(transactional = false)
-//    public void update(@AccountEmailBinder final List<AccountEmail> accountEmailList,
-//                       @CallContextBinder final CallContext context);
-//
-//    @SqlUpdate
-//    public void delete(@AccountEmailBinder final AccountEmail accountEmail,
-//                       @CallContextBinder final CallContext context);
-//
-//    @SqlBatch(transactional = false)
-//    public void delete(@AccountEmailBinder final List<AccountEmail> accountEmailList,
-//                       @CallContextBinder final CallContext context);
-//
-//    @SqlBatch(transactional=false)
-//    public void insertAccountEmailHistoryFromTransaction(@Bind("historyRecordId") final List<String> historyRecordIdList,
-//                                                         @AccountEmailBinder final List<AccountEmail> accountEmail,
-//                                                         @ChangeTypeBinder final ChangeType changeType,
-//                                                         @CallContextBinder final CallContext context);
-//
-//    @SqlQuery
-//    public List<AccountEmail> getByAccountId(@Bind("accountId") final String accountId);
+                                          @ObjectTypeBinder final ObjectType objectType,
+                                          @AccountEmailHistoryBinder final List<EntityHistory<AccountEmail>> entities,
+                                          @CallContextBinder final CallContext context);
 }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountHistoryBinder.java b/account/src/main/java/com/ning/billing/account/dao/AccountHistoryBinder.java
index be30dc6..475bf26 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountHistoryBinder.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountHistoryBinder.java
@@ -16,20 +16,21 @@
 
 package com.ning.billing.account.dao;
 
-import com.ning.billing.account.api.Account;
-import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.dao.EntityHistory;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
 import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.sqlobject.Binder;
 import org.skife.jdbi.v2.sqlobject.BinderFactory;
 import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
 
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.dao.EntityHistory;
 
 @BindingAnnotation(AccountHistoryBinder.AccountHistoryBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
@@ -37,24 +38,24 @@ import java.lang.annotation.Target;
 public @interface AccountHistoryBinder {
     public static class AccountHistoryBinderFactory implements BinderFactory {
         @Override
-        public Binder<AccountHistoryBinder, EntityHistory<Account>> build(Annotation annotation) {
+        public Binder<AccountHistoryBinder, EntityHistory<Account>> build(final Annotation annotation) {
             return new Binder<AccountHistoryBinder, EntityHistory<Account>>() {
                 @Override
-                public void bind(SQLStatement q, AccountHistoryBinder bind, EntityHistory<Account> history) {
+                public void bind(final SQLStatement<?> q, final AccountHistoryBinder bind, final EntityHistory<Account> history) {
                     q.bind("recordId", history.getValue());
                     q.bind("changeType", history.getChangeType().toString());
 
-                    Account account = history.getEntity();
+                    final Account account = history.getEntity();
                     q.bind("id", account.getId().toString());
                     q.bind("externalKey", account.getExternalKey());
                     q.bind("email", account.getEmail());
                     q.bind("name", account.getName());
                     q.bind("firstNameLength", account.getFirstNameLength());
-                    Currency currency = account.getCurrency();
+                    final Currency currency = account.getCurrency();
                     q.bind("currency", (currency == null) ? null : currency.toString());
                     q.bind("billingCycleDay", account.getBillCycleDay());
-                    q.bind("paymentMethodId", account.getPaymentMethodId() !=  null ? account.getPaymentMethodId().toString() : null);
-                    DateTimeZone timeZone = account.getTimeZone();
+                    q.bind("paymentMethodId", account.getPaymentMethodId() != null ? account.getPaymentMethodId().toString() : null);
+                    final DateTimeZone timeZone = account.getTimeZone();
                     q.bind("timeZone", (timeZone == null) ? null : timeZone.toString());
                     q.bind("locale", account.getLocale());
                     q.bind("address1", account.getAddress1());
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountMapper.java b/account/src/main/java/com/ning/billing/account/dao/AccountMapper.java
index 86c29a6..f443993 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountMapper.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountMapper.java
@@ -16,53 +16,54 @@
 
 package com.ning.billing.account.dao;
 
-import com.ning.billing.account.api.Account;
-import com.ning.billing.account.api.DefaultAccount;
-import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.dao.MapperBase;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
 import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.UUID;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.DefaultAccount;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.dao.MapperBase;
 
 public class AccountMapper extends MapperBase implements ResultSetMapper<Account> {
     @Override
-    public Account map(int index, ResultSet result, StatementContext context) throws SQLException {
-        UUID id = UUID.fromString(result.getString("id"));
-        String externalKey = result.getString("external_key");
-        String email = result.getString("email");
-        String name = result.getString("name");
-        int firstNameLength = result.getInt("first_name_length");
-        int billingCycleDay = result.getInt("billing_cycle_day");
+    public Account map(final int index, final ResultSet result, final StatementContext context) throws SQLException {
+        final UUID id = UUID.fromString(result.getString("id"));
+        final String externalKey = result.getString("external_key");
+        final String email = result.getString("email");
+        final String name = result.getString("name");
+        final int firstNameLength = result.getInt("first_name_length");
+        final int billingCycleDay = result.getInt("billing_cycle_day");
 
-        String currencyString = result.getString("currency");
-        Currency currency = (currencyString == null) ? null : Currency.valueOf(currencyString);
+        final String currencyString = result.getString("currency");
+        final Currency currency = (currencyString == null) ? null : Currency.valueOf(currencyString);
 
-        UUID paymentMethodId = result.getString("payment_method_id") != null ? UUID.fromString(result.getString("payment_method_id")) : null;
+        final UUID paymentMethodId = result.getString("payment_method_id") != null ? UUID.fromString(result.getString("payment_method_id")) : null;
 
-        String timeZoneId = result.getString("time_zone");
-        DateTimeZone timeZone = (timeZoneId == null) ? null : DateTimeZone.forID(timeZoneId);
+        final String timeZoneId = result.getString("time_zone");
+        final DateTimeZone timeZone = (timeZoneId == null) ? null : DateTimeZone.forID(timeZoneId);
 
-        String locale = result.getString("locale");
+        final String locale = result.getString("locale");
 
-        String address1 = result.getString("address1");
-        String address2 = result.getString("address2");
-        String companyName = result.getString("company_name");
-        String city = result.getString("city");
-        String stateOrProvince = result.getString("state_or_province");
-        String postalCode = result.getString("postal_code");
-        String country = result.getString("country");
-        String phone = result.getString("phone");
+        final String address1 = result.getString("address1");
+        final String address2 = result.getString("address2");
+        final String companyName = result.getString("company_name");
+        final String city = result.getString("city");
+        final String stateOrProvince = result.getString("state_or_province");
+        final String postalCode = result.getString("postal_code");
+        final String country = result.getString("country");
+        final String phone = result.getString("phone");
 
-        Boolean isMigrated = result.getBoolean("migrated");
-        Boolean isNotifiedForInvoices = result.getBoolean("is_notified_for_invoices");
+        final Boolean isMigrated = result.getBoolean("migrated");
+        final Boolean isNotifiedForInvoices = result.getBoolean("is_notified_for_invoices");
 
-        return new DefaultAccount(id, externalKey, email, name,firstNameLength, currency,
-                billingCycleDay, paymentMethodId, timeZone, locale,
-                address1, address2, companyName, city, stateOrProvince, country, postalCode, phone,
-                isMigrated, isNotifiedForInvoices);
+        return new DefaultAccount(id, externalKey, email, name, firstNameLength, currency,
+                                  billingCycleDay, paymentMethodId, timeZone, locale,
+                                  address1, address2, companyName, city, stateOrProvince, country, postalCode, phone,
+                                  isMigrated, isNotifiedForInvoices);
     }
-}
\ No newline at end of file
+}
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
index 8ed05ee..01b344a 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
@@ -18,15 +18,6 @@ package com.ning.billing.account.dao;
 
 import java.util.UUID;
 
-import com.ning.billing.account.api.Account;
-import com.ning.billing.util.ChangeType;
-import com.ning.billing.util.dao.AuditSqlDao;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
-import com.ning.billing.util.dao.ChangeTypeBinder;
-import com.ning.billing.util.dao.EntityHistory;
-import com.ning.billing.util.dao.UuidMapper;
-import com.ning.billing.util.entity.dao.UpdatableEntitySqlDao;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@@ -35,6 +26,13 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 
+import com.ning.billing.account.api.Account;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.dao.EntityHistory;
+import com.ning.billing.util.dao.UuidMapper;
+import com.ning.billing.util.entity.dao.UpdatableEntitySqlDao;
+
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper({UuidMapper.class, AccountMapper.class})
 public interface AccountSqlDao extends UpdatableEntitySqlDao<Account>, Transactional<AccountSqlDao>, Transmogrifier {
@@ -55,5 +53,5 @@ public interface AccountSqlDao extends UpdatableEntitySqlDao<Account>, Transacti
     @Override
     @SqlUpdate
     public void insertHistoryFromTransaction(@AccountHistoryBinder final EntityHistory<Account> account,
-                                            @CallContextBinder final CallContext context);
+                                             @CallContextBinder final CallContext context);
 }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java
index ae4d623..8e162f7 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java
@@ -34,9 +34,9 @@ import com.ning.billing.account.api.AccountChangeEvent;
 import com.ning.billing.account.api.AccountCreationEvent;
 import com.ning.billing.account.api.user.DefaultAccountChangeEvent;
 import com.ning.billing.account.api.user.DefaultAccountCreationEvent;
+import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
-import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.dao.EntityAudit;
 import com.ning.billing.util.dao.EntityHistory;
@@ -44,13 +44,13 @@ import com.ning.billing.util.dao.TableName;
 import com.ning.billing.util.entity.EntityPersistenceException;
 
 public class AuditedAccountDao implements AccountDao {
-    private final static Logger log = LoggerFactory.getLogger(AuditedAccountDao.class);
-    
+    private static final Logger log = LoggerFactory.getLogger(AuditedAccountDao.class);
+
     private final AccountSqlDao accountSqlDao;
     private final Bus eventBus;
 
     @Inject
-    public AuditedAccountDao(IDBI dbi, Bus eventBus) {
+    public AuditedAccountDao(final IDBI dbi, final Bus eventBus) {
         this.eventBus = eventBus;
         this.accountSqlDao = dbi.onDemand(AccountSqlDao.class);
     }
@@ -85,23 +85,24 @@ public class AuditedAccountDao implements AccountDao {
             accountSqlDao.inTransaction(new Transaction<Void, AccountSqlDao>() {
                 @Override
                 public Void inTransaction(final AccountSqlDao transactionalDao, final TransactionStatus status) throws AccountApiException, Bus.EventBusException {
-                    Account currentAccount = transactionalDao.getAccountByKey(key);
+                    final Account currentAccount = transactionalDao.getAccountByKey(key);
                     if (currentAccount != null) {
                         throw new AccountApiException(ErrorCode.ACCOUNT_ALREADY_EXISTS, key);
                     }
+
                     transactionalDao.create(account, context);
 
-                    // insert history
-                    Long recordId = accountSqlDao.getRecordId(account.getId().toString());
-                    EntityHistory<Account> history = new EntityHistory<Account>(account.getId(), recordId, account, ChangeType.INSERT);
+                    // Insert history
+                    final Long recordId = accountSqlDao.getRecordId(account.getId().toString());
+                    final EntityHistory<Account> history = new EntityHistory<Account>(account.getId(), recordId, account, ChangeType.INSERT);
                     accountSqlDao.insertHistoryFromTransaction(history, context);
 
-                    // insert audit
-                    Long historyRecordId = accountSqlDao.getHistoryRecordId(recordId);
-                    EntityAudit audit = new EntityAudit(TableName.ACCOUNT_HISTORY, historyRecordId, ChangeType.INSERT);
+                    // Insert audit
+                    final Long historyRecordId = accountSqlDao.getHistoryRecordId(recordId);
+                    final EntityAudit audit = new EntityAudit(TableName.ACCOUNT_HISTORY, historyRecordId, ChangeType.INSERT);
                     accountSqlDao.insertAuditFromTransaction(audit, context);
 
-                    AccountCreationEvent creationEvent = new DefaultAccountCreationEvent(account, context.getUserToken());
+                    final AccountCreationEvent creationEvent = new DefaultAccountCreationEvent(account, context.getUserToken());
                     try {
                         eventBus.postFromTransaction(creationEvent, transactionalDao);
                     } catch (EventBusException e) {
@@ -122,38 +123,36 @@ public class AuditedAccountDao implements AccountDao {
     }
 
     @Override
-    public void update(final Account account, final CallContext context) throws EntityPersistenceException {
+    public void update(final Account specifiedAccount, final CallContext context) throws EntityPersistenceException {
         try {
             accountSqlDao.inTransaction(new Transaction<Void, AccountSqlDao>() {
                 @Override
                 public Void inTransaction(final AccountSqlDao transactional, final TransactionStatus status) throws EntityPersistenceException, Bus.EventBusException {
-                    String accountId = account.getId().toString();
-                    Account currentAccount = transactional.getById(accountId);
+                    final UUID accountId = specifiedAccount.getId();
+                    final Account currentAccount = transactional.getById(accountId.toString());
                     if (currentAccount == null) {
                         throw new EntityPersistenceException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID, accountId);
                     }
 
-                    String currentKey = currentAccount.getExternalKey();
-                    if (!currentKey.equals(account.getExternalKey())) {
-                        throw new EntityPersistenceException(ErrorCode.ACCOUNT_CANNOT_CHANGE_EXTERNAL_KEY, currentKey);
-                    }
+                    // Set unspecified (null) fields to their current values
+                    final Account account = specifiedAccount.mergeWithDelegate(currentAccount);
 
                     transactional.update(account, context);
 
-                    Long recordId = accountSqlDao.getRecordId(account.getId().toString());
-                    EntityHistory<Account> history = new EntityHistory<Account>(account.getId(), recordId, account, ChangeType.INSERT);
+                    final Long recordId = accountSqlDao.getRecordId(accountId.toString());
+                    final EntityHistory<Account> history = new EntityHistory<Account>(accountId, recordId, account, ChangeType.INSERT);
                     accountSqlDao.insertHistoryFromTransaction(history, context);
 
-                    Long historyRecordId = accountSqlDao.getHistoryRecordId(recordId);
-                    EntityAudit audit = new EntityAudit(TableName.ACCOUNT_HISTORY, historyRecordId, ChangeType.INSERT);
+                    final Long historyRecordId = accountSqlDao.getHistoryRecordId(recordId);
+                    final EntityAudit audit = new EntityAudit(TableName.ACCOUNT_HISTORY, historyRecordId, ChangeType.INSERT);
                     accountSqlDao.insertAuditFromTransaction(audit, context);
 
-                    AccountChangeEvent changeEvent = new DefaultAccountChangeEvent(account.getId(), context.getUserToken(), currentAccount, account);
+                    final AccountChangeEvent changeEvent = new DefaultAccountChangeEvent(accountId, context.getUserToken(), currentAccount, account);
                     if (changeEvent.hasChanges()) {
                         try {
                             eventBus.postFromTransaction(changeEvent, transactional);
                         } catch (EventBusException e) {
-                            log.warn("Failed to post account change event for account " + account.getId(), e);
+                            log.warn("Failed to post account change event for account " + accountId, e);
                         }
                     }
                     return null;
diff --git a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java
index 664d9cc..f5f50ed 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java
@@ -17,12 +17,17 @@
 package com.ning.billing.account.dao;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import org.skife.jdbi.v2.IDBI;
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 import com.ning.billing.account.api.AccountEmail;
 import com.ning.billing.util.callcontext.CallContext;
@@ -35,12 +40,12 @@ public class AuditedAccountEmailDao extends AuditedCollectionDaoBase<AccountEmai
     private final AccountEmailSqlDao accountEmailSqlDao;
 
     @Inject
-    public AuditedAccountEmailDao(IDBI dbi) {
+    public AuditedAccountEmailDao(final IDBI dbi) {
         this.accountEmailSqlDao = dbi.onDemand(AccountEmailSqlDao.class);
     }
 
     @Override
-    protected AccountEmail getEquivalenceObjectFor(AccountEmail obj) {
+    protected AccountEmail getEquivalenceObjectFor(final AccountEmail obj) {
         return obj;
     }
 
@@ -55,7 +60,51 @@ public class AuditedAccountEmailDao extends AuditedCollectionDaoBase<AccountEmai
     }
 
     @Override
-    public String getKey(AccountEmail entity) {
+    public void addEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+        accountEmailSqlDao.inTransaction(new Transaction<Object, AccountEmailSqlDao>() {
+            @Override
+            public Object inTransaction(final AccountEmailSqlDao transactional, final TransactionStatus status) throws Exception {
+                // Compute the final list of emails by looking up the current ones and adding the new one
+                // We can use a simple set here as the supplied email may not have its id field populated
+                final List<AccountEmail> currentEmails = accountEmailSqlDao.load(accountId.toString(), ObjectType.ACCOUNT_EMAIL);
+                final Map<String, AccountEmail> newEmails = new HashMap<String, AccountEmail>();
+                for (final AccountEmail currentEmail : currentEmails) {
+                    newEmails.put(currentEmail.getEmail(), currentEmail);
+                }
+                newEmails.put(email.getEmail(), email);
+
+                saveEntitiesFromTransaction(getSqlDao(), accountId, ObjectType.ACCOUNT_EMAIL,
+                                            ImmutableList.<AccountEmail>copyOf(newEmails.values()), context);
+
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public void removeEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+        accountEmailSqlDao.inTransaction(new Transaction<Object, AccountEmailSqlDao>() {
+            @Override
+            public Object inTransaction(final AccountEmailSqlDao transactional, final TransactionStatus status) throws Exception {
+                // Compute the final list of emails by looking up the current ones and removing the new one
+                // We can use a simple set here as the supplied email may not have its id field populated
+                final List<AccountEmail> currentEmails = accountEmailSqlDao.load(accountId.toString(), ObjectType.ACCOUNT_EMAIL);
+                final Map<String, AccountEmail> newEmails = new HashMap<String, AccountEmail>();
+                for (final AccountEmail currentEmail : currentEmails) {
+                    newEmails.put(currentEmail.getEmail(), currentEmail);
+                }
+                newEmails.remove(email.getEmail());
+
+                saveEntitiesFromTransaction(getSqlDao(), accountId, ObjectType.ACCOUNT_EMAIL,
+                                            ImmutableList.<AccountEmail>copyOf(newEmails.values()), context);
+
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public String getKey(final AccountEmail entity) {
         return entity.getEmail();
     }
 
@@ -64,79 +113,13 @@ public class AuditedAccountEmailDao extends AuditedCollectionDaoBase<AccountEmai
         accountEmailSqlDao.test();
     }
 
-//    @Override
-//    public List<AccountEmail> getEmails(final UUID accountId) {
-//        return accountEmailSqlDao.load(accountId.toString(), null);
-//        //return accountEmailSqlDao.getByAccountId(accountId.toString());
-//    }
-
-//    @Override
-//    public void saveEmails(final UUID accountId, final List<AccountEmail> emails, final CallContext context) {
-//        final List<AccountEmail> existingEmails = accountEmailSqlDao.getByAccountId(accountId.toString());
-//        final List<AccountEmail> updatedEmails = new ArrayList<AccountEmail>();
-//
-//        Iterator<AccountEmail> existingEmailIterator = existingEmails.iterator();
-//        while (existingEmailIterator.hasNext()) {
-//            AccountEmail existingEmail = existingEmailIterator.next();
-//
-//            Iterator<AccountEmail> newEmailIterator = emails.iterator();
-//            while (newEmailIterator.hasNext()) {
-//                AccountEmail newEmail = newEmailIterator.next();
-//                if (newEmail.getId().equals(existingEmail.getId())) {
-//                    // check equality; if not equal, add to updated
-//                    if (!newEmail.equals(existingEmail)) {
-//                        updatedEmails.add(newEmail);
-//                    }
-//
-//                    // remove from both
-//                    newEmailIterator.remove();
-//                    existingEmailIterator.remove();
-//                }
-//            }
-//        }
-//
-//        // remaining emails in newEmail are inserts; remaining emails in existingEmail are deletes
-//        accountEmailSqlDao.inTransaction(new Transaction<Void, AccountEmailSqlDao>() {
-//            @Override
-//            public Void inTransaction(AccountEmailSqlDao dao, TransactionStatus transactionStatus) throws Exception {
-//                dao.create(emails, context);
-//                dao.update(updatedEmails, context);
-//                dao.delete(existingEmails, context);
-//
-//                List<String> insertHistoryIdList = getIdList(emails.size());
-//                List<String> updateHistoryIdList = getIdList(updatedEmails.size());
-//                List<String> deleteHistoryIdList = getIdList(existingEmails.size());
-//
-//                // insert histories
-//                dao.insertAccountEmailHistoryFromTransaction(insertHistoryIdList, emails, ChangeType.INSERT, context);
-//                dao.insertAccountEmailHistoryFromTransaction(updateHistoryIdList, updatedEmails, ChangeType.UPDATE, context);
-//                dao.insertAccountEmailHistoryFromTransaction(deleteHistoryIdList, existingEmails, ChangeType.DELETE, context);
-//
-//                // insert audits
-//                auditSqlDao.insertAuditFromTransaction(TableName.ACCOUNT_EMAIL_HISTORY, insertHistoryIdList, ChangeType.INSERT, context);
-//                auditSqlDao.insertAuditFromTransaction(TableName.ACCOUNT_EMAIL_HISTORY, updateHistoryIdList, ChangeType.UPDATE, context);
-//                auditSqlDao.insertAuditFromTransaction(TableName.ACCOUNT_EMAIL_HISTORY, deleteHistoryIdList, ChangeType.DELETE, context);
-//
-//                return null;
-//            }
-//        });
-//    }
-//
-//    private List<String> getIdList(int size) {
-//        List<String> results = new ArrayList<String>();
-//        for (int i = 0; i < size; i++) {
-//            results.add(UUID.randomUUID().toString());
-//        }
-//        return results;
-//    }
-
     @Override
     protected TableName getTableName() {
         return TableName.ACCOUNT_EMAIL_HISTORY;
     }
 
     @Override
-    protected UpdatableEntityCollectionSqlDao<AccountEmail> transmogrifyDao(Transmogrifier transactionalDao) {
+    protected UpdatableEntityCollectionSqlDao<AccountEmail> transmogrifyDao(final Transmogrifier transactionalDao) {
         return transactionalDao.become(AccountEmailSqlDao.class);
     }
 
diff --git a/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg b/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
index e56bf58..dd7b8da 100644
--- a/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
+++ b/account/src/main/resources/com/ning/billing/account/dao/AccountSqlDao.sql.stg
@@ -39,7 +39,7 @@ create() ::= <<
 
 update() ::= <<
     UPDATE accounts
-    SET external_key = :externalKey, email = :email, name = :name, first_name_length = :firstNameLength,
+    SET email = :email, name = :name, first_name_length = :firstNameLength,
         currency = :currency, billing_cycle_day = :billingCycleDay, payment_method_id = :paymentMethodId,
         time_zone = :timeZone, locale = :locale,
         address1 = :address1, address2 = :address2, company_name = :companyName, city = :city, state_or_province = :stateOrProvince,
@@ -138,4 +138,4 @@ insertAuditFromTransaction() ::= <<
 test() ::= <<
     SELECT 1 FROM accounts;
 >>
-;
\ No newline at end of file
+;
diff --git a/account/src/main/resources/com/ning/billing/account/ddl.sql b/account/src/main/resources/com/ning/billing/account/ddl.sql
index 2cf54d1..7ba749e 100644
--- a/account/src/main/resources/com/ning/billing/account/ddl.sql
+++ b/account/src/main/resources/com/ning/billing/account/ddl.sql
@@ -75,7 +75,6 @@ CREATE TABLE account_emails (
     PRIMARY KEY(record_id)
 ) ENGINE=innodb;
 CREATE UNIQUE INDEX account_email_id ON account_emails(id);
-CREATE INDEX account_email_account_id ON account_emails(account_id);
 CREATE UNIQUE INDEX account_email_account_id_email ON account_emails(account_id, email);
 
 DROP TABLE IF EXISTS account_email_history;
diff --git a/account/src/test/java/com/ning/billing/account/api/user/TestDefaultAccountUserApi.java b/account/src/test/java/com/ning/billing/account/api/user/TestDefaultAccountUserApi.java
index e3e2f84..5d4657b 100644
--- a/account/src/test/java/com/ning/billing/account/api/user/TestDefaultAccountUserApi.java
+++ b/account/src/test/java/com/ning/billing/account/api/user/TestDefaultAccountUserApi.java
@@ -27,9 +27,11 @@ import org.testng.annotations.Test;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountData;
 import com.ning.billing.account.api.DefaultAccount;
+import com.ning.billing.account.api.DefaultAccountEmail;
 import com.ning.billing.account.dao.AccountDao;
 import com.ning.billing.account.dao.AccountEmailDao;
 import com.ning.billing.account.dao.MockAccountDao;
+import com.ning.billing.account.dao.MockAccountEmailDao;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.callcontext.CallContext;
@@ -38,14 +40,15 @@ import com.ning.billing.util.callcontext.CallContextFactory;
 public class TestDefaultAccountUserApi {
     private final CallContextFactory factory = Mockito.mock(CallContextFactory.class);
     private final CallContext callContext = Mockito.mock(CallContext.class);
-    private final AccountEmailDao accountEmailDao = Mockito.mock(AccountEmailDao.class);
 
     private AccountDao accountDao;
+    private AccountEmailDao accountEmailDao;
     private DefaultAccountUserApi accountUserApi;
 
     @BeforeMethod(groups = "fast")
     public void setUp() throws Exception {
         accountDao = new MockAccountDao(Mockito.mock(Bus.class));
+        accountEmailDao = new MockAccountEmailDao();
         accountUserApi = new DefaultAccountUserApi(factory, accountDao, accountEmailDao);
     }
 
@@ -55,9 +58,9 @@ public class TestDefaultAccountUserApi {
         final String externalKey = UUID.randomUUID().toString();
         final String email = UUID.randomUUID().toString();
         final String name = UUID.randomUUID().toString();
-        final int firstNameLength = Integer.MAX_VALUE;
+        final Integer firstNameLength = Integer.MAX_VALUE;
         final Currency currency = Currency.BRL;
-        final int billCycleDay = Integer.MIN_VALUE;
+        final Integer billCycleDay = Integer.MIN_VALUE;
         final UUID paymentMethodId = UUID.randomUUID();
         final DateTimeZone timeZone = DateTimeZone.UTC;
         final String locale = UUID.randomUUID().toString();
@@ -69,8 +72,8 @@ public class TestDefaultAccountUserApi {
         final String country = UUID.randomUUID().toString();
         final String postalCode = UUID.randomUUID().toString();
         final String phone = UUID.randomUUID().toString();
-        final boolean isMigrated = true;
-        final boolean isNotifiedForInvoices = false;
+        final Boolean isMigrated = true;
+        final Boolean isNotifiedForInvoices = false;
         final AccountData data = new DefaultAccount(id, externalKey, email, name, firstNameLength, currency, billCycleDay,
                                                     paymentMethodId, timeZone, locale, address1, address2, companyName,
                                                     city, stateOrProvince, country, postalCode, phone, isMigrated, isNotifiedForInvoices);
@@ -98,4 +101,26 @@ public class TestDefaultAccountUserApi {
         Assert.assertEquals(account.isMigrated(), isMigrated);
         Assert.assertEquals(account.isNotifiedForInvoices(), isNotifiedForInvoices);
     }
+
+    @Test(groups = "fast")
+    public void testAddEmail() throws Exception {
+        final UUID accountId = UUID.randomUUID();
+
+        // Verify the initial state
+        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 0);
+
+        // Add the first email
+        final String email1 = UUID.randomUUID().toString();
+        accountUserApi.addEmail(accountId, new DefaultAccountEmail(accountId, email1), callContext);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 1);
+
+        // Add a second one
+        final String email2 = UUID.randomUUID().toString();
+        accountUserApi.addEmail(accountId, new DefaultAccountEmail(accountId, email2), callContext);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 2);
+
+        // Remove the first second one
+        accountUserApi.removeEmail(accountId, new DefaultAccountEmail(accountId, email1), callContext);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 1);
+    }
 }
diff --git a/account/src/test/java/com/ning/billing/account/api/user/TestEventJson.java b/account/src/test/java/com/ning/billing/account/api/user/TestEventJson.java
index a32fbc2..8853ad6 100644
--- a/account/src/test/java/com/ning/billing/account/api/user/TestEventJson.java
+++ b/account/src/test/java/com/ning/billing/account/api/user/TestEventJson.java
@@ -19,7 +19,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.jackson.ObjectMapper;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -27,36 +26,37 @@ import com.ning.billing.account.api.AccountChangeEvent;
 import com.ning.billing.account.api.ChangedField;
 import com.ning.billing.account.api.DefaultChangedField;
 import com.ning.billing.account.api.user.DefaultAccountCreationEvent.DefaultAccountData;
+import com.ning.billing.util.jackson.ObjectMapper;
 
 public class TestEventJson {
     private final ObjectMapper mapper = new ObjectMapper();
 
-    @Test(groups= {"fast"})
+    @Test(groups = {"fast"})
     public void testDefaultAccountChangeEvent() throws Exception {
 
-        List<ChangedField> changes = new ArrayList<ChangedField>();
+        final List<ChangedField> changes = new ArrayList<ChangedField>();
         changes.add(new DefaultChangedField("fieldXX", "valueX", "valueXXX"));
-        changes.add(new DefaultChangedField("fieldYY", "valueY", "valueYYY"));        
-        AccountChangeEvent e = new DefaultAccountChangeEvent(UUID.randomUUID(), changes, UUID.randomUUID());
-        
-        String json = mapper.writeValueAsString(e);
-        
-        Class<?> claz = Class.forName("com.ning.billing.account.api.user.DefaultAccountChangeEvent");
-        Object obj =  mapper.readValue(json, claz);
+        changes.add(new DefaultChangedField("fieldYY", "valueY", "valueYYY"));
+        final AccountChangeEvent e = new DefaultAccountChangeEvent(UUID.randomUUID(), changes, UUID.randomUUID());
+
+        final String json = mapper.writeValueAsString(e);
+
+        final Class<?> claz = Class.forName("com.ning.billing.account.api.user.DefaultAccountChangeEvent");
+        final Object obj = mapper.readValue(json, claz);
         Assert.assertTrue(obj.equals(e));
     }
-    
-    @Test(groups= {"fast"})
+
+    @Test(groups = {"fast"})
     public void testAccountCreationEvent() throws Exception {
-        
-        DefaultAccountData data = new DefaultAccountData("dsfdsf", "bobo", 3, "bobo@yahoo.com", 12, "USD", UUID.randomUUID(), 
-                "UTC", "US", "21 avenue", "", "Gling", "San Franciso", "CA", "94110", "USA", "4126789887", false, false);
-        DefaultAccountCreationEvent e = new DefaultAccountCreationEvent(data, UUID.randomUUID(), UUID.randomUUID());
-        
-        String json = mapper.writeValueAsString(e);
-        Class<?> claz = Class.forName(DefaultAccountCreationEvent.class.getName());
-        Object obj =  mapper.readValue(json, claz);
+
+        final DefaultAccountData data = new DefaultAccountData("dsfdsf", "bobo", 3, "bobo@yahoo.com", 12, "USD", UUID.randomUUID(),
+                                                         "UTC", "US", "21 avenue", "", "Gling", "San Franciso", "CA", "94110", "USA", "4126789887", false, false);
+        final DefaultAccountCreationEvent e = new DefaultAccountCreationEvent(data, UUID.randomUUID(), UUID.randomUUID());
+
+        final String json = mapper.writeValueAsString(e);
+        final Class<?> claz = Class.forName(DefaultAccountCreationEvent.class.getName());
+        final Object obj = mapper.readValue(json, claz);
         Assert.assertTrue(obj.equals(e));
-        
+
     }
 }
diff --git a/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java b/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
index a97a630..0635c4e 100644
--- a/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
+++ b/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
@@ -16,11 +16,8 @@
 
 package com.ning.billing.account.dao;
 
-import static org.testng.Assert.fail;
-
 import java.io.IOException;
 
-import org.apache.commons.io.IOUtils;
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.TransactionCallback;
@@ -30,18 +27,21 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 
 import com.ning.billing.dbi.MysqlTestingHelper;
-import com.ning.billing.util.bus.DefaultBusService;
-import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.BusService;
+import com.ning.billing.util.bus.DefaultBusService;
 import com.ning.billing.util.bus.InMemoryBus;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.tag.api.user.TagEventBuilder;
 
+import static org.testng.Assert.fail;
+
 public abstract class AccountDaoTestBase {
     private final MysqlTestingHelper helper = new MysqlTestingHelper();
 
@@ -67,7 +67,7 @@ public abstract class AccountDaoTestBase {
             dbi = helper.getDBI();
 
             bus = new InMemoryBus();
-            BusService busService = new DefaultBusService(bus);
+            final BusService busService = new DefaultBusService(bus);
             ((DefaultBusService) busService).startBus();
 
             accountDao = new AuditedAccountDao(dbi, bus);
@@ -76,17 +76,15 @@ public abstract class AccountDaoTestBase {
             accountEmailDao = new AuditedAccountEmailDao(dbi);
             accountEmailDao.test();
 
-            Clock clock = new ClockMock();
+            final Clock clock = new ClockMock();
             context = new DefaultCallContextFactory(clock).createCallContext("Account Dao Tests", CallOrigin.TEST, UserType.TEST);
-        }
-        catch (Throwable t) {
+        } catch (Throwable t) {
             fail(t.toString());
         }
     }
 
     @AfterClass(alwaysRun = true)
-    public void stopMysql()
-    {
+    public void stopMysql() {
         helper.stopMysql();
     }
 
@@ -94,11 +92,11 @@ public abstract class AccountDaoTestBase {
     public void cleanupData() {
         dbi.inTransaction(new TransactionCallback<Void>() {
             @Override
-            public Void inTransaction(Handle h, TransactionStatus status) throws Exception {
+            public Void inTransaction(final Handle h, final TransactionStatus status) throws Exception {
                 h.execute("truncate table accounts");
                 h.execute("truncate table notifications");
                 h.execute("truncate table bus_events");
-                h.execute("truncate table claimed_bus_events");                              
+                h.execute("truncate table claimed_bus_events");
                 h.execute("truncate table claimed_notifications");
                 h.execute("truncate table tag_definitions");
                 h.execute("truncate table tags");
diff --git a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
index d8348af..535dbbc 100644
--- a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
@@ -27,33 +27,32 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountChangeEvent;
 import com.ning.billing.account.api.user.DefaultAccountChangeEvent;
 import com.ning.billing.account.api.user.DefaultAccountCreationEvent;
-import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.Bus.EventBusException;
+import com.ning.billing.util.callcontext.CallContext;
 
 public class MockAccountDao implements AccountDao {
     private final Bus eventBus;
     private final Map<UUID, Account> accounts = new ConcurrentHashMap<UUID, Account>();
 
     @Inject
-    public MockAccountDao(Bus eventBus) {
+    public MockAccountDao(final Bus eventBus) {
         this.eventBus = eventBus;
     }
 
     @Override
-    public void create(Account account, CallContext context) {
+    public void create(final Account account, final CallContext context) {
         accounts.put(account.getId(), account);
 
         try {
             eventBus.post(new DefaultAccountCreationEvent(account, null));
-        }
-        catch (EventBusException ex) {
+        } catch (EventBusException ex) {
             throw new RuntimeException(ex);
         }
     }
 
     @Override
-    public Account getById(UUID id) {
+    public Account getById(final UUID id) {
         return accounts.get(id);
     }
 
@@ -67,8 +66,8 @@ public class MockAccountDao implements AccountDao {
     }
 
     @Override
-    public Account getAccountByKey(String externalKey) {
-        for (Account account : accounts.values()) {
+    public Account getAccountByKey(final String externalKey) {
+        for (final Account account : accounts.values()) {
             if (externalKey.equals(account.getExternalKey())) {
                 return account;
             }
@@ -77,21 +76,20 @@ public class MockAccountDao implements AccountDao {
     }
 
     @Override
-    public UUID getIdFromKey(String externalKey) {
-        Account account = getAccountByKey(externalKey);
+    public UUID getIdFromKey(final String externalKey) {
+        final Account account = getAccountByKey(externalKey);
         return account == null ? null : account.getId();
     }
 
     @Override
-    public void update(Account account, CallContext context) {
-        Account currentAccount = accounts.put(account.getId(), account);
+    public void update(final Account account, final CallContext context) {
+        final Account currentAccount = accounts.put(account.getId(), account);
 
-        AccountChangeEvent changeEvent = new DefaultAccountChangeEvent(account.getId(), null, currentAccount, account);
+        final AccountChangeEvent changeEvent = new DefaultAccountChangeEvent(account.getId(), null, currentAccount, account);
         if (changeEvent.hasChanges()) {
             try {
                 eventBus.post(changeEvent);
-            }
-            catch (EventBusException ex) {
+            } catch (EventBusException ex) {
                 throw new RuntimeException(ex);
             }
         }
diff --git a/account/src/test/java/com/ning/billing/account/dao/MockAccountEmailDao.java b/account/src/test/java/com/ning/billing/account/dao/MockAccountEmailDao.java
new file mode 100644
index 0000000..933ca54
--- /dev/null
+++ b/account/src/test/java/com/ning/billing/account/dao/MockAccountEmailDao.java
@@ -0,0 +1,73 @@
+/*
+ * 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.account.dao;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.google.common.collect.ImmutableList;
+import com.ning.billing.account.api.AccountEmail;
+import com.ning.billing.util.callcontext.CallContext;
+
+public class MockAccountEmailDao implements AccountEmailDao {
+    private final Map<UUID, Set<AccountEmail>> emails = new ConcurrentHashMap<UUID, Set<AccountEmail>>();
+
+    @Override
+    public List<AccountEmail> getEmails(final UUID accountId) {
+        final Set<AccountEmail> accountEmails = emails.get(accountId);
+        if (accountEmails == null) {
+            return ImmutableList.<AccountEmail>of();
+        } else {
+            return ImmutableList.<AccountEmail>copyOf(accountEmails.iterator());
+        }
+    }
+
+    @Override
+    public void saveEmails(final UUID accountId, final List<AccountEmail> newEmails, final CallContext context) {
+        if (emails.get(accountId) == null) {
+            emails.put(accountId, new HashSet<AccountEmail>());
+        }
+
+        emails.get(accountId).addAll(newEmails);
+    }
+
+    @Override
+    public void addEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+        if (emails.get(accountId) == null) {
+            emails.put(accountId, new HashSet<AccountEmail>());
+        }
+
+        emails.get(accountId).add(email);
+    }
+
+    @Override
+    public void removeEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+        if (emails.get(accountId) == null) {
+            emails.put(accountId, new HashSet<AccountEmail>());
+        }
+
+        emails.get(accountId).remove(email);
+    }
+
+    @Override
+    public void test() {
+    }
+}
diff --git a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
index 5e51ecd..b3105c3 100644
--- a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
@@ -16,68 +16,69 @@
 
 package com.ning.billing.account.dao;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-import com.ning.billing.account.api.AccountEmail;
-import com.ning.billing.account.api.DefaultAccountEmail;
-import com.ning.billing.util.api.TagApiException;
-import com.ning.billing.util.customfield.CustomField;
-import com.ning.billing.util.customfield.StringCustomField;
-import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
-import com.ning.billing.util.customfield.dao.CustomFieldDao;
-import com.ning.billing.util.dao.ObjectType;
-import com.ning.billing.util.entity.EntityPersistenceException;
-import com.ning.billing.util.tag.dao.AuditedTagDao;
-import com.ning.billing.util.tag.dao.TagDao;
 import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.Handle;
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountData;
+import com.ning.billing.account.api.AccountEmail;
 import com.ning.billing.account.api.DefaultAccount;
+import com.ning.billing.account.api.DefaultAccountEmail;
 import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.api.TagApiException;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.customfield.StringCustomField;
+import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
+import com.ning.billing.util.customfield.dao.CustomFieldDao;
+import com.ning.billing.util.dao.ObjectType;
+import com.ning.billing.util.entity.EntityPersistenceException;
 import com.ning.billing.util.tag.DefaultTagDefinition;
 import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.TagDefinition;
+import com.ning.billing.util.tag.dao.AuditedTagDao;
+import com.ning.billing.util.tag.dao.TagDao;
 import com.ning.billing.util.tag.dao.TagDefinitionSqlDao;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
 @Test(groups = {"slow", "account-dao"})
 public class TestAccountDao extends AccountDaoTestBase {
-    private Account createTestAccount(int billCycleDay) {
+    private Account createTestAccount(final int billCycleDay) {
         return createTestAccount(billCycleDay, "123-456-7890");
     }
 
-    private Account createTestAccount(int billCycleDay, String phone) {
-        String thisKey = "test" + UUID.randomUUID().toString();
-        String lastName = UUID.randomUUID().toString();
-        String thisEmail = "me@me.com" + " " + UUID.randomUUID();
-        String firstName = "Bob";
-        String name = firstName + " " + lastName;
-        String locale = "EN-US";
-        DateTimeZone timeZone = DateTimeZone.forID("America/Los_Angeles");
-        int firstNameLength = firstName.length();
+    private Account createTestAccount(final int billCycleDay, final String phone) {
+        final String thisKey = "test" + UUID.randomUUID().toString();
+        final String lastName = UUID.randomUUID().toString();
+        final String thisEmail = "me@me.com" + " " + UUID.randomUUID();
+        final String firstName = "Bob";
+        final String name = firstName + " " + lastName;
+        final String locale = "EN-US";
+        final DateTimeZone timeZone = DateTimeZone.forID("America/Los_Angeles");
+        final int firstNameLength = firstName.length();
 
         return new DefaultAccount(UUID.randomUUID(), thisKey, thisEmail, name, firstNameLength, Currency.USD,
-                billCycleDay, UUID.randomUUID(), timeZone, locale,
-                null, null, null, null, null, null, null, // add null address fields
-                phone, false, false);
+                                  billCycleDay, UUID.randomUUID(), timeZone, locale,
+                                  null, null, null, null, null, null, null, // add null address fields
+                                  phone, false, false);
     }
 
     @Test
     public void testBasic() throws EntityPersistenceException {
-        Account a = createTestAccount(5);
+        final Account a = createTestAccount(5);
         accountDao.create(a, context);
-        String key = a.getExternalKey();
+        final String key = a.getExternalKey();
 
         Account r = accountDao.getAccountByKey(key);
         assertNotNull(r);
@@ -87,7 +88,7 @@ public class TestAccountDao extends AccountDaoTestBase {
         assertNotNull(r);
         assertEquals(r.getExternalKey(), a.getExternalKey());
 
-        List<Account> all = accountDao.get();
+        final List<Account> all = accountDao.get();
         assertNotNull(all);
         assertTrue(all.size() >= 1);
     }
@@ -95,27 +96,27 @@ public class TestAccountDao extends AccountDaoTestBase {
     // simple test to ensure long phone numbers can be stored
     @Test
     public void testLongPhoneNumber() throws EntityPersistenceException {
-        Account account = createTestAccount(1, "123456789012345678901234");
+        final Account account = createTestAccount(1, "123456789012345678901234");
         accountDao.create(account, context);
 
-        Account saved = accountDao.getAccountByKey(account.getExternalKey());
+        final Account saved = accountDao.getAccountByKey(account.getExternalKey());
         assertNotNull(saved);
     }
 
     // simple test to ensure excessively long phone numbers cannot be stored
     @Test(expectedExceptions = {EntityPersistenceException.class})
     public void testOverlyLongPhoneNumber() throws EntityPersistenceException {
-        Account account = createTestAccount(1, "12345678901234567890123456");
+        final Account account = createTestAccount(1, "12345678901234567890123456");
         accountDao.create(account, context);
     }
 
     @Test
     public void testGetById() throws EntityPersistenceException {
         Account account = createTestAccount(1);
-        UUID id = account.getId();
-        String key = account.getExternalKey();
-        String name = account.getName();
-        int firstNameLength = account.getFirstNameLength();
+        final UUID id = account.getId();
+        final String key = account.getExternalKey();
+        final String name = account.getName();
+        final Integer firstNameLength = account.getFirstNameLength();
 
         accountDao.create(account, context);
 
@@ -130,45 +131,45 @@ public class TestAccountDao extends AccountDaoTestBase {
 
     @Test
     public void testCustomFields() throws EntityPersistenceException {
-        String fieldName = "testField1";
-        String fieldValue = "testField1_value";
+        final String fieldName = "testField1";
+        final String fieldValue = "testField1_value";
 
-        UUID accountId = UUID.randomUUID();
-        List<CustomField> customFields = new ArrayList<CustomField>();
+        final UUID accountId = UUID.randomUUID();
+        final List<CustomField> customFields = new ArrayList<CustomField>();
         customFields.add(new StringCustomField(fieldName, fieldValue));
-        CustomFieldDao customFieldDao = new AuditedCustomFieldDao(dbi);
+        final CustomFieldDao customFieldDao = new AuditedCustomFieldDao(dbi);
         customFieldDao.saveEntities(accountId, ObjectType.ACCOUNT, customFields, context);
 
-        Map<String, CustomField> customFieldMap = customFieldDao.loadEntities(accountId, ObjectType.ACCOUNT);
+        final Map<String, CustomField> customFieldMap = customFieldDao.loadEntities(accountId, ObjectType.ACCOUNT);
         assertEquals(customFieldMap.size(), 1);
-        CustomField customField = customFieldMap.get(fieldName);
+        final CustomField customField = customFieldMap.get(fieldName);
         assertEquals(customField.getName(), fieldName);
         assertEquals(customField.getValue(), fieldValue);
     }
 
     @Test
     public void testTags() throws EntityPersistenceException, TagApiException {
-        Account account = createTestAccount(1);
-        TagDefinition definition = new DefaultTagDefinition("Test Tag", "For testing only", false);
-        TagDefinitionSqlDao tagDescriptionDao = dbi.onDemand(TagDefinitionSqlDao.class);
+        final Account account = createTestAccount(1);
+        final TagDefinition definition = new DefaultTagDefinition("Test Tag", "For testing only", false);
+        final TagDefinitionSqlDao tagDescriptionDao = dbi.onDemand(TagDefinitionSqlDao.class);
         tagDescriptionDao.create(definition, context);
 
-        TagDao tagDao = new AuditedTagDao(dbi, tagEventBuilder, bus);
+        final TagDao tagDao = new AuditedTagDao(dbi, tagEventBuilder, bus);
         tagDao.insertTag(account.getId(), ObjectType.ACCOUNT, definition, context);
 
-        Map<String, Tag> tagMap = tagDao.loadEntities(account.getId(), ObjectType.ACCOUNT);
+        final Map<String, Tag> tagMap = tagDao.loadEntities(account.getId(), ObjectType.ACCOUNT);
         assertEquals(tagMap.size(), 1);
-        Tag tag = tagMap.get(definition.getName());
+        final Tag tag = tagMap.get(definition.getName());
         assertEquals(tag.getTagDefinitionName(), definition.getName());
     }
 
     @Test
     public void testGetIdFromKey() throws EntityPersistenceException {
-        Account account = createTestAccount(1);
+        final Account account = createTestAccount(1);
         accountDao.create(account, context);
 
         try {
-            UUID accountId = accountDao.getIdFromKey(account.getExternalKey());
+            final UUID accountId = accountDao.getIdFromKey(account.getExternalKey());
             assertEquals(accountId, account.getId());
         } catch (AccountApiException a) {
             fail("Retrieving account failed.");
@@ -177,7 +178,7 @@ public class TestAccountDao extends AccountDaoTestBase {
 
     @Test(expectedExceptions = AccountApiException.class)
     public void testGetIdFromKeyForNullKey() throws AccountApiException {
-        String key = null;
+        final String key = null;
         accountDao.getIdFromKey(key);
     }
 
@@ -186,7 +187,7 @@ public class TestAccountDao extends AccountDaoTestBase {
         final Account account = createTestAccount(1);
         accountDao.create(account, context);
 
-        AccountData accountData = new AccountData() {
+        final AccountData accountData = new AccountData() {
             @Override
             public String getExternalKey() {
                 return account.getExternalKey();
@@ -198,7 +199,7 @@ public class TestAccountDao extends AccountDaoTestBase {
             }
 
             @Override
-            public int getFirstNameLength() {
+            public Integer getFirstNameLength() {
                 return 4;
             }
 
@@ -213,17 +214,17 @@ public class TestAccountDao extends AccountDaoTestBase {
             }
 
             @Override
-            public boolean isMigrated() {
+            public Boolean isMigrated() {
                 return false;
             }
 
             @Override
-            public boolean isNotifiedForInvoices() {
+            public Boolean isNotifiedForInvoices() {
                 return false;
             }
 
             @Override
-            public int getBillCycleDay() {
+            public Integer getBillCycleDay() {
                 return account.getBillCycleDay();
             }
 
@@ -236,6 +237,7 @@ public class TestAccountDao extends AccountDaoTestBase {
             public UUID getPaymentMethodId() {
                 return account.getPaymentMethodId();
             }
+
             @Override
             public DateTimeZone getTimeZone() {
                 return DateTimeZone.forID("Australia/Darwin");
@@ -245,6 +247,7 @@ public class TestAccountDao extends AccountDaoTestBase {
             public String getLocale() {
                 return "FR-CA";
             }
+
             @Override
             public String getAddress1() {
                 return null;
@@ -281,10 +284,10 @@ public class TestAccountDao extends AccountDaoTestBase {
             }
         };
 
-        Account updatedAccount = new DefaultAccount(account.getId(), accountData);
+        final Account updatedAccount = new DefaultAccount(account.getId(), accountData);
         accountDao.update(updatedAccount, context);
 
-        Account savedAccount = accountDao.getAccountByKey(account.getExternalKey());
+        final Account savedAccount = accountDao.getAccountByKey(account.getExternalKey());
 
         assertNotNull(savedAccount);
         assertEquals(savedAccount.getName(), updatedAccount.getName());
@@ -305,31 +308,31 @@ public class TestAccountDao extends AccountDaoTestBase {
 
     @Test
     public void testAddingContactInformation() throws Exception {
-        UUID accountId = UUID.randomUUID();
-        DefaultAccount account = new DefaultAccount(accountId, "extKey123456", "myemail123456@glam.com",
-                                                    "John Smith", 4, Currency.USD, 15, null,
-                                                    DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
-                                                    null, null, null, null, null, null, null, null, false, false);
+        final UUID accountId = UUID.randomUUID();
+        final DefaultAccount account = new DefaultAccount(accountId, "extKey123456", "myemail123456@glam.com",
+                                                          "John Smith", 4, Currency.USD, 15, null,
+                                                          DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
+                                                          null, null, null, null, null, null, null, null, false, false);
         accountDao.create(account, context);
 
-        String address1 = "123 address 1";
-        String address2 = "456 address 2";
-        String companyName = "Some Company";
-        String city = "Cambridge Bay";
-        String stateOrProvince = "Nunavut";
-        String country = "Canada";
-        String postalCode = "X0B 0C0";
-        String phone = "18001112222";
-
-        DefaultAccount updatedAccount = new DefaultAccount(accountId, "extKey123456", "myemail123456@glam.com",
-                                                    "John Smith", 4, Currency.USD, 15, null,
-                                                    DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
-                                                    address1, address2, companyName, city, stateOrProvince, country,
-                                                    postalCode, phone, false, false);
+        final String address1 = "123 address 1";
+        final String address2 = "456 address 2";
+        final String companyName = "Some Company";
+        final String city = "Cambridge Bay";
+        final String stateOrProvince = "Nunavut";
+        final String country = "Canada";
+        final String postalCode = "X0B 0C0";
+        final String phone = "18001112222";
+
+        final DefaultAccount updatedAccount = new DefaultAccount(accountId, "extKey123456", "myemail123456@glam.com",
+                                                                 "John Smith", 4, Currency.USD, 15, null,
+                                                                 DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
+                                                                 address1, address2, companyName, city, stateOrProvince, country,
+                                                                 postalCode, phone, false, false);
 
         accountDao.update(updatedAccount, context);
 
-        Account savedAccount = accountDao.getById(accountId);
+        final Account savedAccount = accountDao.getById(accountId);
 
         assertNotNull(savedAccount);
         assertEquals(savedAccount.getId(), accountId);
@@ -344,55 +347,23 @@ public class TestAccountDao extends AccountDaoTestBase {
     }
 
     @Test
-    public void testRemovingContactInformation() throws Exception {
-        UUID accountId = UUID.randomUUID();
-
-        DefaultAccount account = new DefaultAccount(accountId, "extKey654321", "myemail654321@glam.com",
-                                                    "John Smith", 4, Currency.USD, 15, null,
-                                                    DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
-                                                    "123 address 1", "456 address 2", null, "Cambridge Bay",
-                                                    "Nunavut", "Canada", "X0B 0C0", "18001112222",
-                                                    false, false);
-        accountDao.create(account, context);
-
-        DefaultAccount updatedAccount = new DefaultAccount(accountId, "extKey654321", "myemail654321@glam.com",
-                                                    "John Smith", 4, Currency.USD, 15, null,
-                                                    DateTimeZone.forID("America/Cambridge_Bay"), "EN-CA",
-                                                    null, null, null, null, null, null, null, null,
-                                                    false, false);
-
-        accountDao.update(updatedAccount, context);
-
-        Account savedAccount = accountDao.getById(accountId);
-
-        assertNotNull(savedAccount);
-        assertEquals(savedAccount.getId(), accountId);
-        assertEquals(savedAccount.getAddress1(), null);
-        assertEquals(savedAccount.getAddress2(), null);
-        assertEquals(savedAccount.getCompanyName(), null);
-        assertEquals(savedAccount.getCity(), null);
-        assertEquals(savedAccount.getStateOrProvince(), null);
-        assertEquals(savedAccount.getCity(), null);
-        assertEquals(savedAccount.getPostalCode(), null);
-        assertEquals(savedAccount.getPhone(), null);
-    }
-
-    @Test(expectedExceptions = EntityPersistenceException.class)
     public void testExternalKeyCannotBeUpdated() throws Exception {
-        UUID accountId = UUID.randomUUID();
-        String originalExternalKey = "extKey1337";
+        final UUID accountId = UUID.randomUUID();
+        final String originalExternalKey = "extKey1337";
 
-        DefaultAccount account = new DefaultAccount(accountId, originalExternalKey, "myemail1337@glam.com",
-                                                    "John Smith", 4, Currency.USD, 15, null,
-                                                    null, null, null, null, null, null, null, null, null, null,
-                                                    false, false);
+        final DefaultAccount account = new DefaultAccount(accountId, originalExternalKey, "myemail1337@glam.com",
+                                                          "John Smith", 4, Currency.USD, 15, null,
+                                                          null, null, null, null, null, null, null, null, null, null,
+                                                          false, false);
         accountDao.create(account, context);
 
-        DefaultAccount updatedAccount = new DefaultAccount(accountId, "extKey1338", "myemail1337@glam.com",
-                                                    "John Smith", 4, Currency.USD, 15, null,
-                                                    null, null, null, null, null, null, null, null, null, null,
-                                                    false, false);
-        accountDao.update(updatedAccount, context);
+        final String buggyKey = "extKey1338";
+        final DefaultAccount updatedAccountData = new DefaultAccount(accountId, buggyKey, "myemail1337@glam.com",
+                                                                 "John Smith", 4, Currency.USD, 15, null,
+                                                                 null, null, null, null, null, null, null, null, null, null,
+                                                                 false, false);
+        accountDao.update(updatedAccountData, context);
+        Assert.assertNull(accountDao.getAccountByKey(buggyKey));
     }
 
     @Test
@@ -400,7 +371,7 @@ public class TestAccountDao extends AccountDaoTestBase {
         List<AccountEmail> emails = new ArrayList<AccountEmail>();
 
         // generate random account id
-        UUID accountId = UUID.randomUUID();
+        final UUID accountId = UUID.randomUUID();
 
         // add a new e-mail
         final AccountEmail email = new DefaultAccountEmail(accountId, "test@gmail.com");
@@ -413,7 +384,7 @@ public class TestAccountDao extends AccountDaoTestBase {
         verifyAccountEmailAuditAndHistoryCount(accountId, 1);
 
         // update e-mail
-        AccountEmail updatedEmail = new DefaultAccountEmail(email, "test2@gmail.com");
+        final AccountEmail updatedEmail = new DefaultAccountEmail(email, "test2@gmail.com");
         emails.clear();
         emails.add(updatedEmail);
         accountEmailDao.saveEmails(accountId, emails, context);
@@ -433,8 +404,46 @@ public class TestAccountDao extends AccountDaoTestBase {
         verifyAccountEmailAuditAndHistoryCount(accountId, 4);
     }
 
-    private void verifyAccountEmailAuditAndHistoryCount(UUID accountId, int expectedCount) {
-        Handle handle = dbi.open();
+    @Test
+    public void testAddAndRemoveAccountEmail() {
+        final UUID accountId = UUID.randomUUID();
+        final String email1 = UUID.randomUUID().toString();
+        final String email2 = UUID.randomUUID().toString();
+
+        // Verify the original state
+        assertEquals(accountEmailDao.getEmails(accountId).size(), 0);
+
+        // Add a new e-mail
+        final AccountEmail accountEmail1 = new DefaultAccountEmail(accountId, email1);
+        accountEmailDao.addEmail(accountId, accountEmail1, context);
+        final List<AccountEmail> firstEmails = accountEmailDao.getEmails(accountId);
+        assertEquals(firstEmails.size(), 1);
+        assertEquals(firstEmails.get(0).getAccountId(), accountId);
+        assertEquals(firstEmails.get(0).getEmail(), email1);
+
+        // Add a second e-mail
+        final AccountEmail accountEmail2 = new DefaultAccountEmail(accountId, email2);
+        accountEmailDao.addEmail(accountId, accountEmail2, context);
+        final List<AccountEmail> secondEmails = accountEmailDao.getEmails(accountId);
+        assertEquals(secondEmails.size(), 2);
+        assertTrue(secondEmails.get(0).getAccountId().equals(accountId));
+        assertTrue(secondEmails.get(1).getAccountId().equals(accountId));
+        assertTrue(secondEmails.get(0).getEmail().equals(email1) || secondEmails.get(0).getEmail().equals(email2));
+        assertTrue(secondEmails.get(1).getEmail().equals(email1) || secondEmails.get(1).getEmail().equals(email2));
+
+        // Delete the first e-mail
+        accountEmailDao.removeEmail(accountId, accountEmail1, context);
+        final List<AccountEmail> thirdEmails = accountEmailDao.getEmails(accountId);
+        assertEquals(thirdEmails.size(), 1);
+        assertEquals(thirdEmails.get(0).getAccountId(), accountId);
+        assertEquals(thirdEmails.get(0).getEmail(), email2);
+
+        // Verify that history and audit contain three entries (2 inserts and one delete)
+        verifyAccountEmailAuditAndHistoryCount(accountId, 3);
+    }
+
+    private void verifyAccountEmailAuditAndHistoryCount(final UUID accountId, final int expectedCount) {
+        final Handle handle = dbi.open();
 
         // verify audit
         StringBuilder sb = new StringBuilder();
diff --git a/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithMocks.java b/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithMocks.java
index aa944e3..f806309 100644
--- a/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithMocks.java
+++ b/account/src/test/java/com/ning/billing/account/glue/AccountModuleWithMocks.java
@@ -27,7 +27,7 @@ public class AccountModuleWithMocks extends AccountModule {
     @Override
     protected void installAccountDao() {
         bind(MockAccountDao.class).asEagerSingleton();
-        AccountEmailDao accountEmailDao = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountEmailDao.class);
+        final AccountEmailDao accountEmailDao = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountEmailDao.class);
         bind(AccountEmailDao.class).toInstance(accountEmailDao);
         bind(AccountDao.class).to(MockAccountDao.class);
     }

analytics/pom.xml 17(+6 -11)

diff --git a/analytics/pom.xml b/analytics/pom.xml
index 9fc2da7..ecd27bf 100644
--- a/analytics/pom.xml
+++ b/analytics/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-analytics</artifactId>
@@ -35,17 +35,12 @@
             <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -82,7 +77,7 @@
             <type>test-jar</type>
             <scope>test</scope>
         </dependency>
-         <dependency>
+        <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-catalog</artifactId>
             <scope>test</scope>
@@ -95,7 +90,7 @@
         <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-entitlement</artifactId>
-             <type>test-jar</type>
+            <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -106,7 +101,7 @@
         <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-junction</artifactId>
-             <type>test-jar</type>
+            <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
index caefaef..eb41bce 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
@@ -21,20 +21,37 @@ import com.google.inject.Inject;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountChangeEvent;
 import com.ning.billing.account.api.AccountCreationEvent;
+import com.ning.billing.entitlement.api.timeline.RepairEntitlementEvent;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.SubscriptionEvent;
+import com.ning.billing.invoice.api.EmptyInvoiceEvent;
 import com.ning.billing.invoice.api.InvoiceCreationEvent;
 import com.ning.billing.payment.api.PaymentErrorEvent;
 import com.ning.billing.payment.api.PaymentInfoEvent;
+import com.ning.billing.util.tag.api.ControlTagCreationEvent;
+import com.ning.billing.util.tag.api.ControlTagDefinitionCreationEvent;
+import com.ning.billing.util.tag.api.ControlTagDefinitionDeletionEvent;
+import com.ning.billing.util.tag.api.ControlTagDeletionEvent;
+import com.ning.billing.util.tag.api.UserTagCreationEvent;
+import com.ning.billing.util.tag.api.UserTagDefinitionCreationEvent;
+import com.ning.billing.util.tag.api.UserTagDefinitionDeletionEvent;
+import com.ning.billing.util.tag.api.UserTagDeletionEvent;
 
 public class AnalyticsListener {
     private final BusinessSubscriptionTransitionRecorder bstRecorder;
     private final BusinessAccountRecorder bacRecorder;
+    private final BusinessInvoiceRecorder invoiceRecorder;
+    private final BusinessTagRecorder tagRecorder;
 
     @Inject
-    public AnalyticsListener(final BusinessSubscriptionTransitionRecorder bstRecorder, final BusinessAccountRecorder bacRecorder) {
+    public AnalyticsListener(final BusinessSubscriptionTransitionRecorder bstRecorder,
+                             final BusinessAccountRecorder bacRecorder,
+                             final BusinessInvoiceRecorder invoiceRecorder,
+                             final BusinessTagRecorder tagRecorder) {
         this.bstRecorder = bstRecorder;
         this.bacRecorder = bacRecorder;
+        this.invoiceRecorder = invoiceRecorder;
+        this.tagRecorder = tagRecorder;
     }
 
     @Subscribe
@@ -77,12 +94,17 @@ public class AnalyticsListener {
             return;
         }
 
-        bacRecorder.accountUpdated(event.getAccountId(), event.getChangedFields());
+        bacRecorder.accountUpdated(event.getAccountId());
     }
 
     @Subscribe
-    public void handleInvoice(final InvoiceCreationEvent event) {
-        bacRecorder.accountUpdated(event.getAccountId());
+    public void handleInvoiceCreation(final InvoiceCreationEvent event) {
+        invoiceRecorder.invoiceCreated(event.getInvoiceId());
+    }
+
+    @Subscribe
+    public void handleNullInvoice(final EmptyInvoiceEvent event) {
+        // Ignored for now
     }
 
     @Subscribe
@@ -94,4 +116,49 @@ public class AnalyticsListener {
     public void handlePaymentError(final PaymentErrorEvent paymentError) {
         // TODO - we can't tie the error back to an account yet
     }
+
+    @Subscribe
+    public void handleControlTagCreation(final ControlTagCreationEvent event) {
+        tagRecorder.tagAdded(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName());
+    }
+
+    @Subscribe
+    public void handleControlTagDeletion(final ControlTagDeletionEvent event) {
+        tagRecorder.tagRemoved(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName());
+    }
+
+    @Subscribe
+    public void handleUserTagCreation(final UserTagCreationEvent event) {
+        tagRecorder.tagAdded(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName());
+    }
+
+    @Subscribe
+    public void handleUserTagDeletion(final UserTagDeletionEvent event) {
+        tagRecorder.tagRemoved(event.getObjectType(), event.getObjectId(), event.getTagDefinition().getName());
+    }
+
+    @Subscribe
+    public void handleControlTagDefinitionCreation(final ControlTagDefinitionCreationEvent event) {
+        // Ignored for now
+    }
+
+    @Subscribe
+    public void handleControlTagDefinitionDeletion(final ControlTagDefinitionDeletionEvent event) {
+        // Ignored for now
+    }
+
+    @Subscribe
+    public void handleUserTagDefinitionCreation(final UserTagDefinitionCreationEvent event) {
+        // Ignored for now
+    }
+
+    @Subscribe
+    public void handleUserTagDefinitionDeletion(final UserTagDefinitionDeletionEvent event) {
+        // Ignored for now
+    }
+
+    @Subscribe
+    public void handleRepairEntitlement(final RepairEntitlementEvent event) {
+        // Ignored for now
+    }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java b/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
new file mode 100644
index 0000000..424e1c2
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.api.user;
+
+import javax.inject.Inject;
+import java.util.List;
+import java.util.UUID;
+
+import com.ning.billing.analytics.dao.AnalyticsDao;
+import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccountTag;
+import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+
+// Note: not exposed in api yet
+public class DefaultAnalyticsUserApi {
+    private final AnalyticsDao analyticsDao;
+
+    @Inject
+    public DefaultAnalyticsUserApi(final AnalyticsDao analyticsDao) {
+        this.analyticsDao = analyticsDao;
+    }
+
+    public BusinessAccount getAccountByKey(final String accountKey) {
+        return analyticsDao.getAccountByKey(accountKey);
+    }
+
+    public List<BusinessSubscriptionTransition> getTransitionsForBundle(final String externalKey) {
+        return analyticsDao.getTransitionsByKey(externalKey);
+    }
+
+    public List<BusinessInvoice> getInvoicesForAccount(final String accountKey) {
+        return analyticsDao.getInvoicesByKey(accountKey);
+    }
+
+    public List<BusinessAccountTag> getTagsForAccount(final String accountKey) {
+        return analyticsDao.getTagsForAccount(accountKey);
+    }
+
+    public List<BusinessInvoiceItem> getInvoiceItemsForInvoice(final UUID invoiceId) {
+        return analyticsDao.getInvoiceItemsForInvoice(invoiceId.toString());
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
index fb3343e..998fd7e 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
@@ -17,9 +17,7 @@
 package com.ning.billing.analytics;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -31,64 +29,47 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountData;
 import com.ning.billing.account.api.AccountUserApi;
-import com.ning.billing.account.api.ChangedField;
-import com.ning.billing.analytics.dao.BusinessAccountDao;
+import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
+import com.ning.billing.analytics.model.BusinessAccount;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentInfoEvent;
-import com.ning.billing.util.api.TagUserApi;
-import com.ning.billing.util.dao.ObjectType;
-import com.ning.billing.util.tag.Tag;
 
 public class BusinessAccountRecorder {
     private static final Logger log = LoggerFactory.getLogger(BusinessAccountRecorder.class);
 
-    private final BusinessAccountDao dao;
+    private final BusinessAccountSqlDao sqlDao;
     private final AccountUserApi accountApi;
     private final InvoiceUserApi invoiceUserApi;
     private final PaymentApi paymentApi;
-    private final TagUserApi tagUserApi;
 
     @Inject
-    public BusinessAccountRecorder(final BusinessAccountDao dao, final AccountUserApi accountApi,
-                                   final InvoiceUserApi invoiceUserApi, final PaymentApi paymentApi,
-                                   final TagUserApi tagUserApi) {
-        this.dao = dao;
+    public BusinessAccountRecorder(final BusinessAccountSqlDao sqlDao, final AccountUserApi accountApi,
+                                   final InvoiceUserApi invoiceUserApi, final PaymentApi paymentApi) {
+        this.sqlDao = sqlDao;
         this.accountApi = accountApi;
         this.invoiceUserApi = invoiceUserApi;
         this.paymentApi = paymentApi;
-        this.tagUserApi = tagUserApi;
     }
 
     public void accountCreated(final AccountData data) {
-        Account account;
+        final Account account;
         try {
             account = accountApi.getAccountByKey(data.getExternalKey());
-            Map<String, Tag> tags = tagUserApi.getTags(account.getId(), ObjectType.ACCOUNT);
-            final BusinessAccount bac = createBusinessAccountFromAccount(account, new ArrayList<Tag>(tags.values()));
+            final BusinessAccount bac = new BusinessAccount();
+            updateBusinessAccountFromAccount(account, bac);
 
             log.info("ACCOUNT CREATION " + bac);
-            dao.createAccount(bac);
+            sqlDao.createAccount(bac);
         } catch (AccountApiException e) {
             log.warn("Error encountered creating BusinessAccount", e);
         }
     }
 
     /**
-     * Notification handler for Account changes
-     *
-     * @param accountId     account id changed
-     * @param changedFields list of changed fields
-     */
-    public void accountUpdated(final UUID accountId, final List<ChangedField> changedFields) {
-        // None of the fields updated interest us so far - see DefaultAccountChangeNotification
-        // TODO We'll need notifications for tags changes eventually
-    }
-
-    /**
      * Notification handler for Payment creations
      *
      * @param paymentInfo payment object (from the payment plugin)
@@ -110,64 +91,40 @@ public class BusinessAccountRecorder {
     public void accountUpdated(final UUID accountId) {
         try {
             final Account account = accountApi.getAccountById(accountId);
-            final Map<String, Tag> tags = tagUserApi.getTags(accountId, ObjectType.ACCOUNT);
-
-            if (account == null) {
-                log.warn("Couldn't find account {}", accountId);
-                return;
-            }
 
-            BusinessAccount bac = dao.getAccount(account.getExternalKey());
+            BusinessAccount bac = sqlDao.getAccount(account.getExternalKey());
             if (bac == null) {
-                bac = createBusinessAccountFromAccount(account, new ArrayList<Tag>(tags.values()));
+                bac = new BusinessAccount();
+                updateBusinessAccountFromAccount(account, bac);
                 log.info("ACCOUNT CREATION " + bac);
-                dao.createAccount(bac);
+                sqlDao.createAccount(bac);
             } else {
                 updateBusinessAccountFromAccount(account, bac);
                 log.info("ACCOUNT UPDATE " + bac);
-                dao.saveAccount(bac);
+                sqlDao.saveAccount(bac);
             }
         } catch (AccountApiException e) {
             log.warn("Error encountered creating BusinessAccount", e);
         }
-
-    }
-
-    private BusinessAccount createBusinessAccountFromAccount(final Account account, final List<Tag> tags) {
-        final BusinessAccount bac = new BusinessAccount(
-                account.getExternalKey(),
-                invoiceUserApi.getAccountBalance(account.getId()),
-                tags,
-                // These fields will be updated below
-                null,
-                null,
-                null,
-                null,
-                null,
-                null
-        );
-        updateBusinessAccountFromAccount(account, bac);
-
-        return bac;
     }
 
     private void updateBusinessAccountFromAccount(final Account account, final BusinessAccount bac) {
+        bac.setName(account.getName());
+        bac.setKey(account.getExternalKey());
 
-        final List<UUID> invoiceIds = new ArrayList<UUID>();
         try {
-            DateTime lastInvoiceDate = null;
-            BigDecimal totalInvoiceBalance = BigDecimal.ZERO;
-            String lastPaymentStatus = null;
-            String paymentMethod = null;
-            String creditCardType = null;
-            String billingAddressCountry = null;
+            DateTime lastInvoiceDate = bac.getLastInvoiceDate();
+            BigDecimal totalInvoiceBalance = bac.getTotalInvoiceBalance();
+            String lastPaymentStatus = bac.getLastPaymentStatus();
+            String paymentMethod = bac.getPaymentMethod();
+            String creditCardType = bac.getCreditCardType();
+            String billingAddressCountry = bac.getBillingAddressCountry();
 
             // Retrieve invoices information
             final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId());
             if (invoices != null && invoices.size() > 0) {
 
                 for (final Invoice invoice : invoices) {
-                    invoiceIds.add(invoice.getId());
                     totalInvoiceBalance = totalInvoiceBalance.add(invoice.getBalance());
 
                     if (lastInvoiceDate == null || invoice.getInvoiceDate().isAfter(lastInvoiceDate)) {
@@ -177,11 +134,11 @@ public class BusinessAccountRecorder {
 
                 // Retrieve payments information for these invoices
                 DateTime lastPaymentDate = null;
-                
-                List<Payment> payments = paymentApi.getAccountPayments(account.getId());
+
+                final List<Payment> payments = paymentApi.getAccountPayments(account.getId());
                 if (payments != null) {
-                    for (Payment cur : payments) {
-                     // Use the last payment method/type/country as the default one for the account
+                    for (final Payment cur : payments) {
+                        // Use the last payment method/type/country as the default one for the account
                         if (lastPaymentDate == null || cur.getEffectiveDate().isAfter(lastPaymentDate)) {
                             lastPaymentDate = cur.getEffectiveDate();
                             lastPaymentStatus = cur.getPaymentStatus().toString();
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java
new file mode 100644
index 0000000..21693f3
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoiceRecorder.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.analytics.dao.AnalyticsDao;
+import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
+import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
+import com.ning.billing.entitlement.api.user.Subscription;
+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.InvoiceUserApi;
+
+public class BusinessInvoiceRecorder {
+    private static final Logger log = LoggerFactory.getLogger(BusinessInvoiceRecorder.class);
+
+    private final AnalyticsDao analyticsDao;
+    private final AccountUserApi accountApi;
+    private final EntitlementUserApi entitlementApi;
+    private final InvoiceUserApi invoiceApi;
+
+    @Inject
+    public BusinessInvoiceRecorder(final AnalyticsDao analyticsDao,
+                                   final AccountUserApi accountApi,
+                                   final EntitlementUserApi entitlementApi,
+                                   final InvoiceUserApi invoiceApi) {
+        this.analyticsDao = analyticsDao;
+        this.accountApi = accountApi;
+        this.entitlementApi = entitlementApi;
+        this.invoiceApi = invoiceApi;
+    }
+
+    public void invoiceCreated(final UUID invoiceId) {
+        // Lookup the invoice object
+        final Invoice invoice = invoiceApi.getInvoice(invoiceId);
+        if (invoice == null) {
+            log.warn("Ignoring invoice creation for invoice id {} (invoice does not exist)", invoiceId.toString());
+            return;
+        }
+
+        // Lookup the associated account
+        final String accountKey;
+        try {
+            final Account account = accountApi.getAccountById(invoice.getAccountId());
+            accountKey = account.getExternalKey();
+        } catch (AccountApiException e) {
+            log.warn("Ignoring invoice creation for invoice id {} and account id {} (account does not exist)",
+                     invoice.getId().toString(),
+                     invoice.getAccountId().toString());
+            return;
+        }
+
+        // Create the invoice
+        final BusinessInvoice businessInvoice = new BusinessInvoice(accountKey, invoice);
+
+        // Create associated invoice items
+        final List<BusinessInvoiceItem> businessInvoiceItems = new ArrayList<BusinessInvoiceItem>();
+        for (final InvoiceItem invoiceItem : invoice.getInvoiceItems()) {
+            final BusinessInvoiceItem businessInvoiceItem = createBusinessInvoiceItem(invoiceItem);
+            if (businessInvoiceItem != null) {
+                businessInvoiceItems.add(businessInvoiceItem);
+            }
+        }
+
+        // Update the Analytics tables
+        analyticsDao.createInvoice(accountKey, businessInvoice, businessInvoiceItems);
+    }
+
+    private BusinessInvoiceItem createBusinessInvoiceItem(final InvoiceItem invoiceItem) {
+        final String externalKey;
+        try {
+            final SubscriptionBundle bundle = entitlementApi.getBundleFromId(invoiceItem.getBundleId());
+            externalKey = bundle.getKey();
+        } catch (EntitlementUserApiException e) {
+            log.warn("Ignoring invoice item {} for bundle {} (bundle does not exist)",
+                     invoiceItem.getId().toString(),
+                     invoiceItem.getBundleId().toString());
+            return null;
+        }
+
+        final Subscription subscription;
+        try {
+            subscription = entitlementApi.getSubscriptionFromId(invoiceItem.getSubscriptionId());
+        } catch (EntitlementUserApiException e) {
+            log.warn("Ignoring invoice item {} for subscription {} (subscription does not exist)",
+                     invoiceItem.getId().toString(),
+                     invoiceItem.getSubscriptionId().toString());
+            return null;
+        }
+
+        final Plan plan = subscription.getCurrentPlan();
+        if (plan == null) {
+            log.warn("Ignoring invoice item {} for subscription {} (null plan)",
+                     invoiceItem.getId().toString(),
+                     invoiceItem.getSubscriptionId().toString());
+            return null;
+        }
+
+        final PlanPhase planPhase = subscription.getCurrentPhase();
+        if (planPhase == null) {
+            log.warn("Ignoring invoice item {} for subscription {} (null phase)",
+                     invoiceItem.getId().toString(),
+                     invoiceItem.getSubscriptionId().toString());
+            return null;
+        }
+
+        return new BusinessInvoiceItem(externalKey, invoiceItem, plan, planPhase);
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
index 80db909..04e3547 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
@@ -17,7 +17,6 @@
 package com.ning.billing.analytics;
 
 import java.util.List;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
@@ -27,7 +26,10 @@ import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
-import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionDao;
+import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
+import com.ning.billing.analytics.model.BusinessSubscription;
+import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
@@ -38,14 +40,14 @@ import com.ning.billing.entitlement.api.user.SubscriptionEvent;
 public class BusinessSubscriptionTransitionRecorder {
     private static final Logger log = LoggerFactory.getLogger(BusinessSubscriptionTransitionRecorder.class);
 
-    private final BusinessSubscriptionTransitionDao dao;
+    private final BusinessSubscriptionTransitionSqlDao sqlDao;
     private final EntitlementUserApi entitlementApi;
     private final AccountUserApi accountApi;
     private final CatalogService catalogService;
 
     @Inject
-    public BusinessSubscriptionTransitionRecorder(final BusinessSubscriptionTransitionDao dao, final CatalogService catalogService, final EntitlementUserApi entitlementApi, final AccountUserApi accountApi) {
-        this.dao = dao;
+    public BusinessSubscriptionTransitionRecorder(final BusinessSubscriptionTransitionSqlDao sqlDao, final CatalogService catalogService, final EntitlementUserApi entitlementApi, final AccountUserApi accountApi) {
+        this.sqlDao = sqlDao;
         this.catalogService = catalogService;
         this.entitlementApi = entitlementApi;
         this.accountApi = accountApi;
@@ -84,13 +86,13 @@ public class BusinessSubscriptionTransitionRecorder {
     void recordTransition(final BusinessSubscriptionEvent event, final SubscriptionEvent transition)
             throws AccountApiException, EntitlementUserApiException {
         Currency currency = null;
-        String transitionKey = null;
+        String externalKey = null;
         String accountKey = null;
 
         // Retrieve key and currency via the bundle
         final SubscriptionBundle bundle = entitlementApi.getBundleFromId(transition.getBundleId());
         if (bundle != null) {
-            transitionKey = bundle.getKey();
+            externalKey = bundle.getKey();
 
             final Account account = accountApi.getAccountById(bundle.getAccountId());
             if (account != null) {
@@ -104,7 +106,7 @@ public class BusinessSubscriptionTransitionRecorder {
         DateTime previousEffectiveTransitionTime = null;
         // For creation events, the prev subscription will always be null
         if (event.getEventType() != BusinessSubscriptionEvent.EventType.ADD) {
-            final List<BusinessSubscriptionTransition> transitions = dao.getTransitions(transitionKey);
+            final List<BusinessSubscriptionTransition> transitions = sqlDao.getTransitions(externalKey);
             if (transitions != null && transitions.size() > 0) {
                 final BusinessSubscriptionTransition lastTransition = transitions.get(transitions.size() - 1);
                 if (lastTransition != null && lastTransition.getNextSubscription() != null) {
@@ -129,14 +131,14 @@ public class BusinessSubscriptionTransitionRecorder {
             nextSubscription = new BusinessSubscription(transition.getNextPriceList(), transition.getNextPlan(), transition.getNextPhase(), currency, transition.getEffectiveTransitionTime(), transition.getNextState(), transition.getSubscriptionId(), transition.getBundleId(), catalogService.getFullCatalog());
         }
 
-        record(transition.getId(), transitionKey, accountKey, transition.getRequestedTransitionTime(), event, prevSubscription, nextSubscription);
+        record(transition.getTotalOrdering(), externalKey, accountKey, transition.getRequestedTransitionTime(), event, prevSubscription, nextSubscription);
     }
 
     // Public for internal reasons
-    public void record(final UUID id, final String key, final String accountKey, final DateTime requestedDateTime, final BusinessSubscriptionEvent event, final BusinessSubscription prevSubscription, final BusinessSubscription nextSubscription) {
+    public void record(final Long totalOrdering, final String externalKey, final String accountKey, final DateTime requestedDateTime, final BusinessSubscriptionEvent event, final BusinessSubscription prevSubscription, final BusinessSubscription nextSubscription) {
         final BusinessSubscriptionTransition transition = new BusinessSubscriptionTransition(
-                id,
-                key,
+                totalOrdering,
+                externalKey,
                 accountKey,
                 requestedDateTime,
                 event,
@@ -145,6 +147,6 @@ public class BusinessSubscriptionTransitionRecorder {
         );
 
         log.info(transition.getEvent() + " " + transition);
-        dao.createTransition(transition);
+        sqlDao.createTransition(transition);
     }
 }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessTagRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessTagRecorder.java
new file mode 100644
index 0000000..8aa4343
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessTagRecorder.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics;
+
+import javax.inject.Inject;
+import java.util.UUID;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.analytics.dao.BusinessAccountTagSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoicePaymentTagSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoiceTagSqlDao;
+import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionTagSqlDao;
+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.util.dao.ObjectType;
+
+public class BusinessTagRecorder {
+    private static final Logger log = LoggerFactory.getLogger(BusinessTagRecorder.class);
+
+    private final BusinessAccountTagSqlDao accountTagSqlDao;
+    private final BusinessInvoiceTagSqlDao invoiceTagSqlDao;
+    private final BusinessInvoicePaymentTagSqlDao invoicePaymentTagSqlDao;
+    private final BusinessSubscriptionTransitionTagSqlDao subscriptionTransitionTagSqlDao;
+    private final AccountUserApi accountApi;
+    private final EntitlementUserApi entitlementUserApi;
+
+    @Inject
+    public BusinessTagRecorder(final BusinessAccountTagSqlDao accountTagSqlDao,
+                               final BusinessInvoicePaymentTagSqlDao invoicePaymentTagSqlDao,
+                               final BusinessInvoiceTagSqlDao invoiceTagSqlDao,
+                               final BusinessSubscriptionTransitionTagSqlDao subscriptionTransitionTagSqlDao,
+                               final AccountUserApi accountApi,
+                               final EntitlementUserApi entitlementUserApi) {
+        this.accountTagSqlDao = accountTagSqlDao;
+        this.invoicePaymentTagSqlDao = invoicePaymentTagSqlDao;
+        this.invoiceTagSqlDao = invoiceTagSqlDao;
+        this.subscriptionTransitionTagSqlDao = subscriptionTransitionTagSqlDao;
+        this.accountApi = accountApi;
+        this.entitlementUserApi = entitlementUserApi;
+    }
+
+    public void tagAdded(final ObjectType objectType, final UUID objectId, final String name) {
+        if (objectType.equals(ObjectType.ACCOUNT)) {
+            tagAddedForAccount(objectId, name);
+        } else if (objectType.equals(ObjectType.BUNDLE)) {
+            tagAddedForBundle(objectId, name);
+        } else if (objectType.equals(ObjectType.INVOICE)) {
+            tagAddedForInvoice(objectId, name);
+        } else if (objectType.equals(ObjectType.PAYMENT)) {
+            tagAddedForPayment(objectId, name);
+        } else {
+            log.info("Ignoring tag addition of {} for object id {} (type {})", new Object[]{name, objectId.toString(), objectType.toString()});
+        }
+    }
+
+    public void tagRemoved(final ObjectType objectType, final UUID objectId, final String name) {
+        if (objectType.equals(ObjectType.ACCOUNT)) {
+            tagRemovedForAccount(objectId, name);
+        } else if (objectType.equals(ObjectType.BUNDLE)) {
+            tagRemovedForBundle(objectId, name);
+        } else if (objectType.equals(ObjectType.INVOICE)) {
+            tagRemovedForInvoice(objectId, name);
+        } else if (objectType.equals(ObjectType.PAYMENT)) {
+            tagRemovedForPayment(objectId, name);
+        } else {
+            log.info("Ignoring tag removal of {} for object id {} (type {})", new Object[]{name, objectId.toString(), objectType.toString()});
+        }
+    }
+
+    private void tagAddedForAccount(final UUID objectId, final String name) {
+        final Account account;
+        try {
+            account = accountApi.getAccountById(objectId);
+        } catch (AccountApiException e) {
+            log.warn("Ignoring tag addition of {} for account id {} (account does not exist)", name, objectId.toString());
+            return;
+        }
+
+        final String accountKey = account.getExternalKey();
+        accountTagSqlDao.addTag(accountKey, name);
+    }
+
+    private void tagRemovedForAccount(final UUID objectId, final String name) {
+        final Account account;
+        try {
+            account = accountApi.getAccountById(objectId);
+        } catch (AccountApiException e) {
+            log.warn("Ignoring tag removal of {} for account id {} (account does not exist)", name, objectId.toString());
+            return;
+        }
+
+        final String accountKey = account.getExternalKey();
+        accountTagSqlDao.removeTag(accountKey, name);
+    }
+
+    private void tagAddedForBundle(final UUID objectId, final String name) {
+        final SubscriptionBundle bundle;
+        try {
+            bundle = entitlementUserApi.getBundleFromId(objectId);
+        } catch (EntitlementUserApiException e) {
+            log.warn("Ignoring tag addition of {} for bundle id {} (bundle does not exist)", name, objectId.toString());
+            return;
+        }
+
+        /*
+         * Note: we store tags associated to bundles, not to subscriptions.
+         * Subscriptions are in the core of killbill and not exposed in Analytics to avoid a hard dependency
+         * (i.e. dashboards should not rely on killbill ids).
+         */
+        final String externalKey = bundle.getKey();
+        subscriptionTransitionTagSqlDao.addTag(externalKey, name);
+    }
+
+    private void tagRemovedForBundle(final UUID objectId, final String name) {
+        final SubscriptionBundle bundle;
+        try {
+            bundle = entitlementUserApi.getBundleFromId(objectId);
+        } catch (EntitlementUserApiException e) {
+            log.warn("Ignoring tag removal of {} for bundle id {} (bundle does not exist)", name, objectId.toString());
+            return;
+        }
+
+        final String externalKey = bundle.getKey();
+        subscriptionTransitionTagSqlDao.removeTag(externalKey, name);
+    }
+
+    private void tagAddedForInvoice(final UUID objectId, final String name) {
+        invoiceTagSqlDao.addTag(objectId.toString(), name);
+    }
+
+    private void tagRemovedForInvoice(final UUID objectId, final String name) {
+        invoiceTagSqlDao.removeTag(objectId.toString(), name);
+    }
+
+    private void tagAddedForPayment(final UUID objectId, final String name) {
+        invoicePaymentTagSqlDao.addTag(objectId.toString(), name);
+    }
+
+    private void tagRemovedForPayment(final UUID objectId, final String name) {
+        invoicePaymentTagSqlDao.removeTag(objectId.toString(), name);
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java
new file mode 100644
index 0000000..8dcc6c8
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/AnalyticsDao.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccountTag;
+import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+
+public interface AnalyticsDao {
+    BusinessAccount getAccountByKey(final String accountKey);
+
+    List<BusinessSubscriptionTransition> getTransitionsByKey(final String externalKey);
+
+    List<BusinessInvoice> getInvoicesByKey(final String accountKey);
+
+    List<BusinessAccountTag> getTagsForAccount(final String accountKey);
+
+    List<BusinessInvoiceItem> getInvoiceItemsForInvoice(final String invoiceId);
+
+    void createInvoice(final String accountKey, final BusinessInvoice invoice, final Iterable<BusinessInvoiceItem> invoiceItems);
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
index 234e543..223068e 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountBinder.java
@@ -30,16 +30,13 @@ import org.skife.jdbi.v2.sqlobject.Binder;
 import org.skife.jdbi.v2.sqlobject.BinderFactory;
 import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
 
-import com.google.common.base.Joiner;
-import com.ning.billing.analytics.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccount;
 
 @BindingAnnotation(BusinessAccountBinder.BacBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface BusinessAccountBinder {
     public static class BacBinderFactory implements BinderFactory {
-        private final Joiner joiner = Joiner.on(";").skipNulls();
-
         public Binder build(final Annotation annotation) {
             return new Binder<BusinessAccountBinder, BusinessAccount>() {
                 public void bind(final SQLStatement q, final BusinessAccountBinder bind, final BusinessAccount account) {
@@ -54,7 +51,7 @@ public @interface BusinessAccountBinder {
 
                     q.bind("account_key", account.getKey());
                     q.bind("balance", account.getRoundedBalance());
-                    q.bind("tags", joiner.join(account.getTags()));
+                    q.bind("name", account.getName());
                     if (account.getLastInvoiceDate() != null) {
                         q.bind("last_invoice_date", account.getLastInvoiceDate().getMillis());
                     } else {
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldMapper.java
new file mode 100644
index 0000000..7cb7260
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldMapper.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessAccountField;
+
+public class BusinessAccountFieldMapper implements ResultSetMapper<BusinessAccountField> {
+    @Override
+    public BusinessAccountField map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessAccountField(r.getString(1), r.getString(2), r.getString(3));
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java
new file mode 100644
index 0000000..d982772
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessAccountField;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessAccountFieldMapper.class)
+public interface BusinessAccountFieldSqlDao {
+    @SqlQuery
+    List<BusinessAccountField> getFieldsForAccount(@Bind("account_key") final String accountKey);
+
+    @SqlUpdate
+    int addField(@Bind("account_key") final String accountKey, @Bind("name") final String name, @Bind("value") final String value);
+
+    @SqlUpdate
+    int removeField(@Bind("account_key") final String accountKey, @Bind("name") final String name);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java
index 366bb3b..bf4da3d 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountMapper.java
@@ -19,55 +19,22 @@ package com.ning.billing.analytics.dao;
 import java.math.BigDecimal;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.google.common.base.Splitter;
-import com.google.common.collect.Iterables;
-import com.ning.billing.analytics.BusinessAccount;
-import com.ning.billing.util.tag.Tag;
+import com.ning.billing.analytics.model.BusinessAccount;
 
 public class BusinessAccountMapper implements ResultSetMapper<BusinessAccount> {
-    private final Splitter splitter = Splitter.on(";").trimResults().omitEmptyStrings();
-
     @Override
     public BusinessAccount map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
-        final List<String> tagNames = new ArrayList<String>();
-        Iterables.addAll(tagNames, splitter.split(r.getString(5)));
-
-        final List<Tag> tags = new ArrayList<Tag>();
-        for (final String tagName : tagNames) {
-            tags.add(new Tag() {
-                private final UUID id = UUID.randomUUID();
-
-                @Override
-                public String getTagDefinitionName() {
-                    return tagName;
-                }
-
-                @Override
-                public UUID getId() {
-                    return id;
-                }
-
-                @Override
-                public String toString() {
-                    return tagName;
-                }
-            });
-        }
-
         final BusinessAccount account = new BusinessAccount(
                 r.getString(1),
+                r.getString(5),
                 BigDecimal.valueOf(r.getDouble(4)),
-                tags,
-                new DateTime(r.getLong(6), DateTimeZone.UTC),
+                r.getLong(6) == 0 ? null : new DateTime(r.getLong(6), DateTimeZone.UTC),
                 BigDecimal.valueOf(r.getDouble(7)),
                 r.getString(8),
                 r.getString(9),
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagMapper.java
new file mode 100644
index 0000000..ddad81d
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagMapper.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessAccountTag;
+
+public class BusinessAccountTagMapper implements ResultSetMapper<BusinessAccountTag> {
+    @Override
+    public BusinessAccountTag map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessAccountTag(r.getString(1), r.getString(2));
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java
new file mode 100644
index 0000000..0aac244
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessAccountTag;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessAccountTagMapper.class)
+public interface BusinessAccountTagSqlDao {
+    @SqlQuery
+    List<BusinessAccountTag> getTagsForAccount(@Bind("account_key") final String accountKey);
+
+    @SqlUpdate
+    int addTag(@Bind("account_key") final String accountKey, @Bind("name") final String name);
+
+    @SqlUpdate
+    int removeTag(@Bind("account_key") final String accountKey, @Bind("name") final String name);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceBinder.java
new file mode 100644
index 0000000..412f323
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceBinder.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.sql.Types;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.utils.Rounder;
+
+@BindingAnnotation(BusinessInvoiceBinder.BinBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface BusinessInvoiceBinder {
+    public static class BinBinderFactory implements BinderFactory {
+        public Binder build(final Annotation annotation) {
+            return new Binder<BusinessInvoiceBinder, BusinessInvoice>() {
+                public void bind(final SQLStatement q, final BusinessInvoiceBinder bind, final BusinessInvoice invoice) {
+                    q.bind("invoice_id", invoice.getInvoiceId().toString());
+
+                    final DateTime dateTimeNow = new DateTime(DateTimeZone.UTC);
+                    if (invoice.getCreatedDate() != null) {
+                        q.bind("created_date", invoice.getCreatedDate().getMillis());
+                    } else {
+                        q.bind("created_date", dateTimeNow.getMillis());
+                    }
+
+                    if (invoice.getUpdatedDate() != null) {
+                        q.bind("updated_date", invoice.getUpdatedDate().getMillis());
+                    } else {
+                        q.bind("updated_date", dateTimeNow.getMillis());
+                    }
+
+                    q.bind("account_key", invoice.getAccountKey());
+
+                    if (invoice.getInvoiceDate() != null) {
+                        q.bind("invoice_date", invoice.getInvoiceDate().getMillis());
+                    } else {
+                        q.bindNull("invoice_date", Types.BIGINT);
+                    }
+
+                    if (invoice.getTargetDate() != null) {
+                        q.bind("target_date", invoice.getTargetDate().getMillis());
+                    } else {
+                        q.bindNull("target_date", Types.BIGINT);
+                    }
+
+                    q.bind("currency", invoice.getCurrency().toString());
+                    q.bind("balance", Rounder.round(invoice.getBalance()));
+                    q.bind("amount_paid", Rounder.round(invoice.getAmountPaid()));
+                    q.bind("amount_charged", Rounder.round(invoice.getAmountCharged()));
+                    q.bind("amount_credited", Rounder.round(invoice.getAmountCredited()));
+                }
+            };
+        }
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldMapper.java
new file mode 100644
index 0000000..d75dffc
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldMapper.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessInvoiceField;
+
+public class BusinessInvoiceFieldMapper implements ResultSetMapper<BusinessInvoiceField> {
+    @Override
+    public BusinessInvoiceField map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessInvoiceField(UUID.fromString(r.getString(1)), r.getString(2), r.getString(3));
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java
new file mode 100644
index 0000000..a6a9e18
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessInvoiceField;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessInvoiceFieldMapper.class)
+public interface BusinessInvoiceFieldSqlDao {
+    @SqlQuery
+    List<BusinessInvoiceField> getFieldsForInvoice(@Bind("invoice_id") final String invoiceId);
+
+    @SqlUpdate
+    int addField(@Bind("invoice_id") final String invoiceId, @Bind("name") final String name, @Bind("value") final String value);
+
+    @SqlUpdate
+    int removeField(@Bind("invoice_id") final String invoiceId, @Bind("name") final String name);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemBinder.java
new file mode 100644
index 0000000..7ded40e
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemBinder.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.sql.Types;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.utils.Rounder;
+
+@BindingAnnotation(BusinessInvoiceItemBinder.BiiBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface BusinessInvoiceItemBinder {
+    public static class BiiBinderFactory implements BinderFactory {
+        public Binder build(final Annotation annotation) {
+            return new Binder<BusinessInvoiceItemBinder, BusinessInvoiceItem>() {
+                public void bind(final SQLStatement q, final BusinessInvoiceItemBinder bind, final BusinessInvoiceItem invoiceItem) {
+                    q.bind("item_id", invoiceItem.getItemId().toString());
+
+                    final DateTime dateTimeNow = new DateTime(DateTimeZone.UTC);
+                    if (invoiceItem.getCreatedDate() != null) {
+                        q.bind("created_date", invoiceItem.getCreatedDate().getMillis());
+                    } else {
+                        q.bind("created_date", dateTimeNow.getMillis());
+                    }
+
+                    if (invoiceItem.getUpdatedDate() != null) {
+                        q.bind("updated_date", invoiceItem.getUpdatedDate().getMillis());
+                    } else {
+                        q.bind("updated_date", dateTimeNow.getMillis());
+                    }
+
+                    q.bind("invoice_id", invoiceItem.getInvoiceId().toString());
+                    q.bind("item_type", invoiceItem.getItemType());
+                    q.bind("external_key", invoiceItem.getExternalKey());
+                    q.bind("product_name", invoiceItem.getProductName());
+                    q.bind("product_type", invoiceItem.getProductType());
+                    q.bind("product_category", invoiceItem.getProductCategory());
+                    q.bind("slug", invoiceItem.getSlug());
+                    q.bind("phase", invoiceItem.getPhase());
+                    q.bind("billing_period", invoiceItem.getBillingPeriod());
+
+                    if (invoiceItem.getStartDate() != null) {
+                        q.bind("start_date", invoiceItem.getStartDate().getMillis());
+                    } else {
+                        q.bindNull("start_date", Types.BIGINT);
+                    }
+
+                    if (invoiceItem.getEndDate() != null) {
+                        q.bind("end_date", invoiceItem.getEndDate().getMillis());
+                    } else {
+                        q.bindNull("end_date", Types.BIGINT);
+                    }
+
+                    q.bind("amount", Rounder.round(invoiceItem.getAmount()));
+                    q.bind("currency", invoiceItem.getCurrency().toString());
+                }
+            };
+        }
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemMapper.java
new file mode 100644
index 0000000..b74f5b0
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemMapper.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.catalog.api.Currency;
+
+public class BusinessInvoiceItemMapper implements ResultSetMapper<BusinessInvoiceItem> {
+    @Override
+    public BusinessInvoiceItem map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        final UUID itemId = UUID.fromString(r.getString(1));
+        final DateTime createdDate = new DateTime(r.getLong(2), DateTimeZone.UTC);
+        final DateTime updatedDate = new DateTime(r.getLong(3), DateTimeZone.UTC);
+        final UUID invoiceId = UUID.fromString(r.getString(4));
+        final String itemType = r.getString(5);
+        final String externalKey = r.getString(6);
+        final String productName = r.getString(7);
+        final String productType = r.getString(8);
+        final String productCategory = r.getString(9);
+        final String slug = r.getString(10);
+        final String phase = r.getString(11);
+        final String billingPeriod = r.getString(12);
+        final DateTime startDate = new DateTime(r.getLong(13), DateTimeZone.UTC);
+        final DateTime endDate = new DateTime(r.getLong(14), DateTimeZone.UTC);
+        final BigDecimal amount = BigDecimal.valueOf(r.getDouble(15));
+        final Currency currency = Currency.valueOf(r.getString(16));
+
+        return new BusinessInvoiceItem(amount, billingPeriod, createdDate, currency, endDate, externalKey, invoiceId,
+                                       itemId, itemType, phase, productCategory, productName, productType, slug,
+                                       startDate, updatedDate);
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java
new file mode 100644
index 0000000..dd18e3a
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessInvoiceItem;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessInvoiceItemMapper.class)
+public interface BusinessInvoiceItemSqlDao extends Transactional<BusinessInvoiceItemSqlDao>, Transmogrifier {
+    @SqlQuery
+    BusinessInvoiceItem getInvoiceItem(@Bind("item_id") final String itemId);
+
+    @SqlQuery
+    List<BusinessInvoiceItem> getInvoiceItemsForInvoice(@Bind("invoice_id") final String invoiceId);
+
+    @SqlQuery
+    List<BusinessInvoiceItem> getInvoiceItemsForBundle(@Bind("external_key") final String externalKey);
+
+    @SqlUpdate
+    int createInvoiceItem(@BusinessInvoiceItemBinder final BusinessInvoiceItem invoiceItem);
+
+    @SqlUpdate
+    int updateInvoiceItem(@BusinessInvoiceItemBinder final BusinessInvoiceItem invoiceItem);
+
+    @SqlUpdate
+    int deleteInvoiceItem(@Bind("item_id") final String itemId);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceMapper.java
new file mode 100644
index 0000000..93d727a
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceMapper.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.catalog.api.Currency;
+
+public class BusinessInvoiceMapper implements ResultSetMapper<BusinessInvoice> {
+    @Override
+    public BusinessInvoice map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        final UUID invoiceId = UUID.fromString(r.getString(1));
+        final DateTime createdDate = new DateTime(r.getLong(2), DateTimeZone.UTC);
+        final DateTime updatedDate = new DateTime(r.getLong(3), DateTimeZone.UTC);
+        final String accountKey = r.getString(4);
+        final DateTime invoiceDate = new DateTime(r.getLong(5), DateTimeZone.UTC);
+        final DateTime targetDate = new DateTime(r.getLong(6), DateTimeZone.UTC);
+        final Currency currency = Currency.valueOf(r.getString(7));
+        final BigDecimal balance = BigDecimal.valueOf(r.getDouble(8));
+        final BigDecimal amountPaid = BigDecimal.valueOf(r.getDouble(9));
+        final BigDecimal amountCharged = BigDecimal.valueOf(r.getDouble(10));
+        final BigDecimal amountCredited = BigDecimal.valueOf(r.getDouble(11));
+
+        return new BusinessInvoice(accountKey, amountCharged, amountCredited, amountPaid, balance, createdDate, currency,
+                                   invoiceDate, invoiceId, targetDate, updatedDate);
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentBinder.java
new file mode 100644
index 0000000..8c01e8f
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentBinder.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.sql.Types;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import com.ning.billing.analytics.model.BusinessInvoicePayment;
+import com.ning.billing.analytics.utils.Rounder;
+
+@BindingAnnotation(BusinessInvoicePaymentBinder.BipBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface BusinessInvoicePaymentBinder {
+    public static class BipBinderFactory implements BinderFactory {
+        public Binder build(final Annotation annotation) {
+            return new Binder<BusinessInvoicePaymentBinder, BusinessInvoicePayment>() {
+                public void bind(final SQLStatement q, final BusinessInvoicePaymentBinder bind, final BusinessInvoicePayment invoicePayment) {
+                    q.bind("payment_id", invoicePayment.getPaymentId().toString());
+
+                    final DateTime dateTimeNow = new DateTime(DateTimeZone.UTC);
+                    if (invoicePayment.getCreatedDate() != null) {
+                        q.bind("created_date", invoicePayment.getCreatedDate().getMillis());
+                    } else {
+                        q.bind("created_date", dateTimeNow.getMillis());
+                    }
+
+                    if (invoicePayment.getUpdatedDate() != null) {
+                        q.bind("updated_date", invoicePayment.getUpdatedDate().getMillis());
+                    } else {
+                        q.bind("updated_date", dateTimeNow.getMillis());
+                    }
+
+                    q.bind("attempt_id", invoicePayment.getAttemptId().toString());
+                    q.bind("account_key", invoicePayment.getAccountKey());
+                    q.bind("invoice_id", invoicePayment.getInvoiceId().toString());
+
+                    if (invoicePayment.getEffectiveDate() != null) {
+                        q.bind("effective_date", invoicePayment.getEffectiveDate().getMillis());
+                    } else {
+                        q.bindNull("effective_date", Types.BIGINT);
+                    }
+
+                    q.bind("amount", Rounder.round(invoicePayment.getAmount()));
+                    q.bind("currency", invoicePayment.getCurrency().toString());
+                    q.bind("payment_error", invoicePayment.getPaymentError());
+                    q.bind("processing_status", invoicePayment.getProcessingStatus());
+                    q.bind("requested_amount", Rounder.round(invoicePayment.getRequestedAmount()));
+                    q.bind("plugin_name", invoicePayment.getPluginName());
+                    q.bind("payment_type", invoicePayment.getPaymentType());
+                    q.bind("payment_method", invoicePayment.getPaymentMethod());
+                    q.bind("card_type", invoicePayment.getCardType());
+                    q.bind("card_country", invoicePayment.getCardCountry());
+                }
+            };
+        }
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldMapper.java
new file mode 100644
index 0000000..ac391e1
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldMapper.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessInvoicePaymentField;
+
+public class BusinessInvoicePaymentFieldMapper implements ResultSetMapper<BusinessInvoicePaymentField> {
+    @Override
+    public BusinessInvoicePaymentField map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessInvoicePaymentField(UUID.fromString(r.getString(1)), r.getString(2), r.getString(3));
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java
new file mode 100644
index 0000000..2b85250
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessInvoicePaymentField;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessInvoicePaymentFieldMapper.class)
+public interface BusinessInvoicePaymentFieldSqlDao {
+    @SqlQuery
+    List<BusinessInvoicePaymentField> getFieldsForInvoicePayment(@Bind("payment_id") final String paymentId);
+
+    @SqlUpdate
+    int addField(@Bind("payment_id") final String paymentId, @Bind("name") final String name, @Bind("value") final String value);
+
+    @SqlUpdate
+    int removeField(@Bind("payment_id") final String paymentId, @Bind("name") final String name);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentMapper.java
new file mode 100644
index 0000000..af80d53
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentMapper.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessInvoicePayment;
+import com.ning.billing.catalog.api.Currency;
+
+public class BusinessInvoicePaymentMapper implements ResultSetMapper<BusinessInvoicePayment> {
+    @Override
+    public BusinessInvoicePayment map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        final UUID paymentId = UUID.fromString(r.getString(1));
+        final DateTime createdDate = new DateTime(r.getLong(2), DateTimeZone.UTC);
+        final DateTime updatedDate = new DateTime(r.getLong(3), DateTimeZone.UTC);
+        final UUID attemptId = UUID.fromString(r.getString(4));
+        final String accountKey = r.getString(5);
+        final UUID invoiceId = UUID.fromString(r.getString(6));
+        final DateTime effectiveDate = new DateTime(r.getLong(7), DateTimeZone.UTC);
+        final BigDecimal amount = BigDecimal.valueOf(r.getDouble(8));
+        final Currency currency = Currency.valueOf(r.getString(9));
+        final String paymentError = r.getString(10);
+        final String processingStatus = r.getString(11);
+        final BigDecimal requestedAmount = BigDecimal.valueOf(r.getDouble(12));
+        final String pluginName = r.getString(13);
+        final String paymentType = r.getString(14);
+        final String paymentMethod = r.getString(15);
+        final String cardType = r.getString(16);
+        final String cardCountry = r.getString(17);
+
+        return new BusinessInvoicePayment(accountKey, amount, attemptId, cardCountry, cardType, createdDate, currency,
+                                          effectiveDate, invoiceId, paymentError, paymentId, paymentMethod, paymentType,
+                                          pluginName, processingStatus, requestedAmount, updatedDate);
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java
new file mode 100644
index 0000000..681378d
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessInvoicePayment;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessInvoicePaymentMapper.class)
+public interface BusinessInvoicePaymentSqlDao {
+    @SqlQuery
+    BusinessInvoicePayment getInvoicePaymentForPaymentAttempt(@Bind("attempt_id") final String attemptId);
+
+    @SqlQuery
+    List<BusinessInvoicePayment> getInvoicePaymentsForPayment(@Bind("payment_id") final String paymentId);
+
+    @SqlQuery
+    List<BusinessInvoicePayment> getInvoicePaymentsForAccount(@Bind("account_key") final String accountKey);
+
+    @SqlUpdate
+    int createInvoicePayment(@BusinessInvoicePaymentBinder final BusinessInvoicePayment payment);
+
+    @SqlUpdate
+    int updateInvoicePaymentForPaymentAttempt(@BusinessInvoicePaymentBinder final BusinessInvoicePayment payment);
+
+    @SqlUpdate
+    int deleteInvoicePaymentForPaymentAttempt(@Bind("attempt_id") final String attemptId);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagMapper.java
new file mode 100644
index 0000000..c81c532
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagMapper.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessInvoicePaymentTag;
+
+public class BusinessInvoicePaymentTagMapper implements ResultSetMapper<BusinessInvoicePaymentTag> {
+    @Override
+    public BusinessInvoicePaymentTag map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessInvoicePaymentTag(UUID.fromString(r.getString(1)), r.getString(2));
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java
new file mode 100644
index 0000000..74f67b3
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessInvoicePaymentTag;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessInvoicePaymentTagMapper.class)
+public interface BusinessInvoicePaymentTagSqlDao {
+    @SqlQuery
+    List<BusinessInvoicePaymentTag> getTagsForInvoicePayment(@Bind("payment_id") final String paymentId);
+
+    @SqlUpdate
+    int addTag(@Bind("payment_id") final String paymentId, @Bind("name") final String name);
+
+    @SqlUpdate
+    int removeTag(@Bind("payment_id") final String paymentId, @Bind("name") final String name);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java
new file mode 100644
index 0000000..d3c8c6e
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessInvoice;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessInvoiceMapper.class)
+public interface BusinessInvoiceSqlDao extends Transactional<BusinessInvoiceSqlDao>, Transmogrifier {
+    @SqlQuery
+    BusinessInvoice getInvoice(@Bind("invoice_id") final String invoiceId);
+
+    @SqlQuery
+    List<BusinessInvoice> getInvoicesForAccount(@Bind("account_key") final String accountKey);
+
+    @SqlUpdate
+    int createInvoice(@BusinessInvoiceBinder final BusinessInvoice invoice);
+
+    @SqlUpdate
+    int updateInvoice(@BusinessInvoiceBinder final BusinessInvoice invoice);
+
+    @SqlUpdate
+    int deleteInvoice(@Bind("invoice_id") final String invoiceId);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagMapper.java
new file mode 100644
index 0000000..c812143
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagMapper.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessInvoiceTag;
+
+public class BusinessInvoiceTagMapper implements ResultSetMapper<BusinessInvoiceTag> {
+    @Override
+    public BusinessInvoiceTag map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessInvoiceTag(UUID.fromString(r.getString(1)), r.getString(2));
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java
new file mode 100644
index 0000000..587f45a
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessInvoiceTag;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessInvoiceTagMapper.class)
+public interface BusinessInvoiceTagSqlDao {
+    @SqlQuery
+    List<BusinessInvoiceTag> getTagsForInvoice(@Bind("invoice_id") final String invoiceId);
+
+    @SqlUpdate
+    int addTag(@Bind("invoice_id") final String invoiceId, @Bind("name") final String name);
+
+    @SqlUpdate
+    int removeTag(@Bind("invoice_id") final String invoiceId, @Bind("name") final String name);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusBinder.java
new file mode 100644
index 0000000..eb1bd9d
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusBinder.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.sql.Types;
+
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import com.ning.billing.analytics.model.BusinessOverdueStatus;
+
+@BindingAnnotation(BusinessOverdueStatusBinder.BosBinderFactory.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface BusinessOverdueStatusBinder {
+    public static class BosBinderFactory implements BinderFactory {
+        public Binder build(final Annotation annotation) {
+            return new Binder<BusinessOverdueStatusBinder, BusinessOverdueStatus>() {
+                public void bind(final SQLStatement q, final BusinessOverdueStatusBinder bind, final BusinessOverdueStatus overdueStatus) {
+                    q.bind("external_key", overdueStatus.getExternalKey());
+                    q.bind("status", overdueStatus.getStatus());
+
+                    if (overdueStatus.getStartDate() != null) {
+                        q.bind("start_date", overdueStatus.getStartDate().getMillis());
+                    } else {
+                        q.bindNull("start_date", Types.BIGINT);
+                    }
+
+                    if (overdueStatus.getEndDate() != null) {
+                        q.bind("end_date", overdueStatus.getEndDate().getMillis());
+                    } else {
+                        q.bindNull("end_date", Types.BIGINT);
+                    }
+                }
+            };
+        }
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusMapper.java
new file mode 100644
index 0000000..dcd6bf2
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusMapper.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessOverdueStatus;
+
+public class BusinessOverdueStatusMapper implements ResultSetMapper<BusinessOverdueStatus> {
+    @Override
+    public BusinessOverdueStatus map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        final String externalKey = r.getString(1);
+        final String status = r.getString(2);
+        final DateTime startDate = new DateTime(r.getLong(3), DateTimeZone.UTC);
+        final DateTime endDate = new DateTime(r.getLong(4), DateTimeZone.UTC);
+
+        return new BusinessOverdueStatus(endDate, externalKey, startDate, status);
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java
new file mode 100644
index 0000000..44668d0
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessOverdueStatus;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessOverdueStatusMapper.class)
+public interface BusinessOverdueStatusSqlDao {
+    @SqlQuery
+    List<BusinessOverdueStatus> getOverdueStatusesForBundle(@Bind("external_key") final String externalKey);
+
+    @SqlUpdate
+    int createOverdueStatus(@BusinessOverdueStatusBinder final BusinessOverdueStatus status);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
index 2a04c8e..9e5b507 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionBinder.java
@@ -28,8 +28,8 @@ import org.skife.jdbi.v2.sqlobject.Binder;
 import org.skife.jdbi.v2.sqlobject.BinderFactory;
 import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
 
-import com.ning.billing.analytics.BusinessSubscription;
-import com.ning.billing.analytics.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscription;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
 
 @BindingAnnotation(BusinessSubscriptionTransitionBinder.BstBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
@@ -39,8 +39,8 @@ public @interface BusinessSubscriptionTransitionBinder {
         public Binder build(final Annotation annotation) {
             return new Binder<BusinessSubscriptionTransitionBinder, BusinessSubscriptionTransition>() {
                 public void bind(final SQLStatement q, final BusinessSubscriptionTransitionBinder bind, final BusinessSubscriptionTransition arg) {
-                    q.bind("event_id", arg.getId().toString());
-                    q.bind("event_key", arg.getKey());
+                    q.bind("total_ordering", arg.getTotalOrdering());
+                    q.bind("external_key", arg.getExternalKey());
                     q.bind("account_key", arg.getAccountKey());
                     q.bind("requested_timestamp", arg.getRequestedTimestamp().getMillis());
                     q.bind("event", arg.getEvent().toString());
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldMapper.java
new file mode 100644
index 0000000..68ef0e2
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldMapper.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionField;
+
+public class BusinessSubscriptionTransitionFieldMapper implements ResultSetMapper<BusinessSubscriptionTransitionField> {
+    @Override
+    public BusinessSubscriptionTransitionField map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
+        return new BusinessSubscriptionTransitionField(r.getString(1), r.getString(2), r.getString(3));
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java
new file mode 100644
index 0000000..d22076e
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionField;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessSubscriptionTransitionFieldMapper.class)
+public interface BusinessSubscriptionTransitionFieldSqlDao {
+    @SqlQuery
+    List<BusinessSubscriptionTransitionField> getFieldsForBusinessSubscriptionTransition(@Bind("external_key") final String externalKey);
+
+    @SqlUpdate
+    int addField(@Bind("external_key") final String externalKey, @Bind("name") final String name, @Bind("value") final String value);
+
+    @SqlUpdate
+    int removeField(@Bind("external_key") final String externalKey, @Bind("name") final String name);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
index ac38463..c5bdf96 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
@@ -26,9 +26,9 @@ import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import com.ning.billing.analytics.BusinessSubscription;
-import com.ning.billing.analytics.BusinessSubscriptionEvent;
-import com.ning.billing.analytics.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessSubscription;
+import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
 import com.ning.billing.catalog.api.ProductCategory;
 
 import static com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
@@ -83,7 +83,7 @@ public class BusinessSubscriptionTransitionMapper implements ResultSetMapper<Bus
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.valueOf(r.getString(5));
 
         return new BusinessSubscriptionTransition(
-                UUID.fromString(r.getString(1)),
+                r.getLong(1),
                 r.getString(2),
                 r.getString(3),
                 new DateTime(r.getLong(4), DateTimeZone.UTC),
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java
new file mode 100644
index 0000000..c073a53
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
+
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionTag;
+
+@ExternalizedSqlViaStringTemplate3()
+@RegisterMapper(BusinessSubscriptionTransitionTagMapper.class)
+public interface BusinessSubscriptionTransitionTagSqlDao {
+    @SqlQuery
+    List<BusinessSubscriptionTransitionTag> getTagsForBusinessSubscriptionTransition(@Bind("external_key") final String externalKey);
+
+    @SqlUpdate
+    int addTag(@Bind("external_key") final String externalKey, @Bind("name") final String name);
+
+    @SqlUpdate
+    int removeTag(@Bind("external_key") final String externalKey, @Bind("name") final String name);
+
+    @SqlUpdate
+    void test();
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java b/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java
new file mode 100644
index 0000000..d5f8627
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/DefaultAnalyticsDao.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import javax.inject.Inject;
+import java.util.List;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
+
+import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccountTag;
+import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+
+public class DefaultAnalyticsDao implements AnalyticsDao {
+    private final BusinessAccountSqlDao accountSqlDao;
+    private final BusinessSubscriptionTransitionSqlDao subscriptionTransitionSqlDao;
+    private final BusinessInvoiceSqlDao invoiceSqlDao;
+    private final BusinessInvoiceItemSqlDao invoiceItemSqlDao;
+    private final BusinessAccountTagSqlDao accountTagSqlDao;
+
+    @Inject
+    public DefaultAnalyticsDao(final BusinessAccountSqlDao accountSqlDao,
+                               final BusinessSubscriptionTransitionSqlDao subscriptionTransitionSqlDao,
+                               final BusinessInvoiceSqlDao invoiceSqlDao,
+                               final BusinessInvoiceItemSqlDao invoiceItemSqlDao,
+                               final BusinessAccountTagSqlDao accountTagSqlDao) {
+        this.accountSqlDao = accountSqlDao;
+        this.subscriptionTransitionSqlDao = subscriptionTransitionSqlDao;
+        this.invoiceSqlDao = invoiceSqlDao;
+        this.invoiceItemSqlDao = invoiceItemSqlDao;
+        this.accountTagSqlDao = accountTagSqlDao;
+    }
+
+    @Override
+    public BusinessAccount getAccountByKey(final String accountKey) {
+        return accountSqlDao.getAccount(accountKey);
+    }
+
+    @Override
+    public List<BusinessSubscriptionTransition> getTransitionsByKey(final String externalKey) {
+        return subscriptionTransitionSqlDao.getTransitions(externalKey);
+    }
+
+    @Override
+    public List<BusinessInvoice> getInvoicesByKey(final String accountKey) {
+        return invoiceSqlDao.getInvoicesForAccount(accountKey);
+    }
+
+    @Override
+    public List<BusinessAccountTag> getTagsForAccount(final String accountKey) {
+        return accountTagSqlDao.getTagsForAccount(accountKey);
+    }
+
+    @Override
+    public List<BusinessInvoiceItem> getInvoiceItemsForInvoice(final String invoiceId) {
+        return invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId);
+    }
+
+    @Override
+    public void createInvoice(final String accountKey, final BusinessInvoice invoice, final Iterable<BusinessInvoiceItem> invoiceItems) {
+        invoiceSqlDao.inTransaction(new Transaction<Void, BusinessInvoiceSqlDao>() {
+            @Override
+            public Void inTransaction(final BusinessInvoiceSqlDao transactional, final TransactionStatus status) throws Exception {
+                // Create the invoice
+                transactional.createInvoice(invoice);
+
+                // Add associated invoice items
+                final BusinessInvoiceItemSqlDao invoiceItemSqlDao = transactional.become(BusinessInvoiceItemSqlDao.class);
+                for (final BusinessInvoiceItem invoiceItem : invoiceItems) {
+                    invoiceItemSqlDao.createInvoiceItem(invoiceItem);
+                }
+
+                // Update BAC
+                final BusinessAccountSqlDao accountSqlDao = transactional.become(BusinessAccountSqlDao.class);
+                final BusinessAccount account = accountSqlDao.getAccount(accountKey);
+                if (account == null) {
+                    throw new IllegalStateException("Account does not exist for key " + accountKey);
+                }
+                account.setBalance(account.getBalance().add(invoice.getBalance()));
+                account.setLastInvoiceDate(invoice.getInvoiceDate());
+                account.setTotalInvoiceBalance(account.getTotalInvoiceBalance().add(invoice.getBalance()));
+                account.setUpdatedDt(new DateTime(DateTimeZone.UTC));
+                accountSqlDao.saveAccount(account);
+
+                return null;
+            }
+        });
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccountField.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccountField.java
new file mode 100644
index 0000000..b990125
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccountField.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+public class BusinessAccountField extends BusinessField {
+    private final String accountKey;
+
+    public BusinessAccountField(final String accountKey, final String name, final String value) {
+        super(name, value);
+        this.accountKey = accountKey;
+    }
+
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessAccountField");
+        sb.append("{accountKey='").append(accountKey).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append(", value='").append(value).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessAccountField that = (BusinessAccountField) o;
+
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        if (value != null ? !value.equals(that.value) : that.value != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = accountKey != null ? accountKey.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (value != null ? value.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccountTag.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccountTag.java
new file mode 100644
index 0000000..3a8de99
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessAccountTag.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+public class BusinessAccountTag extends BusinessTag {
+    private final String accountKey;
+
+    public BusinessAccountTag(final String accountKey, final String name) {
+        super(name);
+        this.accountKey = accountKey;
+    }
+
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessAccountTag");
+        sb.append("{accountKey='").append(accountKey).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessAccountTag that = (BusinessAccountTag) o;
+
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = accountKey != null ? accountKey.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessField.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessField.java
new file mode 100644
index 0000000..68552d0
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessField.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+public abstract class BusinessField {
+    protected final String name;
+    protected final String value;
+
+    public BusinessField(final String name, final String value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoice.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoice.java
new file mode 100644
index 0000000..31591c6
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoice.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import com.ning.billing.analytics.utils.Rounder;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.api.Invoice;
+
+public class BusinessInvoice {
+    private final UUID invoiceId;
+    private final DateTime createdDate;
+
+    private DateTime updatedDate;
+    private String accountKey;
+    private DateTime invoiceDate;
+    private DateTime targetDate;
+    private Currency currency;
+    private BigDecimal balance;
+    private BigDecimal amountPaid;
+    private BigDecimal amountCharged;
+    private BigDecimal amountCredited;
+
+    public BusinessInvoice(final String accountKey, final BigDecimal amountCharged, final BigDecimal amountCredited,
+                           final BigDecimal amountPaid, final BigDecimal balance, final DateTime createdDate,
+                           final Currency currency, final DateTime invoiceDate, final UUID invoiceId,
+                           final DateTime targetDate, final DateTime updatedDate) {
+        this.accountKey = accountKey;
+        this.amountCharged = amountCharged;
+        this.amountCredited = amountCredited;
+        this.amountPaid = amountPaid;
+        this.balance = balance;
+        this.createdDate = createdDate;
+        this.currency = currency;
+        this.invoiceDate = invoiceDate;
+        this.invoiceId = invoiceId;
+        this.targetDate = targetDate;
+        this.updatedDate = updatedDate;
+    }
+
+    public BusinessInvoice(final String accountKey, final Invoice invoice) {
+        this(accountKey, invoice.getAmountCharged(), invoice.getAmountCredited(), invoice.getAmountPaid(), invoice.getBalance(),
+             new DateTime(DateTimeZone.UTC), invoice.getCurrency(), invoice.getInvoiceDate(), invoice.getId(), invoice.getTargetDate(),
+             new DateTime(DateTimeZone.UTC));
+    }
+
+    public DateTime getCreatedDate() {
+        return createdDate;
+    }
+
+    public UUID getInvoiceId() {
+        return invoiceId;
+    }
+
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    public void setAccountKey(final String accountKey) {
+        this.accountKey = accountKey;
+    }
+
+    public BigDecimal getAmountCharged() {
+        return amountCharged;
+    }
+
+    public void setAmountCharged(final BigDecimal amountCharged) {
+        this.amountCharged = amountCharged;
+    }
+
+    public BigDecimal getAmountCredited() {
+        return amountCredited;
+    }
+
+    public void setAmountCredited(final BigDecimal amountCredited) {
+        this.amountCredited = amountCredited;
+    }
+
+    public BigDecimal getAmountPaid() {
+        return amountPaid;
+    }
+
+    public void setAmountPaid(final BigDecimal amountPaid) {
+        this.amountPaid = amountPaid;
+    }
+
+    public BigDecimal getBalance() {
+        return balance;
+    }
+
+    public void setBalance(final BigDecimal balance) {
+        this.balance = balance;
+    }
+
+    public Currency getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(final Currency currency) {
+        this.currency = currency;
+    }
+
+    public DateTime getInvoiceDate() {
+        return invoiceDate;
+    }
+
+    public void setInvoiceDate(final DateTime invoiceDate) {
+        this.invoiceDate = invoiceDate;
+    }
+
+    public DateTime getTargetDate() {
+        return targetDate;
+    }
+
+    public void setTargetDate(final DateTime targetDate) {
+        this.targetDate = targetDate;
+    }
+
+    public DateTime getUpdatedDate() {
+        return updatedDate;
+    }
+
+    public void setUpdatedDate(final DateTime updatedDate) {
+        this.updatedDate = updatedDate;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessInvoice");
+        sb.append("{accountKey='").append(accountKey).append('\'');
+        sb.append(", invoiceId=").append(invoiceId);
+        sb.append(", createdDate=").append(createdDate);
+        sb.append(", updatedDate=").append(updatedDate);
+        sb.append(", invoiceDate=").append(invoiceDate);
+        sb.append(", targetDate=").append(targetDate);
+        sb.append(", currency=").append(currency);
+        sb.append(", balance=").append(balance);
+        sb.append(", amountPaid=").append(amountPaid);
+        sb.append(", amountCharged=").append(amountCharged);
+        sb.append(", amountCredited=").append(amountCredited);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessInvoice that = (BusinessInvoice) o;
+
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (amountCharged != null ? Rounder.round(amountCharged) != Rounder.round(that.amountCharged) : that.amountCharged != null) {
+            return false;
+        }
+        if (amountCredited != null ? Rounder.round(amountCredited) != Rounder.round(that.amountCredited) : that.amountCredited != null) {
+            return false;
+        }
+        if (amountPaid != null ? Rounder.round(amountPaid) != Rounder.round(that.amountPaid) : that.amountPaid != null) {
+            return false;
+        }
+        if (balance != null ? Rounder.round(balance) != Rounder.round(that.balance) : that.balance != null) {
+            return false;
+        }
+        if (createdDate != null ? !createdDate.equals(that.createdDate) : that.createdDate != null) {
+            return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (invoiceDate != null ? !invoiceDate.equals(that.invoiceDate) : that.invoiceDate != null) {
+            return false;
+        }
+        if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
+            return false;
+        }
+        if (targetDate != null ? !targetDate.equals(that.targetDate) : that.targetDate != null) {
+            return false;
+        }
+        if (updatedDate != null ? !updatedDate.equals(that.updatedDate) : that.updatedDate != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = invoiceId != null ? invoiceId.hashCode() : 0;
+        result = 31 * result + (createdDate != null ? createdDate.hashCode() : 0);
+        result = 31 * result + (updatedDate != null ? updatedDate.hashCode() : 0);
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
+        result = 31 * result + (invoiceDate != null ? invoiceDate.hashCode() : 0);
+        result = 31 * result + (targetDate != null ? targetDate.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (balance != null ? balance.hashCode() : 0);
+        result = 31 * result + (amountPaid != null ? amountPaid.hashCode() : 0);
+        result = 31 * result + (amountCharged != null ? amountCharged.hashCode() : 0);
+        result = 31 * result + (amountCredited != null ? amountCredited.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceField.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceField.java
new file mode 100644
index 0000000..cf69497
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceField.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+public class BusinessInvoiceField extends BusinessField {
+    private final UUID invoiceId;
+
+    public BusinessInvoiceField(final UUID invoiceId, final String name, final String value) {
+        super(name, value);
+        this.invoiceId = invoiceId;
+    }
+
+    public UUID getInvoiceId() {
+        return invoiceId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessInvoiceField");
+        sb.append("{invoiceId='").append(invoiceId).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append(", value='").append(value).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessInvoiceField that = (BusinessInvoiceField) o;
+
+        if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        if (value != null ? !value.equals(that.value) : that.value != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = invoiceId != null ? invoiceId.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (value != null ? value.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceItem.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceItem.java
new file mode 100644
index 0000000..03cb50c
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceItem.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import com.ning.billing.analytics.utils.Rounder;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.invoice.api.InvoiceItem;
+
+public class BusinessInvoiceItem {
+    private final UUID itemId;
+    private final DateTime createdDate;
+
+    private DateTime updatedDate;
+    private UUID invoiceId;
+    private String itemType;
+    private String externalKey;
+    private String productName;
+    private String productType;
+    private String productCategory;
+    private String slug;
+    private String phase;
+    private String billingPeriod;
+    private DateTime startDate;
+    private DateTime endDate;
+    private BigDecimal amount;
+    private Currency currency;
+
+    public BusinessInvoiceItem(final BigDecimal amount, final String billingPeriod, final DateTime createdDate,
+                               final Currency currency, final DateTime endDate, final String externalKey,
+                               final UUID invoiceId, final UUID itemId, final String itemType, final String phase,
+                               final String productCategory, final String productName, final String productType,
+                               final String slug, final DateTime startDate, final DateTime updatedDate) {
+        this.amount = amount;
+        this.billingPeriod = billingPeriod;
+        this.createdDate = createdDate;
+        this.currency = currency;
+        this.endDate = endDate;
+        this.externalKey = externalKey;
+        this.invoiceId = invoiceId;
+        this.itemId = itemId;
+        this.itemType = itemType;
+        this.phase = phase;
+        this.productCategory = productCategory;
+        this.productName = productName;
+        this.productType = productType;
+        this.slug = slug;
+        this.startDate = startDate;
+        this.updatedDate = updatedDate;
+    }
+
+    public BusinessInvoiceItem(final String externalKey, final InvoiceItem invoiceItem, final Plan plan, final PlanPhase planPhase) {
+        this(invoiceItem.getAmount(), planPhase.getBillingPeriod().toString(), new DateTime(DateTimeZone.UTC), invoiceItem.getCurrency(), invoiceItem.getEndDate(),
+             externalKey, invoiceItem.getInvoiceId(), invoiceItem.getId(), invoiceItem.getInvoiceItemType().toString(),
+             planPhase.getPhaseType().toString(), plan.getProduct().getCategory().toString(), plan.getProduct().getName(), plan.getProduct().getCatalogName(),
+             planPhase.getName(), invoiceItem.getStartDate(), new DateTime(DateTimeZone.UTC));
+    }
+
+    public DateTime getCreatedDate() {
+        return createdDate;
+    }
+
+    public UUID getItemId() {
+        return itemId;
+    }
+
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    public void setAmount(final BigDecimal amount) {
+        this.amount = amount;
+    }
+
+    public String getBillingPeriod() {
+        return billingPeriod;
+    }
+
+    public void setBillingPeriod(final String billingPeriod) {
+        this.billingPeriod = billingPeriod;
+    }
+
+    public Currency getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(final Currency currency) {
+        this.currency = currency;
+    }
+
+    public DateTime getEndDate() {
+        return endDate;
+    }
+
+    public void setEndDate(final DateTime endDate) {
+        this.endDate = endDate;
+    }
+
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    public void setExternalKey(final String externalKey) {
+        this.externalKey = externalKey;
+    }
+
+    public UUID getInvoiceId() {
+        return invoiceId;
+    }
+
+    public void setInvoiceId(final UUID invoiceId) {
+        this.invoiceId = invoiceId;
+    }
+
+    public String getItemType() {
+        return itemType;
+    }
+
+    public void setItemType(final String itemType) {
+        this.itemType = itemType;
+    }
+
+    public String getPhase() {
+        return phase;
+    }
+
+    public void setPhase(final String phase) {
+        this.phase = phase;
+    }
+
+    public String getProductCategory() {
+        return productCategory;
+    }
+
+    public void setProductCategory(final String productCategory) {
+        this.productCategory = productCategory;
+    }
+
+    public String getProductName() {
+        return productName;
+    }
+
+    public void setProductName(final String productName) {
+        this.productName = productName;
+    }
+
+    public String getProductType() {
+        return productType;
+    }
+
+    public void setProductType(final String productType) {
+        this.productType = productType;
+    }
+
+    public String getSlug() {
+        return slug;
+    }
+
+    public void setSlug(final String slug) {
+        this.slug = slug;
+    }
+
+    public DateTime getStartDate() {
+        return startDate;
+    }
+
+    public void setStartDate(final DateTime startDate) {
+        this.startDate = startDate;
+    }
+
+    public DateTime getUpdatedDate() {
+        return updatedDate;
+    }
+
+    public void setUpdatedDate(final DateTime updatedDate) {
+        this.updatedDate = updatedDate;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessInvoiceItem");
+        sb.append("{amount=").append(amount);
+        sb.append(", itemId=").append(itemId);
+        sb.append(", createdDate=").append(createdDate);
+        sb.append(", updatedDate=").append(updatedDate);
+        sb.append(", invoiceId=").append(invoiceId);
+        sb.append(", itemType='").append(itemType).append('\'');
+        sb.append(", externalKey='").append(externalKey).append('\'');
+        sb.append(", productName='").append(productName).append('\'');
+        sb.append(", productType='").append(productType).append('\'');
+        sb.append(", productCategory='").append(productCategory).append('\'');
+        sb.append(", slug='").append(slug).append('\'');
+        sb.append(", phase='").append(phase).append('\'');
+        sb.append(", billingPeriod='").append(billingPeriod).append('\'');
+        sb.append(", startDate=").append(startDate);
+        sb.append(", endDate=").append(endDate);
+        sb.append(", currency=").append(currency);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessInvoiceItem that = (BusinessInvoiceItem) o;
+
+        if (amount != null ? Rounder.round(amount) != (Rounder.round(that.amount)) : that.amount != null) {
+            return false;
+        }
+        if (billingPeriod != null ? !billingPeriod.equals(that.billingPeriod) : that.billingPeriod != null) {
+            return false;
+        }
+        if (createdDate != null ? !createdDate.equals(that.createdDate) : that.createdDate != null) {
+            return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (endDate != null ? !endDate.equals(that.endDate) : that.endDate != null) {
+            return false;
+        }
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+            return false;
+        }
+        if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
+            return false;
+        }
+        if (itemId != null ? !itemId.equals(that.itemId) : that.itemId != null) {
+            return false;
+        }
+        if (itemType != null ? !itemType.equals(that.itemType) : that.itemType != null) {
+            return false;
+        }
+        if (phase != null ? !phase.equals(that.phase) : that.phase != null) {
+            return false;
+        }
+        if (productCategory != null ? !productCategory.equals(that.productCategory) : that.productCategory != null) {
+            return false;
+        }
+        if (productName != null ? !productName.equals(that.productName) : that.productName != null) {
+            return false;
+        }
+        if (productType != null ? !productType.equals(that.productType) : that.productType != null) {
+            return false;
+        }
+        if (slug != null ? !slug.equals(that.slug) : that.slug != null) {
+            return false;
+        }
+        if (startDate != null ? !startDate.equals(that.startDate) : that.startDate != null) {
+            return false;
+        }
+        if (updatedDate != null ? !updatedDate.equals(that.updatedDate) : that.updatedDate != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = itemId != null ? itemId.hashCode() : 0;
+        result = 31 * result + (createdDate != null ? createdDate.hashCode() : 0);
+        result = 31 * result + (updatedDate != null ? updatedDate.hashCode() : 0);
+        result = 31 * result + (invoiceId != null ? invoiceId.hashCode() : 0);
+        result = 31 * result + (itemType != null ? itemType.hashCode() : 0);
+        result = 31 * result + (externalKey != null ? externalKey.hashCode() : 0);
+        result = 31 * result + (productName != null ? productName.hashCode() : 0);
+        result = 31 * result + (productType != null ? productType.hashCode() : 0);
+        result = 31 * result + (productCategory != null ? productCategory.hashCode() : 0);
+        result = 31 * result + (slug != null ? slug.hashCode() : 0);
+        result = 31 * result + (phase != null ? phase.hashCode() : 0);
+        result = 31 * result + (billingPeriod != null ? billingPeriod.hashCode() : 0);
+        result = 31 * result + (startDate != null ? startDate.hashCode() : 0);
+        result = 31 * result + (endDate != null ? endDate.hashCode() : 0);
+        result = 31 * result + (amount != null ? amount.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePayment.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePayment.java
new file mode 100644
index 0000000..2622437
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePayment.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.analytics.utils.Rounder;
+import com.ning.billing.catalog.api.Currency;
+
+public class BusinessInvoicePayment {
+    private final UUID paymentId;
+    private final DateTime createdDate;
+    private final UUID attemptId;
+
+    private DateTime updatedDate;
+    private String accountKey;
+    private UUID invoiceId;
+    private DateTime effectiveDate;
+    private BigDecimal amount;
+    private Currency currency;
+    private String paymentError;
+    private String processingStatus;
+    private BigDecimal requestedAmount;
+    private String pluginName;
+    private String paymentType;
+    private String paymentMethod;
+    private String cardType;
+    private String cardCountry;
+
+    public BusinessInvoicePayment(final String accountKey, final BigDecimal amount, final UUID attemptId,
+                                  final String cardCountry, final String cardType, final DateTime createdDate,
+                                  final Currency currency, final DateTime effectiveDate, final UUID invoiceId,
+                                  final String paymentError, final UUID paymentId, final String paymentMethod,
+                                  final String paymentType, final String pluginName, final String processingStatus,
+                                  final BigDecimal requestedAmount, final DateTime updatedDate) {
+        this.accountKey = accountKey;
+        this.amount = amount;
+        this.attemptId = attemptId;
+        this.cardCountry = cardCountry;
+        this.cardType = cardType;
+        this.createdDate = createdDate;
+        this.currency = currency;
+        this.effectiveDate = effectiveDate;
+        this.invoiceId = invoiceId;
+        this.paymentError = paymentError;
+        this.paymentId = paymentId;
+        this.paymentMethod = paymentMethod;
+        this.paymentType = paymentType;
+        this.pluginName = pluginName;
+        this.processingStatus = processingStatus;
+        this.requestedAmount = requestedAmount;
+        this.updatedDate = updatedDate;
+    }
+
+    public UUID getAttemptId() {
+        return attemptId;
+    }
+
+    public DateTime getCreatedDate() {
+        return createdDate;
+    }
+
+    public UUID getPaymentId() {
+        return paymentId;
+    }
+
+    public String getAccountKey() {
+        return accountKey;
+    }
+
+    public void setAccountKey(final String accountKey) {
+        this.accountKey = accountKey;
+    }
+
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    public void setAmount(final BigDecimal amount) {
+        this.amount = amount;
+    }
+
+    public String getCardCountry() {
+        return cardCountry;
+    }
+
+    public void setCardCountry(final String cardCountry) {
+        this.cardCountry = cardCountry;
+    }
+
+    public String getCardType() {
+        return cardType;
+    }
+
+    public void setCardType(final String cardType) {
+        this.cardType = cardType;
+    }
+
+    public Currency getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(final Currency currency) {
+        this.currency = currency;
+    }
+
+    public DateTime getEffectiveDate() {
+        return effectiveDate;
+    }
+
+    public void setEffectiveDate(final DateTime effectiveDate) {
+        this.effectiveDate = effectiveDate;
+    }
+
+    public UUID getInvoiceId() {
+        return invoiceId;
+    }
+
+    public void setInvoiceId(final UUID invoiceId) {
+        this.invoiceId = invoiceId;
+    }
+
+    public String getPaymentError() {
+        return paymentError;
+    }
+
+    public void setPaymentError(final String paymentError) {
+        this.paymentError = paymentError;
+    }
+
+    public String getPaymentMethod() {
+        return paymentMethod;
+    }
+
+    public void setPaymentMethod(final String paymentMethod) {
+        this.paymentMethod = paymentMethod;
+    }
+
+    public String getPaymentType() {
+        return paymentType;
+    }
+
+    public void setPaymentType(final String paymentType) {
+        this.paymentType = paymentType;
+    }
+
+    public String getPluginName() {
+        return pluginName;
+    }
+
+    public void setPluginName(final String pluginName) {
+        this.pluginName = pluginName;
+    }
+
+    public String getProcessingStatus() {
+        return processingStatus;
+    }
+
+    public void setProcessingStatus(final String processingStatus) {
+        this.processingStatus = processingStatus;
+    }
+
+    public BigDecimal getRequestedAmount() {
+        return requestedAmount;
+    }
+
+    public void setRequestedAmount(final BigDecimal requestedAmount) {
+        this.requestedAmount = requestedAmount;
+    }
+
+    public DateTime getUpdatedDate() {
+        return updatedDate;
+    }
+
+    public void setUpdatedDate(final DateTime updatedDate) {
+        this.updatedDate = updatedDate;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessInvoicePayment");
+        sb.append("{accountKey='").append(accountKey).append('\'');
+        sb.append(", paymentId=").append(paymentId);
+        sb.append(", createdDate=").append(createdDate);
+        sb.append(", attemptId=").append(attemptId);
+        sb.append(", updatedDate=").append(updatedDate);
+        sb.append(", invoiceId=").append(invoiceId);
+        sb.append(", effectiveDate=").append(effectiveDate);
+        sb.append(", amount=").append(amount);
+        sb.append(", currency=").append(currency);
+        sb.append(", paymentError='").append(paymentError).append('\'');
+        sb.append(", processingStatus='").append(processingStatus).append('\'');
+        sb.append(", requestedAmount=").append(requestedAmount);
+        sb.append(", pluginName='").append(pluginName).append('\'');
+        sb.append(", paymentType='").append(paymentType).append('\'');
+        sb.append(", paymentMethod='").append(paymentMethod).append('\'');
+        sb.append(", cardType='").append(cardType).append('\'');
+        sb.append(", cardCountry='").append(cardCountry).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessInvoicePayment that = (BusinessInvoicePayment) o;
+
+        if (accountKey != null ? !accountKey.equals(that.accountKey) : that.accountKey != null) {
+            return false;
+        }
+        if (amount != null ? Rounder.round(amount) != Rounder.round(that.amount) : that.amount != null) {
+            return false;
+        }
+        if (attemptId != null ? !attemptId.equals(that.attemptId) : that.attemptId != null) {
+            return false;
+        }
+        if (cardCountry != null ? !cardCountry.equals(that.cardCountry) : that.cardCountry != null) {
+            return false;
+        }
+        if (cardType != null ? !cardType.equals(that.cardType) : that.cardType != null) {
+            return false;
+        }
+        if (createdDate != null ? !createdDate.equals(that.createdDate) : that.createdDate != null) {
+            return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (effectiveDate != null ? !effectiveDate.equals(that.effectiveDate) : that.effectiveDate != null) {
+            return false;
+        }
+        if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
+            return false;
+        }
+        if (paymentError != null ? !paymentError.equals(that.paymentError) : that.paymentError != null) {
+            return false;
+        }
+        if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
+            return false;
+        }
+        if (paymentMethod != null ? !paymentMethod.equals(that.paymentMethod) : that.paymentMethod != null) {
+            return false;
+        }
+        if (paymentType != null ? !paymentType.equals(that.paymentType) : that.paymentType != null) {
+            return false;
+        }
+        if (pluginName != null ? !pluginName.equals(that.pluginName) : that.pluginName != null) {
+            return false;
+        }
+        if (processingStatus != null ? !processingStatus.equals(that.processingStatus) : that.processingStatus != null) {
+            return false;
+        }
+        if (requestedAmount != null ? Rounder.round(requestedAmount) != Rounder.round(that.requestedAmount) : that.requestedAmount != null) {
+            return false;
+        }
+        if (updatedDate != null ? !updatedDate.equals(that.updatedDate) : that.updatedDate != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = paymentId != null ? paymentId.hashCode() : 0;
+        result = 31 * result + (createdDate != null ? createdDate.hashCode() : 0);
+        result = 31 * result + (attemptId != null ? attemptId.hashCode() : 0);
+        result = 31 * result + (updatedDate != null ? updatedDate.hashCode() : 0);
+        result = 31 * result + (accountKey != null ? accountKey.hashCode() : 0);
+        result = 31 * result + (invoiceId != null ? invoiceId.hashCode() : 0);
+        result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
+        result = 31 * result + (amount != null ? amount.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        result = 31 * result + (paymentError != null ? paymentError.hashCode() : 0);
+        result = 31 * result + (processingStatus != null ? processingStatus.hashCode() : 0);
+        result = 31 * result + (requestedAmount != null ? requestedAmount.hashCode() : 0);
+        result = 31 * result + (pluginName != null ? pluginName.hashCode() : 0);
+        result = 31 * result + (paymentType != null ? paymentType.hashCode() : 0);
+        result = 31 * result + (paymentMethod != null ? paymentMethod.hashCode() : 0);
+        result = 31 * result + (cardType != null ? cardType.hashCode() : 0);
+        result = 31 * result + (cardCountry != null ? cardCountry.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePaymentField.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePaymentField.java
new file mode 100644
index 0000000..bcfc85b
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePaymentField.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+public class BusinessInvoicePaymentField extends BusinessField {
+    private final UUID paymentId;
+
+    public BusinessInvoicePaymentField(final UUID paymentId, final String name, final String value) {
+        super(name, value);
+        this.paymentId = paymentId;
+    }
+
+    public UUID getPaymentId() {
+        return paymentId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessPaymentField");
+        sb.append("{paymentId='").append(paymentId).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append(", value='").append(value).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessInvoicePaymentField that = (BusinessInvoicePaymentField) o;
+
+        if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        if (value != null ? !value.equals(that.value) : that.value != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = paymentId != null ? paymentId.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (value != null ? value.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePaymentTag.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePaymentTag.java
new file mode 100644
index 0000000..fd48b1c
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoicePaymentTag.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+public class BusinessInvoicePaymentTag extends BusinessTag {
+    private final UUID paymentId;
+
+    public BusinessInvoicePaymentTag(final UUID paymentId, final String name) {
+        super(name);
+        this.paymentId = paymentId;
+    }
+
+    public UUID getPaymentId() {
+        return paymentId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessPaymentTag");
+        sb.append("{paymentId='").append(paymentId).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessInvoicePaymentTag that = (BusinessInvoicePaymentTag) o;
+
+        if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = paymentId != null ? paymentId.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceTag.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceTag.java
new file mode 100644
index 0000000..e9efe5a
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessInvoiceTag.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+public class BusinessInvoiceTag extends BusinessTag {
+    private final UUID invoiceId;
+
+    public BusinessInvoiceTag(final UUID invoiceId, final String name) {
+        super(name);
+        this.invoiceId = invoiceId;
+    }
+
+    public UUID getInvoiceId() {
+        return invoiceId;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessInvoiceTag");
+        sb.append("{paymentId='").append(invoiceId).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessInvoiceTag that = (BusinessInvoiceTag) o;
+
+        if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = invoiceId != null ? invoiceId.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessOverdueStatus.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessOverdueStatus.java
new file mode 100644
index 0000000..dd8a310
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessOverdueStatus.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import org.joda.time.DateTime;
+
+public class BusinessOverdueStatus {
+    private final String externalKey;
+    private final String status;
+    private final DateTime startDate;
+    private final DateTime endDate;
+
+    public BusinessOverdueStatus(final DateTime endDate, final String externalKey, final DateTime startDate, final String status) {
+        this.endDate = endDate;
+        this.externalKey = externalKey;
+        this.startDate = startDate;
+        this.status = status;
+    }
+
+    public DateTime getEndDate() {
+        return endDate;
+    }
+
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    public DateTime getStartDate() {
+        return startDate;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessOverdueStatus");
+        sb.append("{endDate=").append(endDate);
+        sb.append(", externalKey='").append(externalKey).append('\'');
+        sb.append(", status='").append(status).append('\'');
+        sb.append(", startDate=").append(startDate);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessOverdueStatus that = (BusinessOverdueStatus) o;
+
+        if (endDate != null ? !endDate.equals(that.endDate) : that.endDate != null) {
+            return false;
+        }
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+            return false;
+        }
+        if (startDate != null ? !startDate.equals(that.startDate) : that.startDate != null) {
+            return false;
+        }
+        if (status != null ? !status.equals(that.status) : that.status != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = externalKey != null ? externalKey.hashCode() : 0;
+        result = 31 * result + (status != null ? status.hashCode() : 0);
+        result = 31 * result + (startDate != null ? startDate.hashCode() : 0);
+        result = 31 * result + (endDate != null ? endDate.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscriptionTransitionField.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscriptionTransitionField.java
new file mode 100644
index 0000000..bab1259
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscriptionTransitionField.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+public class BusinessSubscriptionTransitionField extends BusinessField {
+    private final String externalKey;
+
+    public BusinessSubscriptionTransitionField(final String externalKey, final String name, final String value) {
+        super(name, value);
+        this.externalKey = externalKey;
+    }
+
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessSubscriptionTransitionField");
+        sb.append("{externalKey='").append(externalKey).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append(", value='").append(value).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessSubscriptionTransitionField that = (BusinessSubscriptionTransitionField) o;
+
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        if (value != null ? !value.equals(that.value) : that.value != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = externalKey != null ? externalKey.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (value != null ? value.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscriptionTransitionTag.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscriptionTransitionTag.java
new file mode 100644
index 0000000..522194a
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessSubscriptionTransitionTag.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+public class BusinessSubscriptionTransitionTag extends BusinessTag {
+    private final String externalKey;
+
+    public BusinessSubscriptionTransitionTag(final String externalKey, final String name) {
+        super(name);
+        this.externalKey = externalKey;
+    }
+
+    public String getExternalKey() {
+        return externalKey;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("BusinessSubscriptionTransitionTag");
+        sb.append("{externalKey='").append(externalKey).append('\'');
+        sb.append(", name='").append(name).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final BusinessSubscriptionTransitionTag that = (BusinessSubscriptionTransitionTag) o;
+
+        if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = externalKey != null ? externalKey.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/model/BusinessTag.java b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessTag.java
new file mode 100644
index 0000000..80343e1
--- /dev/null
+++ b/analytics/src/main/java/com/ning/billing/analytics/model/BusinessTag.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+public abstract class BusinessTag {
+    protected final String name;
+
+    public BusinessTag(final String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
diff --git a/analytics/src/main/java/com/ning/billing/analytics/setup/AnalyticsModule.java b/analytics/src/main/java/com/ning/billing/analytics/setup/AnalyticsModule.java
index 2233e1e..82433ec 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/setup/AnalyticsModule.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/setup/AnalyticsModule.java
@@ -21,23 +21,52 @@ import com.google.inject.AbstractModule;
 import com.ning.billing.analytics.AnalyticsListener;
 import com.ning.billing.analytics.BusinessAccountRecorder;
 import com.ning.billing.analytics.BusinessSubscriptionTransitionRecorder;
+import com.ning.billing.analytics.BusinessTagRecorder;
 import com.ning.billing.analytics.api.AnalyticsService;
 import com.ning.billing.analytics.api.DefaultAnalyticsService;
-import com.ning.billing.analytics.dao.BusinessAccountDao;
-import com.ning.billing.analytics.dao.BusinessAccountDaoProvider;
-import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionDao;
-import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionDaoProvider;
+import com.ning.billing.analytics.api.user.DefaultAnalyticsUserApi;
+import com.ning.billing.analytics.dao.AnalyticsDao;
+import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
+import com.ning.billing.analytics.dao.BusinessAccountTagSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoiceFieldSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoiceItemSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoicePaymentFieldSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoicePaymentSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoicePaymentTagSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoiceSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoiceTagSqlDao;
+import com.ning.billing.analytics.dao.BusinessOverdueStatusSqlDao;
+import com.ning.billing.analytics.dao.BusinessSqlProvider;
+import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionFieldSqlDao;
+import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
+import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionTagSqlDao;
+import com.ning.billing.analytics.dao.DefaultAnalyticsDao;
 
 public class AnalyticsModule extends AbstractModule {
     @Override
     protected void configure() {
-        bind(BusinessSubscriptionTransitionDao.class).toProvider(BusinessSubscriptionTransitionDaoProvider.class).asEagerSingleton();
-        bind(BusinessAccountDao.class).toProvider(BusinessAccountDaoProvider.class).asEagerSingleton();
+        bind(BusinessAccountSqlDao.class).toProvider(new BusinessSqlProvider<BusinessAccountSqlDao>(BusinessAccountSqlDao.class));
+        bind(BusinessAccountTagSqlDao.class).toProvider(new BusinessSqlProvider<BusinessAccountTagSqlDao>(BusinessAccountTagSqlDao.class));
+        bind(BusinessInvoiceFieldSqlDao.class).toProvider(new BusinessSqlProvider<BusinessInvoiceFieldSqlDao>(BusinessInvoiceFieldSqlDao.class));
+        bind(BusinessInvoiceItemSqlDao.class).toProvider(new BusinessSqlProvider<BusinessInvoiceItemSqlDao>(BusinessInvoiceItemSqlDao.class));
+        bind(BusinessInvoicePaymentFieldSqlDao.class).toProvider(new BusinessSqlProvider<BusinessInvoicePaymentFieldSqlDao>(BusinessInvoicePaymentFieldSqlDao.class));
+        bind(BusinessInvoicePaymentSqlDao.class).toProvider(new BusinessSqlProvider<BusinessInvoicePaymentSqlDao>(BusinessInvoicePaymentSqlDao.class));
+        bind(BusinessInvoicePaymentTagSqlDao.class).toProvider(new BusinessSqlProvider<BusinessInvoicePaymentTagSqlDao>(BusinessInvoicePaymentTagSqlDao.class));
+        bind(BusinessInvoiceSqlDao.class).toProvider(new BusinessSqlProvider<BusinessInvoiceSqlDao>(BusinessInvoiceSqlDao.class));
+        bind(BusinessInvoiceTagSqlDao.class).toProvider(new BusinessSqlProvider<BusinessInvoiceTagSqlDao>(BusinessInvoiceTagSqlDao.class));
+        bind(BusinessOverdueStatusSqlDao.class).toProvider(new BusinessSqlProvider<BusinessOverdueStatusSqlDao>(BusinessOverdueStatusSqlDao.class));
+        bind(BusinessSubscriptionTransitionFieldSqlDao.class).toProvider(new BusinessSqlProvider<BusinessSubscriptionTransitionFieldSqlDao>(BusinessSubscriptionTransitionFieldSqlDao.class));
+        bind(BusinessSubscriptionTransitionSqlDao.class).toProvider(new BusinessSqlProvider<BusinessSubscriptionTransitionSqlDao>(BusinessSubscriptionTransitionSqlDao.class));
+        bind(BusinessSubscriptionTransitionTagSqlDao.class).toProvider(new BusinessSqlProvider<BusinessSubscriptionTransitionTagSqlDao>(BusinessSubscriptionTransitionTagSqlDao.class));
 
         bind(BusinessSubscriptionTransitionRecorder.class).asEagerSingleton();
         bind(BusinessAccountRecorder.class).asEagerSingleton();
+        bind(BusinessTagRecorder.class).asEagerSingleton();
         bind(AnalyticsListener.class).asEagerSingleton();
 
+        bind(AnalyticsDao.class).to(DefaultAnalyticsDao.class).asEagerSingleton();
         bind(AnalyticsService.class).to(DefaultAnalyticsService.class).asEagerSingleton();
+
+        bind(DefaultAnalyticsUserApi.class).asEagerSingleton();
     }
 }
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.sql.stg
new file mode 100644
index 0000000..8bb9e0b
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountFieldSqlDao.sql.stg
@@ -0,0 +1,31 @@
+group BusinessAccountField;
+
+getFieldsForAccount(account_key) ::=<<
+select
+  account_key
+, name
+, value
+from bac_fields
+where account_key = :account_key
+;
+>>
+
+addField(account_key, name, value) ::=<<
+insert into bac_fields (
+  account_key
+, name
+, value
+) values (
+  :account_key
+, :name
+, :value
+);
+>>
+
+removeField(account_key, name) ::= <<
+delete from bac_fields where account_key = :account_key and name = :name;
+>>
+
+test() ::= <<
+select 1 from bac_fields;
+>>
\ No newline at end of file
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.sql.stg
new file mode 100644
index 0000000..af34473
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessAccountTagSqlDao.sql.stg
@@ -0,0 +1,28 @@
+group BusinessAccountTag;
+
+getTagsForAccount(account_key) ::=<<
+select
+  account_key
+, name
+from bac_tags
+where account_key = :account_key
+;
+>>
+
+addTag(account_key, name) ::=<<
+insert into bac_tags (
+  account_key
+, name
+) values (
+  :account_key
+, :name
+);
+>>
+
+removeTag(account_key, name) ::= <<
+delete from bac_tags where account_key = :account_key and name = :name;
+>>
+
+test() ::= <<
+select 1 from bac_tags;
+>>
\ No newline at end of file
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.sql.stg
new file mode 100644
index 0000000..fe0080f
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceFieldSqlDao.sql.stg
@@ -0,0 +1,31 @@
+group BusinessInvoiceField;
+
+getFieldsForInvoice(invoice_id) ::=<<
+select
+  invoice_id
+, name
+, value
+from bin_fields
+where invoice_id = :invoice_id
+;
+>>
+
+addField(invoice_id, name, value) ::=<<
+insert into bin_fields (
+  invoice_id
+, name
+, value
+) values (
+  :invoice_id
+, :name
+, :value
+);
+>>
+
+removeField(invoice_id, name, value) ::= <<
+delete from bin_fields where invoice_id = :invoice_id and name = :name;
+>>
+
+test() ::= <<
+select 1 from bin_tags;
+>>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.sql.stg
new file mode 100644
index 0000000..7952eb6
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceItemSqlDao.sql.stg
@@ -0,0 +1,139 @@
+group BusinessInvoiceItem;
+
+getInvoiceItem(item_id) ::= <<
+select
+  item_id
+, created_date
+, updated_date
+, invoice_id
+, item_type
+, external_key
+, product_name
+, product_type
+, product_category
+, slug
+, phase
+, billing_period
+, start_date
+, end_date
+, amount
+, currency
+from bii
+where item_id = :item_id
+limit 1
+;
+>>
+
+getInvoiceItemsForInvoice(invoice_id) ::= <<
+select
+  item_id
+, created_date
+, updated_date
+, invoice_id
+, item_type
+, external_key
+, product_name
+, product_type
+, product_category
+, slug
+, phase
+, billing_period
+, start_date
+, end_date
+, amount
+, currency
+from bii
+where invoice_id = :invoice_id
+order by created_date asc
+;
+>>
+
+getInvoiceItemsForBundle(external_key) ::= <<
+select
+  item_id
+, created_date
+, updated_date
+, invoice_id
+, item_type
+, external_key
+, product_name
+, product_type
+, product_category
+, slug
+, phase
+, billing_period
+, start_date
+, end_date
+, amount
+, currency
+from bii
+where external_key = :external_key
+order by created_date asc
+;
+>>
+
+createInvoiceItem() ::= <<
+insert into bii (
+  item_id
+, created_date
+, updated_date
+, invoice_id
+, item_type
+, external_key
+, product_name
+, product_type
+, product_category
+, slug
+, phase
+, billing_period
+, start_date
+, end_date
+, amount
+, currency
+) values (
+  :item_id
+, :created_date
+, :updated_date
+, :invoice_id
+, :item_type
+, :external_key
+, :product_name
+, :product_type
+, :product_category
+, :slug
+, :phase
+, :billing_period
+, :start_date
+, :end_date
+, :amount
+, :currency
+);
+>>
+
+updateInvoiceItem() ::= <<
+update bii set
+  updated_date = :updated_date
+, invoice_id = :invoice_id
+, item_type = :item_type
+, external_key = :external_key
+, product_name = :product_name
+, product_type = :product_type
+, product_category = :product_category
+, slug = :slug
+, phase = :phase
+, billing_period = :billing_period
+, start_date = :start_date
+, end_date = :end_date
+, amount = :amount
+, currency = :currency
+where item_id = :item_id
+;
+>>
+
+deleteInvoiceItem(item_id) ::= <<
+delete from bii where item_id = :item_id;
+>>
+
+test() ::= <<
+select 1 from bii;
+>>
\ No newline at end of file
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.sql.stg
new file mode 100644
index 0000000..a2ced92
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentFieldSqlDao.sql.stg
@@ -0,0 +1,31 @@
+group BusinessInvoicePaymentField;
+
+getFieldsForInvoicePayment(payment_id) ::=<<
+select
+  payment_id
+, name
+, value
+from bip_fields
+where payment_id = :payment_id
+;
+>>
+
+addField(payment_id, name, value) ::=<<
+insert into bip_fields (
+  payment_id
+, name
+, value
+) values (
+  :payment_id
+, :name
+, :value
+);
+>>
+
+removeField(payment_id, name) ::= <<
+delete from bip_fields where payment_id = :payment_id and name = :name;
+>>
+
+test() ::= <<
+select 1 from bip_fields;
+>>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.sql.stg
new file mode 100644
index 0000000..c5d0fb8
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentSqlDao.sql.stg
@@ -0,0 +1,144 @@
+group BusinessInvoicePayment;
+
+getInvoicePaymentForPaymentAttempt(attempt_id) ::= <<
+select
+  payment_id
+, created_date
+, updated_date
+, attempt_id
+, account_key
+, invoice_id
+, effective_date
+, amount
+, currency
+, payment_error
+, processing_status
+, requested_amount
+, plugin_name
+, payment_type
+, payment_method
+, card_type
+, card_country
+from bip
+where attempt_id = :attempt_id
+limit 1
+;
+>>
+
+getInvoicePaymentsForPayment(payment_id) ::= <<
+select
+  payment_id
+, created_date
+, updated_date
+, attempt_id
+, account_key
+, invoice_id
+, effective_date
+, amount
+, currency
+, payment_error
+, processing_status
+, requested_amount
+, plugin_name
+, payment_type
+, payment_method
+, card_type
+, card_country
+from bip
+where payment_id = :payment_id
+order by created_date asc
+;
+>>
+
+getInvoicePaymentsForAccount(account_key) ::= <<
+select
+  payment_id
+, created_date
+, updated_date
+, attempt_id
+, account_key
+, invoice_id
+, effective_date
+, amount
+, currency
+, payment_error
+, processing_status
+, requested_amount
+, plugin_name
+, payment_type
+, payment_method
+, card_type
+, card_country
+from bip
+where account_key = :account_key
+order by created_date asc
+;
+>>
+
+createInvoicePayment() ::= <<
+insert into bip (
+  payment_id
+, created_date
+, updated_date
+, attempt_id
+, account_key
+, invoice_id
+, effective_date
+, amount
+, currency
+, payment_error
+, processing_status
+, requested_amount
+, plugin_name
+, payment_type
+, payment_method
+, card_type
+, card_country
+) values (
+  :payment_id
+, :created_date
+, :updated_date
+, :attempt_id
+, :account_key
+, :invoice_id
+, :effective_date
+, :amount
+, :currency
+, :payment_error
+, :processing_status
+, :requested_amount
+, :plugin_name
+, :payment_type
+, :payment_method
+, :card_type
+, :card_country
+);
+>>
+
+updateInvoicePaymentForPaymentAttempt() ::= <<
+update bip set
+  updated_date = :updated_date
+, account_key = :account_key
+, invoice_id = :invoice_id
+, effective_date = :effective_date
+, amount = :amount
+, currency = :currency
+, payment_error = :payment_error
+, processing_status = :processing_status
+, requested_amount = :requested_amount
+, plugin_name = :plugin_name
+, payment_type = :payment_type
+, payment_method = :payment_method
+, card_type = :card_type
+, card_country = :card_country
+where attempt_id = :attempt_id
+;
+>>
+
+deleteInvoicePaymentForPaymentAttempt(attempt_id) ::= <<
+delete from bip where attempt_id = :attempt_id
+>>
+
+test() ::= <<
+select 1 from bip;
+>>
\ No newline at end of file
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.sql.stg
new file mode 100644
index 0000000..57553ad
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoicePaymentTagSqlDao.sql.stg
@@ -0,0 +1,28 @@
+group BusinessInvoicePaymentTag;
+
+getTagsForInvoicePayment(payment_id) ::=<<
+select
+  payment_id
+, name
+from bip_tags
+where payment_id = :payment_id
+;
+>>
+
+addTag(payment_id, name) ::=<<
+insert into bip_tags (
+  payment_id
+, name
+) values (
+  :payment_id
+, :name
+);
+>>
+
+removeTag(payment_id, name) ::= <<
+delete from bip_tags where payment_id = :payment_id and name = :name;
+>>
+
+test() ::= <<
+select 1 from bip_tags;
+>>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.sql.stg
new file mode 100644
index 0000000..83d3ffc
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceSqlDao.sql.stg
@@ -0,0 +1,90 @@
+group BusinessInvoice;
+
+getInvoice(invoice_id) ::= <<
+select
+  invoice_id
+, created_date
+, updated_date
+, account_key
+, invoice_date
+, target_date
+, currency
+, balance
+, amount_paid
+, amount_charged
+, amount_credited
+from bin
+where invoice_id = :invoice_id
+limit 1
+;
+>>
+
+getInvoicesForAccount(account_key) ::= <<
+select
+  invoice_id
+, created_date
+, updated_date
+, account_key
+, invoice_date
+, target_date
+, currency
+, balance
+, amount_paid
+, amount_charged
+, amount_credited
+from bin
+where account_key = :account_key
+order by created_date asc
+;
+>>
+
+createInvoice() ::= <<
+insert into bin (
+  invoice_id
+, created_date
+, updated_date
+, account_key
+, invoice_date
+, target_date
+, currency
+, balance
+, amount_paid
+, amount_charged
+, amount_credited
+) values (
+  :invoice_id
+, :created_date
+, :updated_date
+, :account_key
+, :invoice_date
+, :target_date
+, :currency
+, :balance
+, :amount_paid
+, :amount_charged
+, :amount_credited
+);
+>>
+
+updateInvoice() ::= <<
+update bin set
+  updated_date = :updated_date
+, account_key = :account_key
+, invoice_date = :invoice_date
+, target_date = :target_date
+, currency = :currency
+, balance = :balance
+, amount_paid = :amount_paid
+, amount_charged = :amount_charged
+, amount_credited = :amount_credited
+where invoice_id = :invoice_id
+;
+>>
+
+deleteInvoice(invoice_id) ::= <<
+delete from bin where invoice_id = :invoice_id;
+>>
+
+test() ::= <<
+select 1 from bin;
+>>
\ No newline at end of file
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.sql.stg
new file mode 100644
index 0000000..f01a7d7
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessInvoiceTagSqlDao.sql.stg
@@ -0,0 +1,28 @@
+group BusinessInvoiceTag;
+
+getTagsForInvoice(invoice_id) ::=<<
+select
+  invoice_id
+, name
+from bin_tags
+where invoice_id = :invoice_id
+;
+>>
+
+addTag(invoice_id, name) ::=<<
+insert into bin_tags (
+  invoice_id
+, name
+) values (
+  :invoice_id
+, :name
+);
+>>
+
+removeTag(invoice_id, name) ::= <<
+delete from bin_tags where invoice_id = :invoice_id and name = :name;
+>>
+
+test() ::= <<
+select 1 from bin_tags;
+>>
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.sql.stg
new file mode 100644
index 0000000..d412125
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessOverdueStatusSqlDao.sql.stg
@@ -0,0 +1,31 @@
+group BusinessOverdueStatus;
+
+getOverdueStatusesForBundle(external_key) ::= <<
+select
+  external_key
+, status
+, start_date
+, end_date
+from bos
+where external_key = :external_key
+order by start_date asc
+;
+>>
+
+createOverdueStatus() ::= <<
+insert into bos (
+  external_key
+, status
+, start_date
+, end_date
+) values (
+  :external_key
+, :status
+, :start_date
+, :end_date
+);
+>>
+
+test() ::= <<
+select 1 from bos;
+>>
\ No newline at end of file
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.sql.stg
new file mode 100644
index 0000000..522e6d7
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionFieldSqlDao.sql.stg
@@ -0,0 +1,31 @@
+group BusinessSubscriptionTransitionField;
+
+getFieldsForBusinessSubscriptionTransition(external_key) ::=<<
+select
+  external_key
+, name
+, value
+from bst_fields
+where external_key = :external_key
+;
+>>
+
+addField(external_key, name, value) ::=<<
+insert into bst_fields (
+  external_key
+, name
+, value
+) values (
+  :external_key
+, :name
+, :value
+);
+>>
+
+removeField(external_key, name) ::= <<
+delete from bst_fields where external_key = :external_key and name = :name;
+>>
+
+test() ::= <<
+select 1 from bst_fields;
+>>
\ No newline at end of file
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.sql.stg b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.sql.stg
new file mode 100644
index 0000000..3d2255f
--- /dev/null
+++ b/analytics/src/main/resources/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionTagSqlDao.sql.stg
@@ -0,0 +1,28 @@
+group BusinessSubscriptionTransitionTag;
+
+getTagsForBusinessSubscriptionTransition(external_key) ::=<<
+select
+  external_key
+, name
+from bst_tags
+where external_key = :external_key
+;
+>>
+
+addTag(external_key, name) ::=<<
+insert into bst_tags (
+  external_key
+, name
+) values (
+  :external_key
+, :name
+);
+>>
+
+removeTag(external_key, name) ::= <<
+delete from bst_tags where external_key = :external_key and name = :name;
+>>
+
+test() ::= <<
+select 1 from bst_tags;
+>>
\ No newline at end of file
diff --git a/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql b/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql
index 7240236..43aaad8 100644
--- a/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql
+++ b/analytics/src/main/resources/com/ning/billing/analytics/ddl.sql
@@ -1,8 +1,8 @@
 drop table if exists bst;
 create table bst (
-  event_id char(36) not null
-, event_key varchar(50) not null
-, account_key varchar(50) not null
+  total_ordering bigint default 0
+, external_key varchar(50) not null comment 'Bundle external key'
+, account_key varchar(50) not null comment 'Account external key'
 , requested_timestamp bigint not null
 , event varchar(50) not null
 , prev_product_name varchar(32) default null
@@ -33,22 +33,143 @@ create table bst (
 , next_state varchar(32) default null
 , next_subscription_id varchar(100) default null
 , next_bundle_id varchar(100) default null
-, primary key(event_id)
-) engine=innodb;
-create index bst_key_index on bst (event_key, requested_timestamp asc);
+, primary key(total_ordering)
+) engine=innodb comment 'Business Subscription Transitions, track bundles lifecycle';
+create index bst_key_index on bst (external_key, requested_timestamp asc);
 
 drop table if exists bac;
 create table bac (
   account_key varchar(50) not null
+, name varchar(100) not null
 , created_date bigint not null
 , updated_date bigint not null
 , balance numeric(10, 4) default 0
-, tags varchar(500) default null
 , last_invoice_date bigint default null
 , total_invoice_balance numeric(10, 4) default 0
 , last_payment_status varchar(100) default null
 , payment_method varchar(100) default null
 , credit_card_type varchar(32) default null
 , billing_address_country varchar(100) default null
-) engine=innodb;
-create unique index bac_key_index on bac (account_key);
\ No newline at end of file
+, currency char(3) default null
+) engine=innodb comment 'Business ACcounts, keep a record of all accounts';
+create unique index bac_key_index on bac (account_key);
+
+drop table if exists bin;
+create table bin (
+  invoice_id char(36) not null
+, created_date bigint not null
+, updated_date bigint not null
+, account_key varchar(50) not null
+, invoice_date bigint not null
+, target_date bigint not null
+, currency char(3) not null
+, balance numeric(10, 4) default 0 comment 'amount_charged - amount_paid - amount_credited'
+, amount_paid numeric(10, 4) default 0 comment 'Sums of the successful payments made for this invoice minus the refunds associated with this invoice'
+, amount_charged numeric(10, 4) default 0 comment 'Sums of the invoice items amount'
+, amount_credited numeric(10, 4) default 0 comment 'Sums of the credit items'
+) engine=innodb comment 'Business INvoices, keep a record of generated invoices';
+create unique index bin_key_index on bin (invoice_id);
+
+drop table if exists bii;
+create table bii (
+  item_id char(36) not null
+, created_date bigint not null
+, updated_date bigint not null
+, invoice_id char(36) not null
+, item_type char(20) not null comment 'e.g. FIXED or RECURRING'
+, external_key varchar(50) not null comment 'Bundle external key'
+, product_name varchar(32) default null
+, product_type varchar(32) default null
+, product_category varchar(32) default null
+, slug varchar(50) default null comment 'foo'
+, phase varchar(32) default null
+, billing_period varchar(32) default null
+, start_date bigint default null
+, end_date bigint default null
+, amount numeric(10, 4) default 0
+, currency char(3) default null
+) engine=innodb comment 'Business Invoice Items, keep a record of all invoice items';
+create unique index bii_key_index on bii (item_id);
+
+drop table if exists bip;
+create table bip (
+  payment_id char(36) not null
+, created_date bigint not null
+, updated_date bigint not null
+, attempt_id char(36) not null
+, account_key varchar(50) not null comment 'Account external key'
+, invoice_id char(36) not null
+, effective_date bigint default null
+, amount numeric(10, 4) default 0
+, currency char(3) default null
+, payment_error varchar(256) default null
+, processing_status varchar(50) default null
+, requested_amount numeric(10, 4) default 0
+, plugin_name varchar(20) default null
+, payment_type varchar(20) default null
+, payment_method varchar(20) default null
+, card_type varchar(20) default null
+, card_country varchar(20) default null
+) engine=innodb comment 'Business Invoice Payments, track all payment attempts';
+create unique index bip_key_index on bip (attempt_id);
+
+drop table if exists bos;
+create table bos (
+  external_key varchar(50) not null comment 'Bundle external key'
+, status varchar(50) not null
+, start_date bigint default null
+, end_date bigint default null
+) engine=innodb comment 'Business Overdue Status, historical bundles overdue status';
+create unique index bos_key_index on bos (external_key, status);
+
+drop table if exists bac_tags;
+create table bac_tags (
+  account_key varchar(50) not null comment 'Account external key'
+, name varchar(20) not null
+) engine=innodb comment 'Tags associated to accounts';
+
+drop table if exists bac_fields;
+create table bac_fields (
+  account_key varchar(50) not null comment 'Account external key'
+, name varchar(30) not null
+, value varchar(255) default null
+) engine=innodb comment 'Custom fields associated to accounts';
+
+drop table if exists bst_tags;
+create table bst_tags (
+  external_key varchar(50) not null comment 'Bundle external key'
+, name varchar(20) not null
+) engine=innodb comment 'Tags associated to bundles';
+
+drop table if exists bst_fields;
+create table bst_fields (
+  external_key varchar(50) not null comment 'Bundle external key'
+, name varchar(30) not null
+, value varchar(255) default null
+) engine=innodb comment 'Custom fields associated to bundles';
+
+drop table if exists bin_tags;
+create table bin_tags (
+  invoice_id char(36) not null
+, name varchar(20) not null
+) engine=innodb comment 'Tags associated to invoices';
+
+drop table if exists bin_fields;
+create table bin_fields (
+  invoice_id char(36) not null
+, name varchar(30) not null
+, value varchar(255) default null
+) engine=innodb comment 'Custom fields associated to invoices';
+
+drop table if exists bip_tags;
+create table bip_tags (
+  payment_id char(36) not null
+, name varchar(20) not null
+) engine=innodb comment 'Tags associated to payments';
+
+drop table if exists bip_fields;
+create table bip_fields (
+  payment_id char(36) not null
+, name varchar(30) not null
+, value varchar(255) default null
+) engine=innodb comment 'Custom fields associated to payments';
diff --git a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
index 3a76b0b..e7c167e 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/AnalyticsTestModule.java
@@ -21,7 +21,6 @@ import org.skife.jdbi.v2.IDBI;
 
 import com.ning.billing.account.glue.AccountModule;
 import com.ning.billing.analytics.setup.AnalyticsModule;
-import com.ning.billing.catalog.MockCatalog;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.dbi.MysqlTestingHelper;
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
index 0094ca4..5d452e1 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
@@ -25,7 +25,6 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 import org.mockito.Mockito;
 import org.testng.Assert;
-import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
@@ -37,17 +36,16 @@ import com.ning.billing.account.api.AccountCreationEvent;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.account.api.user.DefaultAccountCreationEvent;
 import com.ning.billing.analytics.AnalyticsTestModule;
-import com.ning.billing.analytics.BusinessSubscription;
-import com.ning.billing.analytics.BusinessSubscriptionEvent;
-import com.ning.billing.analytics.BusinessSubscriptionTransition;
-import com.ning.billing.analytics.MockAccount;
 import com.ning.billing.analytics.MockDuration;
 import com.ning.billing.analytics.MockPhase;
 import com.ning.billing.analytics.MockPlan;
 import com.ning.billing.analytics.MockProduct;
 import com.ning.billing.analytics.TestWithEmbeddedDB;
-import com.ning.billing.analytics.dao.BusinessAccountDao;
-import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionDao;
+import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
+import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
+import com.ning.billing.analytics.model.BusinessSubscription;
+import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
 import com.ning.billing.catalog.MockPriceList;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -74,6 +72,7 @@ import com.ning.billing.invoice.api.user.DefaultInvoiceCreationEvent;
 import com.ning.billing.invoice.dao.InvoiceDao;
 import com.ning.billing.invoice.model.DefaultInvoice;
 import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
+import com.ning.billing.mock.MockAccountBuilder;
 import com.ning.billing.payment.api.DefaultPaymentInfoEvent;
 import com.ning.billing.payment.api.PaymentInfoEvent;
 import com.ning.billing.payment.api.PaymentStatus;
@@ -94,8 +93,8 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
     final Plan plan = new MockPlan("platinum-monthly", product);
     final PlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
 
-    private static final UUID ID = UUID.randomUUID();
-    private static final String KEY = "12345";
+    private static final Long TOTAL_ORDERING = 11L;
+    private static final String EXTERNAL_KEY = "12345";
     private static final String ACCOUNT_KEY = "pierre-12345";
     private static final Currency ACCOUNT_CURRENCY = Currency.EUR;
     private static final BigDecimal INVOICE_AMOUNT = BigDecimal.valueOf(1243.11);
@@ -122,10 +121,10 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
     private Bus bus;
 
     @Inject
-    private BusinessSubscriptionTransitionDao subscriptionDao;
+    private BusinessSubscriptionTransitionSqlDao subscriptionSqlDao;
 
     @Inject
-    private BusinessAccountDao accountDao;
+    private BusinessAccountSqlDao accountSqlDao;
 
     private SubscriptionEvent transition;
     private BusinessSubscriptionTransition expectedTransition;
@@ -151,7 +150,11 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
 
     @BeforeMethod(groups = "slow")
     public void createMocks() {
-        final MockAccount account = new MockAccount(UUID.randomUUID(), ACCOUNT_KEY, ACCOUNT_CURRENCY);
+        final Account account = new MockAccountBuilder(UUID.randomUUID())
+                .externalKey(ACCOUNT_KEY)
+                .currency(ACCOUNT_CURRENCY)
+                .build();
+
         try {
             final Account storedAccount = accountApi.createAccount(account, context);
 
@@ -165,11 +168,11 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
     }
 
     private void createSubscriptionTransitionEvent(final Account account) throws EntitlementUserApiException {
-        final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(account.getId(), KEY, context);
+        final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(account.getId(), EXTERNAL_KEY, context);
 
         // Verify we correctly initialized the account subsystem
         Assert.assertNotNull(bundle);
-        Assert.assertEquals(bundle.getKey(), KEY);
+        Assert.assertEquals(bundle.getKey(), EXTERNAL_KEY);
 
         // Create a subscription transition event
         final UUID subscriptionId = UUID.randomUUID();
@@ -179,7 +182,7 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
 
 
         transition = new DefaultSubscriptionEvent(new SubscriptionTransitionData(
-                ID,
+                UUID.randomUUID(),
                 subscriptionId,
                 bundle.getId(),
                 EntitlementEvent.EventType.API_USER,
@@ -194,12 +197,12 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
                 plan,
                 phase,
                 priceList,
-                1L,
+                TOTAL_ORDERING,
                 null,
                 true), null);
         expectedTransition = new BusinessSubscriptionTransition(
-                ID,
-                KEY,
+                TOTAL_ORDERING,
+                EXTERNAL_KEY,
                 ACCOUNT_KEY,
                 requestedTransitionTime,
                 BusinessSubscriptionEvent.subscriptionCreated(plan.getName(), catalog, new DateTime(), new DateTime()),
@@ -241,15 +244,8 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
     */
     }
 
-
-    @AfterClass(groups = "slow")
-    public void stopMysql() {
-        helper.stopMysql();
-    }
-
-
     // STEPH talk to Pierre -- see previous remark hence disable test
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow", enabled = false)
     public void testRegisterForNotifications() throws Exception {
         // Make sure the service has been instantiated
         Assert.assertEquals(service.getName(), "analytics-service");
@@ -261,23 +257,23 @@ public class TestAnalyticsService extends TestWithEmbeddedDB {
             Assert.fail("Unable to start the bus or service! " + t);
         }
 
-        Assert.assertNull(accountDao.getAccount(ACCOUNT_KEY));
+        Assert.assertNull(accountSqlDao.getAccount(ACCOUNT_KEY));
 
         // Send events and wait for the async part...
         bus.post(transition);
         bus.post(accountCreationNotification);
         Thread.sleep(5000);
 
-        Assert.assertEquals(subscriptionDao.getTransitions(KEY).size(), 1);
-        Assert.assertEquals(subscriptionDao.getTransitions(KEY).get(0), expectedTransition);
+        Assert.assertEquals(subscriptionSqlDao.getTransitions(EXTERNAL_KEY).size(), 1);
+        Assert.assertEquals(subscriptionSqlDao.getTransitions(EXTERNAL_KEY).get(0), expectedTransition);
 
         // Test invoice integration - the account creation notification has triggered a BAC update
-        Assert.assertTrue(accountDao.getAccount(ACCOUNT_KEY).getTotalInvoiceBalance().compareTo(INVOICE_AMOUNT) == 0);
+        Assert.assertTrue(accountSqlDao.getAccount(ACCOUNT_KEY).getTotalInvoiceBalance().compareTo(INVOICE_AMOUNT) == 0);
 
         // Post the same invoice event again - the invoice balance shouldn't change
         bus.post(invoiceCreationNotification);
         Thread.sleep(5000);
-        Assert.assertTrue(accountDao.getAccount(ACCOUNT_KEY).getTotalInvoiceBalance().compareTo(INVOICE_AMOUNT) == 0);
+        Assert.assertTrue(accountSqlDao.getAccount(ACCOUNT_KEY).getTotalInvoiceBalance().compareTo(INVOICE_AMOUNT) == 0);
 
         // Test payment integration - the fields have already been populated, just make sure the code is exercised
         bus.post(paymentInfoNotification);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
index c9c31be..5d6b3a6 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
@@ -19,7 +19,6 @@ package com.ning.billing.analytics.dao;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.sql.SQLException;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
@@ -31,10 +30,10 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import com.ning.billing.analytics.BusinessAccount;
-import com.ning.billing.analytics.BusinessSubscription;
-import com.ning.billing.analytics.BusinessSubscriptionEvent;
-import com.ning.billing.analytics.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessSubscription;
+import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
 import com.ning.billing.analytics.MockDuration;
 import com.ning.billing.analytics.MockPhase;
 import com.ning.billing.analytics.MockPlan;
@@ -51,20 +50,19 @@ import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.util.tag.Tag;
 
 public class TestAnalyticsDao extends TestWithEmbeddedDB {
-    private static final UUID EVENT_ID = UUID.randomUUID();
-    private static final String EVENT_KEY = "23456";
+    private static final Long TOTAL_ORDERING = 1L;
+    private static final String EXTERNAL_KEY = "23456";
     private static final String ACCOUNT_KEY = "pierre-143343-vcc";
 
     private final Product product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
     private final Plan plan = new MockPlan("platinum-monthly", product);
     private final PlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
 
-    private BusinessSubscriptionTransitionDao businessSubscriptionTransitionDao;
+    private BusinessSubscriptionTransitionSqlDao businessSubscriptionTransitionSqlDao;
     private BusinessSubscriptionTransition transition;
-    private BusinessAccountDao businessAccountDao;
+    private BusinessAccountSqlDao businessAccountSqlDao;
     private BusinessAccount account;
 
     private final CatalogService catalogService = Mockito.mock(CatalogService.class);
@@ -87,48 +85,38 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         final BusinessSubscription nextSubscription = new BusinessSubscription(null, plan.getName(), phase.getName(), Currency.USD, new DateTime(DateTimeZone.UTC), Subscription.SubscriptionState.CANCELLED, UUID.randomUUID(), UUID.randomUUID(), catalog);
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCancelled(plan.getName(), catalog, requestedTimestamp, requestedTimestamp);
 
-        transition = new BusinessSubscriptionTransition(EVENT_ID, EVENT_KEY, ACCOUNT_KEY, requestedTimestamp, event, prevSubscription, nextSubscription);
+        transition = new BusinessSubscriptionTransition(TOTAL_ORDERING, EXTERNAL_KEY, ACCOUNT_KEY, requestedTimestamp, event, prevSubscription, nextSubscription);
 
         final IDBI dbi = helper.getDBI();
-        businessSubscriptionTransitionDao = dbi.onDemand(BusinessSubscriptionTransitionDao.class);
+        businessSubscriptionTransitionSqlDao = dbi.onDemand(BusinessSubscriptionTransitionSqlDao.class);
 
         // Healthcheck test to make sure MySQL is setup properly
         try {
-            businessSubscriptionTransitionDao.test();
+            businessSubscriptionTransitionSqlDao.test();
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
     }
 
     private void setupBusinessAccount() {
-        final List<Tag> tags = new ArrayList<Tag>();
-        tags.add(getMockTag("batch1"));
-        tags.add(getMockTag("great,guy"));
-        account = new BusinessAccount(ACCOUNT_KEY, BigDecimal.ONE, tags, new DateTime(DateTimeZone.UTC), BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "FRANCE");
+        account = new BusinessAccount(ACCOUNT_KEY, UUID.randomUUID().toString(), BigDecimal.ONE, new DateTime(DateTimeZone.UTC), BigDecimal.TEN, "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "FRANCE");
 
         final IDBI dbi = helper.getDBI();
-        businessAccountDao = dbi.onDemand(BusinessAccountDao.class);
+        businessAccountSqlDao = dbi.onDemand(BusinessAccountSqlDao.class);
 
         // Healthcheck test to make sure MySQL is setup properly
         try {
-            businessAccountDao.test();
+            businessAccountSqlDao.test();
         } catch (Throwable t) {
             Assert.fail(t.toString());
         }
     }
 
-    private Tag getMockTag(final String tagDefinitionName) {
-        final Tag tag = Mockito.mock(Tag.class);
-        Mockito.when(tag.getTagDefinitionName()).thenReturn(tagDefinitionName);
-        Mockito.when(tag.toString()).thenReturn(tagDefinitionName);
-        return tag;
-    }
-
     @Test(groups = "slow")
     public void testHandleDuplicatedEvents() {
         final BusinessSubscriptionTransition transitionWithNullPrev = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
@@ -136,28 +124,28 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
                 transition.getNextSubscription()
         );
 
-        businessSubscriptionTransitionDao.createTransition(transitionWithNullPrev);
-        List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPrev);
+        List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullPrev);
         // Try to add the same transition, with the same UUID - we should only store one though
-        businessSubscriptionTransitionDao.createTransition(transitionWithNullPrev);
-        transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPrev);
+        transitions = businessSubscriptionTransitionSqlDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullPrev);
 
         // Try now to store a look-alike transition (same fields except UUID) - we should store it this time
         final BusinessSubscriptionTransition secondTransitionWithNullPrev = new BusinessSubscriptionTransition(
-                UUID.randomUUID(),
-                transition.getKey(),
+                12L,
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
                 null,
                 transition.getNextSubscription()
         );
-        businessSubscriptionTransitionDao.createTransition(secondTransitionWithNullPrev);
-        transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        businessSubscriptionTransitionSqlDao.createTransition(secondTransitionWithNullPrev);
+        transitions = businessSubscriptionTransitionSqlDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 2);
         Assert.assertTrue(transitions.contains(transitionWithNullPrev));
         Assert.assertTrue(transitions.contains(secondTransitionWithNullPrev));
@@ -166,17 +154,17 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     @Test(groups = "slow")
     public void testTransitionsWithNullPrevSubscription() {
         final BusinessSubscriptionTransition transitionWithNullPrev = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
                 null,
                 transition.getNextSubscription()
         );
-        businessSubscriptionTransitionDao.createTransition(transitionWithNullPrev);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPrev);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullPrev);
     }
@@ -184,17 +172,17 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     @Test(groups = "slow")
     public void testTransitionsWithNullNextSubscription() {
         final BusinessSubscriptionTransition transitionWithNullNext = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
                 transition.getPreviousSubscription(),
                 null
         );
-        businessSubscriptionTransitionDao.createTransition(transitionWithNullNext);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullNext);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullNext);
     }
@@ -203,17 +191,17 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     public void testTransitionsWithNullFieldsInSubscription() {
         final BusinessSubscription subscriptionWithNullFields = new BusinessSubscription(null, plan.getName(), phase.getName(), Currency.USD, null, null, null, null, catalog);
         final BusinessSubscriptionTransition transitionWithNullFields = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
                 subscriptionWithNullFields,
                 subscriptionWithNullFields
         );
-        businessSubscriptionTransitionDao.createTransition(transitionWithNullFields);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullFields);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transitionWithNullFields);
     }
@@ -222,19 +210,19 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     public void testTransitionsWithNullPlanAndPhase() throws Exception {
         final BusinessSubscription subscriptionWithNullPlanAndPhase = new BusinessSubscription(null, null, null, Currency.USD, null, null, null, null, catalog);
         final BusinessSubscriptionTransition transitionWithNullPlanAndPhase = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
                 subscriptionWithNullPlanAndPhase,
                 subscriptionWithNullPlanAndPhase
         );
-        businessSubscriptionTransitionDao.createTransition(transitionWithNullPlanAndPhase);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPlanAndPhase);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
-        Assert.assertEquals(transitions.get(0).getKey(), transition.getKey());
+        Assert.assertEquals(transitions.get(0).getExternalKey(), transition.getExternalKey());
         Assert.assertEquals(transitions.get(0).getRequestedTimestamp(), transition.getRequestedTimestamp());
         Assert.assertEquals(transitions.get(0).getEvent(), transition.getEvent());
         Assert.assertNull(transitions.get(0).getPreviousSubscription());
@@ -245,17 +233,17 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     public void testTransitionsWithNullPlan() throws Exception {
         final BusinessSubscription subscriptionWithNullPlan = new BusinessSubscription(null, null, phase.getName(), Currency.USD, null, null, null, null, catalog);
         final BusinessSubscriptionTransition transitionWithNullPlan = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
                 subscriptionWithNullPlan,
                 subscriptionWithNullPlan
         );
-        businessSubscriptionTransitionDao.createTransition(transitionWithNullPlan);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPlan);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         // Null Plan but Phase - we don't turn the subscription into a null
         Assert.assertEquals(transitions.get(0), transitionWithNullPlan);
@@ -265,19 +253,19 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
     public void testTransitionsWithNullPhase() throws Exception {
         final BusinessSubscription subscriptionWithNullPhase = new BusinessSubscription(null, plan.getName(), null, Currency.USD, null, null, null, null, catalog);
         final BusinessSubscriptionTransition transitionWithNullPhase = new BusinessSubscriptionTransition(
-                transition.getId(),
-                transition.getKey(),
+                transition.getTotalOrdering(),
+                transition.getExternalKey(),
                 transition.getAccountKey(),
                 transition.getRequestedTimestamp(),
                 transition.getEvent(),
                 subscriptionWithNullPhase,
                 subscriptionWithNullPhase
         );
-        businessSubscriptionTransitionDao.createTransition(transitionWithNullPhase);
+        businessSubscriptionTransitionSqlDao.createTransition(transitionWithNullPhase);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
-        Assert.assertEquals(transitions.get(0).getKey(), transition.getKey());
+        Assert.assertEquals(transitions.get(0).getExternalKey(), transition.getExternalKey());
         Assert.assertEquals(transitions.get(0).getRequestedTimestamp(), transition.getRequestedTimestamp());
         Assert.assertEquals(transitions.get(0).getEvent(), transition.getEvent());
 
@@ -289,26 +277,22 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
 
     @Test(groups = "slow")
     public void testCreateAndRetrieveTransitions() {
-        businessSubscriptionTransitionDao.createTransition(transition);
+        businessSubscriptionTransitionSqlDao.createTransition(transition);
 
-        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionDao.getTransitions(EVENT_KEY);
+        final List<BusinessSubscriptionTransition> transitions = businessSubscriptionTransitionSqlDao.getTransitions(EXTERNAL_KEY);
         Assert.assertEquals(transitions.size(), 1);
         Assert.assertEquals(transitions.get(0), transition);
 
-        Assert.assertEquals(businessSubscriptionTransitionDao.getTransitions("Doesn't exist").size(), 0);
+        Assert.assertEquals(businessSubscriptionTransitionSqlDao.getTransitions("Doesn't exist").size(), 0);
     }
 
     @Test(groups = "slow")
     public void testCreateSaveAndRetrieveAccounts() {
         // Create and retrieve an account
-        businessAccountDao.createAccount(account);
-        final BusinessAccount foundAccount = businessAccountDao.getAccount(ACCOUNT_KEY);
+        businessAccountSqlDao.createAccount(account);
+        final BusinessAccount foundAccount = businessAccountSqlDao.getAccount(ACCOUNT_KEY);
         Assert.assertNotNull(foundAccount.getCreatedDt());
         Assert.assertEquals(foundAccount.getCreatedDt(), foundAccount.getUpdatedDt());
-        // Verify the joiner stuff
-        Assert.assertEquals(foundAccount.getTags().size(), 2);
-        Assert.assertEquals(foundAccount.getTags().get(0).getTagDefinitionName(), "batch1");
-        Assert.assertEquals(foundAccount.getTags().get(1).getTagDefinitionName(), "great,guy");
         // Verify the dates by backfilling them
         account.setCreatedDt(foundAccount.getCreatedDt());
         account.setUpdatedDt(foundAccount.getUpdatedDt());
@@ -318,14 +302,14 @@ public class TestAnalyticsDao extends TestWithEmbeddedDB {
         final DateTime previousUpdatedDt = account.getUpdatedDt();
         account.setBalance(BigDecimal.TEN);
         account.setPaymentMethod("PayPal");
-        businessAccountDao.saveAccount(account);
+        businessAccountSqlDao.saveAccount(account);
         // Verify the save worked as expected
-        account = businessAccountDao.getAccount(ACCOUNT_KEY);
+        account = businessAccountSqlDao.getAccount(ACCOUNT_KEY);
         Assert.assertEquals(Rounder.round(BigDecimal.TEN), account.getRoundedBalance());
         Assert.assertEquals("PayPal", account.getPaymentMethod());
         Assert.assertTrue(account.getUpdatedDt().compareTo(previousUpdatedDt) > 0);
 
         // ACCOUNT not found
-        Assert.assertNull(businessAccountDao.getAccount("Doesn't exist"));
+        Assert.assertNull(businessAccountSqlDao.getAccount("Doesn't exist"));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java
new file mode 100644
index 0000000..69fed56
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountFieldSqlDao.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessAccountField;
+
+public class TestBusinessAccountFieldSqlDao extends TestWithEmbeddedDB {
+    private BusinessAccountFieldSqlDao accountFieldSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        accountFieldSqlDao = dbi.onDemand(BusinessAccountFieldSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final String accountKey = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString().substring(0, 30);
+        final String value = UUID.randomUUID().toString();
+
+        // Verify initial state
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccount(accountKey).size(), 0);
+        Assert.assertEquals(accountFieldSqlDao.removeField(accountKey, name), 0);
+
+        // Add an entry
+        Assert.assertEquals(accountFieldSqlDao.addField(accountKey, name, value), 1);
+        final List<BusinessAccountField> fieldsForAccount = accountFieldSqlDao.getFieldsForAccount(accountKey);
+        Assert.assertEquals(fieldsForAccount.size(), 1);
+
+        // Retrieve it
+        final BusinessAccountField accountField = fieldsForAccount.get(0);
+        Assert.assertEquals(accountField.getAccountKey(), accountKey);
+        Assert.assertEquals(accountField.getName(), name);
+        Assert.assertEquals(accountField.getValue(), value);
+
+        // Delete it
+        Assert.assertEquals(accountFieldSqlDao.removeField(accountKey, name), 1);
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccount(accountKey).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final String accountKey1 = UUID.randomUUID().toString();
+        final String name1 = UUID.randomUUID().toString().substring(0, 30);
+        final String accountKey2 = UUID.randomUUID().toString();
+        final String name2 = UUID.randomUUID().toString().substring(0, 30);
+
+        // Add a field to both accounts
+        Assert.assertEquals(accountFieldSqlDao.addField(accountKey1, name1, UUID.randomUUID().toString()), 1);
+        Assert.assertEquals(accountFieldSqlDao.addField(accountKey2, name2, UUID.randomUUID().toString()), 1);
+
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccount(accountKey1).size(), 1);
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccount(accountKey2).size(), 1);
+
+        // Remove the field for the first account
+        Assert.assertEquals(accountFieldSqlDao.removeField(accountKey1, name1), 1);
+
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccount(accountKey1).size(), 0);
+        Assert.assertEquals(accountFieldSqlDao.getFieldsForAccount(accountKey2).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            accountFieldSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java
new file mode 100644
index 0000000..20ccfc8
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessAccountTagSqlDao.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessAccountTag;
+
+public class TestBusinessAccountTagSqlDao extends TestWithEmbeddedDB {
+    private BusinessAccountTagSqlDao accountTagSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        accountTagSqlDao = dbi.onDemand(BusinessAccountTagSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final String accountKey = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString().substring(0, 20);
+
+        // Verify initial state
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccount(accountKey).size(), 0);
+        Assert.assertEquals(accountTagSqlDao.removeTag(accountKey, name), 0);
+
+        // Add an entry
+        Assert.assertEquals(accountTagSqlDao.addTag(accountKey, name), 1);
+        final List<BusinessAccountTag> tagsForAccount = accountTagSqlDao.getTagsForAccount(accountKey);
+        Assert.assertEquals(tagsForAccount.size(), 1);
+
+        // Retrieve it
+        final BusinessAccountTag accountTag = tagsForAccount.get(0);
+        Assert.assertEquals(accountTag.getAccountKey(), accountKey);
+        Assert.assertEquals(accountTag.getName(), name);
+
+        // Delete it
+        Assert.assertEquals(accountTagSqlDao.removeTag(accountKey, name), 1);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccount(accountKey).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final String accountKey1 = UUID.randomUUID().toString();
+        final String name1 = UUID.randomUUID().toString().substring(0, 20);
+        final String accountKey2 = UUID.randomUUID().toString();
+        final String name2 = UUID.randomUUID().toString().substring(0, 20);
+
+        // Add a tag to both accounts
+        Assert.assertEquals(accountTagSqlDao.addTag(accountKey1, name1), 1);
+        Assert.assertEquals(accountTagSqlDao.addTag(accountKey2, name2), 1);
+
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccount(accountKey1).size(), 1);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccount(accountKey2).size(), 1);
+
+        // Remove the tag for the first account
+        Assert.assertEquals(accountTagSqlDao.removeTag(accountKey1, name1), 1);
+
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccount(accountKey1).size(), 0);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccount(accountKey2).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            accountTagSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
new file mode 100644
index 0000000..9553dfa
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceFieldSqlDao.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessInvoiceField;
+
+public class TestBusinessInvoiceFieldSqlDao extends TestWithEmbeddedDB {
+    private BusinessInvoiceFieldSqlDao invoiceFieldSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        invoiceFieldSqlDao = dbi.onDemand(BusinessInvoiceFieldSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final String invoiceId = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString().substring(0, 30);
+        final String value = UUID.randomUUID().toString();
+
+        // Verify initial state
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId).size(), 0);
+        Assert.assertEquals(invoiceFieldSqlDao.removeField(invoiceId, name), 0);
+
+        // Add an entry
+        Assert.assertEquals(invoiceFieldSqlDao.addField(invoiceId, name, value), 1);
+        final List<BusinessInvoiceField> fieldsForInvoice = invoiceFieldSqlDao.getFieldsForInvoice(invoiceId);
+        Assert.assertEquals(fieldsForInvoice.size(), 1);
+
+        // Retrieve it
+        final BusinessInvoiceField invoiceField = fieldsForInvoice.get(0);
+        Assert.assertEquals(invoiceField.getInvoiceId().toString(), invoiceId);
+        Assert.assertEquals(invoiceField.getName(), name);
+        Assert.assertEquals(invoiceField.getValue(), value);
+
+        // Delete it
+        Assert.assertEquals(invoiceFieldSqlDao.removeField(invoiceId, name), 1);
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final String invoiceId1 = UUID.randomUUID().toString();
+        final String name1 = UUID.randomUUID().toString().substring(0, 30);
+        final String invoiceId2 = UUID.randomUUID().toString();
+        final String name2 = UUID.randomUUID().toString().substring(0, 30);
+
+        // Add a field to both invoices
+        Assert.assertEquals(invoiceFieldSqlDao.addField(invoiceId1, name1, UUID.randomUUID().toString()), 1);
+        Assert.assertEquals(invoiceFieldSqlDao.addField(invoiceId2, name2, UUID.randomUUID().toString()), 1);
+
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId1).size(), 1);
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId2).size(), 1);
+
+        // Remove the field for the first invoice
+        Assert.assertEquals(invoiceFieldSqlDao.removeField(invoiceId1, name1), 1);
+
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId1).size(), 0);
+        Assert.assertEquals(invoiceFieldSqlDao.getFieldsForInvoice(invoiceId2).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            invoiceFieldSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java
new file mode 100644
index 0000000..1bd7b31
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceItemSqlDao.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.catalog.api.Currency;
+
+public class TestBusinessInvoiceItemSqlDao extends TestWithEmbeddedDB {
+    private BusinessInvoiceItemSqlDao invoiceItemSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        invoiceItemSqlDao = dbi.onDemand(BusinessInvoiceItemSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final UUID invoiceId = UUID.randomUUID();
+        final String externalKey = UUID.randomUUID().toString();
+        final BusinessInvoiceItem invoiceItem = createInvoiceItem(invoiceId, externalKey);
+
+        // Verify initial state
+        Assert.assertNull(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString()));
+        Assert.assertEquals(invoiceItemSqlDao.deleteInvoiceItem(invoiceItem.getItemId().toString()), 0);
+
+        // Add the invoice item
+        Assert.assertEquals(invoiceItemSqlDao.createInvoiceItem(invoiceItem), 1);
+
+        // Retrieve it
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString()), invoiceItem);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundle(invoiceItem.getExternalKey()).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundle(invoiceItem.getExternalKey()).get(0), invoiceItem);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString()).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString()).get(0), invoiceItem);
+
+        // Update and retrieve it
+        invoiceItem.setProductName(UUID.randomUUID().toString().substring(0, 20));
+        Assert.assertEquals(invoiceItemSqlDao.updateInvoiceItem(invoiceItem), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString()), invoiceItem);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundle(invoiceItem.getExternalKey()).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundle(invoiceItem.getExternalKey()).get(0), invoiceItem);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString()).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString()).get(0), invoiceItem);
+
+        // Delete it
+        Assert.assertEquals(invoiceItemSqlDao.deleteInvoiceItem(invoiceItem.getItemId().toString()), 1);
+        Assert.assertNull(invoiceItemSqlDao.getInvoiceItem(invoiceItem.getItemId().toString()));
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundle(invoiceItem.getExternalKey()).size(), 0);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceItem.getInvoiceId().toString()).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final UUID invoiceId1 = UUID.randomUUID();
+        final String externalKey1 = UUID.randomUUID().toString();
+        final BusinessInvoiceItem invoiceItem1 = createInvoiceItem(invoiceId1, externalKey1);
+        final UUID invoiceId2 = UUID.randomUUID();
+        final String externalKey2 = UUID.randomUUID().toString();
+        final BusinessInvoiceItem invoiceItem2 = createInvoiceItem(invoiceId2, externalKey2);
+
+        // Create both invoice items
+        Assert.assertEquals(invoiceItemSqlDao.createInvoiceItem(invoiceItem1), 1);
+        Assert.assertEquals(invoiceItemSqlDao.createInvoiceItem(invoiceItem2), 1);
+
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundle(externalKey1).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundle(externalKey2).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId1.toString()).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId2.toString()).size(), 1);
+
+        // Remove the first invoice item
+        Assert.assertEquals(invoiceItemSqlDao.deleteInvoiceItem(invoiceItem1.getItemId().toString()), 1);
+
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundle(externalKey1).size(), 0);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForBundle(externalKey2).size(), 1);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId1.toString()).size(), 0);
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoiceId2.toString()).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            invoiceItemSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+
+    private BusinessInvoiceItem createInvoiceItem(final UUID invoiceId, final String externalKey) {
+        final BigDecimal amount = BigDecimal.TEN;
+        final String billingPeriod = UUID.randomUUID().toString().substring(0, 20);
+        final DateTime createdDate = new DateTime(DateTimeZone.UTC);
+        final Currency currency = Currency.AUD;
+        final DateTime endDate = new DateTime(DateTimeZone.UTC);
+        final UUID itemId = UUID.randomUUID();
+        final String itemType = UUID.randomUUID().toString().substring(0, 20);
+        final String phase = UUID.randomUUID().toString().substring(0, 20);
+        final String productCategory = UUID.randomUUID().toString().substring(0, 20);
+        final String productName = UUID.randomUUID().toString().substring(0, 20);
+        final String productType = UUID.randomUUID().toString().substring(0, 20);
+        final String slug = UUID.randomUUID().toString();
+        final DateTime startDate = new DateTime(DateTimeZone.UTC);
+        final DateTime updatedDate = new DateTime(DateTimeZone.UTC);
+
+        return new BusinessInvoiceItem(amount, billingPeriod, createdDate, currency, endDate, externalKey, invoiceId,
+                                       itemId, itemType, phase, productCategory, productName, productType, slug, startDate, updatedDate);
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
new file mode 100644
index 0000000..b97849d
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentFieldSqlDao.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentField;
+
+public class TestBusinessInvoicePaymentFieldSqlDao extends TestWithEmbeddedDB {
+    private BusinessInvoicePaymentFieldSqlDao invoicePaymentFieldSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        invoicePaymentFieldSqlDao = dbi.onDemand(BusinessInvoicePaymentFieldSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final String paymentId = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString().substring(0, 30);
+        final String value = UUID.randomUUID().toString();
+
+        // Verify initial state
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId).size(), 0);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.removeField(paymentId, name), 0);
+
+        // Add an entry
+        Assert.assertEquals(invoicePaymentFieldSqlDao.addField(paymentId, name, value), 1);
+        final List<BusinessInvoicePaymentField> fieldsForInvoicePayment = invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId);
+        Assert.assertEquals(fieldsForInvoicePayment.size(), 1);
+
+        // Retrieve it
+        final BusinessInvoicePaymentField invoicePaymentField = fieldsForInvoicePayment.get(0);
+        Assert.assertEquals(invoicePaymentField.getPaymentId().toString(), paymentId);
+        Assert.assertEquals(invoicePaymentField.getName(), name);
+        Assert.assertEquals(invoicePaymentField.getValue(), value);
+
+        // Delete it
+        Assert.assertEquals(invoicePaymentFieldSqlDao.removeField(paymentId, name), 1);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final String paymentId1 = UUID.randomUUID().toString();
+        final String name1 = UUID.randomUUID().toString().substring(0, 30);
+        final String paymentId2 = UUID.randomUUID().toString();
+        final String name2 = UUID.randomUUID().toString().substring(0, 30);
+
+        // Add a field to both invoice payments
+        Assert.assertEquals(invoicePaymentFieldSqlDao.addField(paymentId1, name1, UUID.randomUUID().toString()), 1);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.addField(paymentId2, name2, UUID.randomUUID().toString()), 1);
+
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId1).size(), 1);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId2).size(), 1);
+
+        // Remove the field for the first invoice payment
+        Assert.assertEquals(invoicePaymentFieldSqlDao.removeField(paymentId1, name1), 1);
+
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId1).size(), 0);
+        Assert.assertEquals(invoicePaymentFieldSqlDao.getFieldsForInvoicePayment(paymentId2).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            invoicePaymentFieldSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
new file mode 100644
index 0000000..94a8066
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentSqlDao.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessInvoicePayment;
+import com.ning.billing.catalog.api.Currency;
+
+public class TestBusinessInvoicePaymentSqlDao extends TestWithEmbeddedDB {
+    private BusinessInvoicePaymentSqlDao invoicePaymentSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        invoicePaymentSqlDao = dbi.onDemand(BusinessInvoicePaymentSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final UUID attemptId = UUID.randomUUID();
+        final String accountKey = UUID.randomUUID().toString();
+        final BusinessInvoicePayment invoicePayment = createInvoicePayment(attemptId, accountKey);
+
+        // Verify initial state
+        Assert.assertNull(invoicePaymentSqlDao.getInvoicePaymentForPaymentAttempt(invoicePayment.getAttemptId().toString()));
+        Assert.assertEquals(invoicePaymentSqlDao.deleteInvoicePaymentForPaymentAttempt(invoicePayment.getAttemptId().toString()), 0);
+
+        // Add the invoice payment
+        Assert.assertEquals(invoicePaymentSqlDao.createInvoicePayment(invoicePayment), 1);
+
+        // Retrieve it
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentForPaymentAttempt(invoicePayment.getAttemptId().toString()), invoicePayment);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccount(invoicePayment.getAccountKey()).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccount(invoicePayment.getAccountKey()).get(0), invoicePayment);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForPayment(invoicePayment.getPaymentId().toString()).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForPayment(invoicePayment.getPaymentId().toString()).get(0), invoicePayment);
+
+        // Update and retrieve it
+        invoicePayment.setCardType(UUID.randomUUID().toString().substring(0, 20));
+        Assert.assertEquals(invoicePaymentSqlDao.updateInvoicePaymentForPaymentAttempt(invoicePayment), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentForPaymentAttempt(invoicePayment.getAttemptId().toString()), invoicePayment);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccount(invoicePayment.getAccountKey()).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccount(invoicePayment.getAccountKey()).get(0), invoicePayment);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForPayment(invoicePayment.getPaymentId().toString()).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForPayment(invoicePayment.getPaymentId().toString()).get(0), invoicePayment);
+
+        // Delete it
+        Assert.assertEquals(invoicePaymentSqlDao.deleteInvoicePaymentForPaymentAttempt(invoicePayment.getAttemptId().toString()), 1);
+        Assert.assertNull(invoicePaymentSqlDao.getInvoicePaymentForPaymentAttempt(invoicePayment.getAttemptId().toString()));
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccount(invoicePayment.getAccountKey()).size(), 0);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForPayment(invoicePayment.getPaymentId().toString()).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final UUID attemptId1 = UUID.randomUUID();
+        final String accountKey1 = UUID.randomUUID().toString();
+        final BusinessInvoicePayment invoicePayment1 = createInvoicePayment(attemptId1, accountKey1);
+        final UUID attemptId2 = UUID.randomUUID();
+        final String accountKey2 = UUID.randomUUID().toString();
+        final BusinessInvoicePayment invoicePayment2 = createInvoicePayment(attemptId2, accountKey2);
+
+        // Create both invoice payments
+        Assert.assertEquals(invoicePaymentSqlDao.createInvoicePayment(invoicePayment1), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.createInvoicePayment(invoicePayment2), 1);
+
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentForPaymentAttempt(invoicePayment1.getAttemptId().toString()), invoicePayment1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentForPaymentAttempt(invoicePayment2.getAttemptId().toString()), invoicePayment2);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccount(invoicePayment1.getAccountKey()).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccount(invoicePayment2.getAccountKey()).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForPayment(invoicePayment1.getPaymentId().toString()).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForPayment(invoicePayment2.getPaymentId().toString()).size(), 1);
+
+        // Remove the first invoice payment
+        Assert.assertEquals(invoicePaymentSqlDao.deleteInvoicePaymentForPaymentAttempt(invoicePayment1.getAttemptId().toString()), 1);
+
+        Assert.assertNull(invoicePaymentSqlDao.getInvoicePaymentForPaymentAttempt(invoicePayment1.getAttemptId().toString()));
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentForPaymentAttempt(invoicePayment2.getAttemptId().toString()), invoicePayment2);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccount(invoicePayment1.getAccountKey()).size(), 0);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForAccount(invoicePayment2.getAccountKey()).size(), 1);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForPayment(invoicePayment1.getPaymentId().toString()).size(), 0);
+        Assert.assertEquals(invoicePaymentSqlDao.getInvoicePaymentsForPayment(invoicePayment2.getPaymentId().toString()).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            invoicePaymentSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+
+    private BusinessInvoicePayment createInvoicePayment(final UUID attemptId, final String accountKey) {
+        final BigDecimal amount = BigDecimal.ONE;
+        final String cardCountry = UUID.randomUUID().toString().substring(0, 20);
+        final String cardType = UUID.randomUUID().toString().substring(0, 20);
+        final DateTime createdDate = new DateTime(DateTimeZone.UTC);
+        final Currency currency = Currency.BRL;
+        final DateTime effectiveDate = new DateTime(DateTimeZone.UTC);
+        final UUID invoiceId = UUID.randomUUID();
+        final String paymentError = UUID.randomUUID().toString();
+        final UUID paymentId = UUID.randomUUID();
+        final String paymentMethod = UUID.randomUUID().toString().substring(0, 20);
+        final String paymentType = UUID.randomUUID().toString().substring(0, 20);
+        final String pluginName = UUID.randomUUID().toString().substring(0, 20);
+        final String processingStatus = UUID.randomUUID().toString();
+        final BigDecimal requestedAmount = BigDecimal.ZERO;
+        final DateTime updatedDate = new DateTime(DateTimeZone.UTC);
+
+        return new BusinessInvoicePayment(accountKey, amount, attemptId,
+                                          cardCountry, cardType, createdDate,
+                                          currency, effectiveDate, invoiceId,
+                                          paymentError, paymentId, paymentMethod,
+                                          paymentType, pluginName, processingStatus,
+                                          requestedAmount, updatedDate);
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
new file mode 100644
index 0000000..5ae8f48
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoicePaymentTagSqlDao.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessInvoicePaymentTag;
+
+public class TestBusinessInvoicePaymentTagSqlDao extends TestWithEmbeddedDB {
+    private BusinessInvoicePaymentTagSqlDao invoicePaymentTagSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        invoicePaymentTagSqlDao = dbi.onDemand(BusinessInvoicePaymentTagSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final String paymentId = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString().substring(0, 20);
+
+        // Verify initial state
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId).size(), 0);
+        Assert.assertEquals(invoicePaymentTagSqlDao.removeTag(paymentId, name), 0);
+
+        // Add an entry
+        Assert.assertEquals(invoicePaymentTagSqlDao.addTag(paymentId, name), 1);
+        final List<BusinessInvoicePaymentTag> tagsForInvoicePayment = invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId);
+        Assert.assertEquals(tagsForInvoicePayment.size(), 1);
+
+        // Retrieve it
+        final BusinessInvoicePaymentTag invoicePaymentTag = tagsForInvoicePayment.get(0);
+        Assert.assertEquals(invoicePaymentTag.getPaymentId().toString(), paymentId);
+        Assert.assertEquals(invoicePaymentTag.getName(), name);
+
+        // Delete it
+        Assert.assertEquals(invoicePaymentTagSqlDao.removeTag(paymentId, name), 1);
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final String paymentId1 = UUID.randomUUID().toString();
+        final String name1 = UUID.randomUUID().toString().substring(0, 20);
+        final String paymentId2 = UUID.randomUUID().toString();
+        final String name2 = UUID.randomUUID().toString().substring(0, 20);
+
+        // Add a tag to both invoice payments
+        Assert.assertEquals(invoicePaymentTagSqlDao.addTag(paymentId1, name1), 1);
+        Assert.assertEquals(invoicePaymentTagSqlDao.addTag(paymentId2, name2), 1);
+
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId1).size(), 1);
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId2).size(), 1);
+
+        // Remove the tag for the first invoice payment
+        Assert.assertEquals(invoicePaymentTagSqlDao.removeTag(paymentId1, name1), 1);
+
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId1).size(), 0);
+        Assert.assertEquals(invoicePaymentTagSqlDao.getTagsForInvoicePayment(paymentId2).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            invoicePaymentTagSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java
new file mode 100644
index 0000000..8373f81
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceSqlDao.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.catalog.api.Currency;
+
+public class TestBusinessInvoiceSqlDao extends TestWithEmbeddedDB {
+    private BusinessInvoiceSqlDao invoiceSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        invoiceSqlDao = dbi.onDemand(BusinessInvoiceSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final UUID invoiceId = UUID.randomUUID();
+        final String accountKey = UUID.randomUUID().toString();
+        final BusinessInvoice invoice = createInvoice(invoiceId, accountKey);
+
+        // Verify initial state
+        Assert.assertNull(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString()));
+        Assert.assertEquals(invoiceSqlDao.deleteInvoice(invoice.getInvoiceId().toString()), 0);
+
+        // Add the invoice
+        Assert.assertEquals(invoiceSqlDao.createInvoice(invoice), 1);
+
+        // Retrieve it
+        Assert.assertEquals(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString()), invoice);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountKey()).size(), 1);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountKey()).get(0), invoice);
+
+        // Update and retrieve it
+        invoice.setInvoiceDate(new DateTime(DateTimeZone.UTC));
+        Assert.assertEquals(invoiceSqlDao.updateInvoice(invoice), 1);
+        Assert.assertEquals(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString()), invoice);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountKey()).size(), 1);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountKey()).get(0), invoice);
+
+        // Delete it
+        Assert.assertEquals(invoiceSqlDao.deleteInvoice(invoice.getInvoiceId().toString()), 1);
+        Assert.assertNull(invoiceSqlDao.getInvoice(invoice.getInvoiceId().toString()));
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(invoice.getAccountKey()).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final UUID invoiceId1 = UUID.randomUUID();
+        final String accountKey1 = UUID.randomUUID().toString();
+        final BusinessInvoice invoice1 = createInvoice(invoiceId1, accountKey1);
+        final UUID invoiceId2 = UUID.randomUUID();
+        final String accountKey2 = UUID.randomUUID().toString();
+        final BusinessInvoice invoice2 = createInvoice(invoiceId2, accountKey2);
+
+        // Create both invoices
+        Assert.assertEquals(invoiceSqlDao.createInvoice(invoice1), 1);
+        Assert.assertEquals(invoiceSqlDao.createInvoice(invoice2), 1);
+
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountKey1).size(), 1);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountKey2).size(), 1);
+
+        // Remove the first invoice
+        Assert.assertEquals(invoiceSqlDao.deleteInvoice(invoice1.getInvoiceId().toString()), 1);
+
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountKey1).size(), 0);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(accountKey2).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            invoiceSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+
+    private BusinessInvoice createInvoice(final UUID invoiceId, final String accountKey) {
+        final BigDecimal amountCharged = BigDecimal.ZERO;
+        final BigDecimal amountCredited = BigDecimal.ONE;
+        final BigDecimal amountPaid = BigDecimal.TEN;
+        final BigDecimal balance = BigDecimal.valueOf(123L);
+        final DateTime createdDate = new DateTime(DateTimeZone.UTC);
+        final Currency currency = Currency.MXN;
+        final DateTime invoiceDate = new DateTime(DateTimeZone.UTC);
+        final DateTime targetDate = new DateTime(DateTimeZone.UTC);
+        final DateTime updatedDate = new DateTime(DateTimeZone.UTC);
+
+        return new BusinessInvoice(accountKey, amountCharged, amountCredited, amountPaid, balance,
+                                   createdDate, currency, invoiceDate, invoiceId, targetDate, updatedDate);
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java
new file mode 100644
index 0000000..24ee93f
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessInvoiceTagSqlDao.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessInvoiceTag;
+
+public class TestBusinessInvoiceTagSqlDao extends TestWithEmbeddedDB {
+    private BusinessInvoiceTagSqlDao invoiceTagSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        invoiceTagSqlDao = dbi.onDemand(BusinessInvoiceTagSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final String invoiceId = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString().substring(0, 20);
+
+        // Verify initial state
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId).size(), 0);
+        Assert.assertEquals(invoiceTagSqlDao.removeTag(invoiceId, name), 0);
+
+        // Add an entry
+        Assert.assertEquals(invoiceTagSqlDao.addTag(invoiceId, name), 1);
+        final List<BusinessInvoiceTag> tagsForInvoice = invoiceTagSqlDao.getTagsForInvoice(invoiceId);
+        Assert.assertEquals(tagsForInvoice.size(), 1);
+
+        // Retrieve it
+        final BusinessInvoiceTag invoiceTag = tagsForInvoice.get(0);
+        Assert.assertEquals(invoiceTag.getInvoiceId().toString(), invoiceId);
+        Assert.assertEquals(invoiceTag.getName(), name);
+
+        // Delete it
+        Assert.assertEquals(invoiceTagSqlDao.removeTag(invoiceId, name), 1);
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final String invoiceId1 = UUID.randomUUID().toString();
+        final String name1 = UUID.randomUUID().toString().substring(0, 20);
+        final String invoiceId2 = UUID.randomUUID().toString();
+        final String name2 = UUID.randomUUID().toString().substring(0, 20);
+
+        // Add a tag to both invoices
+        Assert.assertEquals(invoiceTagSqlDao.addTag(invoiceId1, name1), 1);
+        Assert.assertEquals(invoiceTagSqlDao.addTag(invoiceId2, name2), 1);
+
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId1).size(), 1);
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId2).size(), 1);
+
+        // Remove the tag for the first invoice
+        Assert.assertEquals(invoiceTagSqlDao.removeTag(invoiceId1, name1), 1);
+
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId1).size(), 0);
+        Assert.assertEquals(invoiceTagSqlDao.getTagsForInvoice(invoiceId2).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            invoiceTagSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java
new file mode 100644
index 0000000..c16ab3c
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessOverdueStatusSqlDao.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessOverdueStatus;
+
+public class TestBusinessOverdueStatusSqlDao extends TestWithEmbeddedDB {
+    private BusinessOverdueStatusSqlDao overdueStatusSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        overdueStatusSqlDao = dbi.onDemand(BusinessOverdueStatusSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCreate() throws Exception {
+        final String externalKey = UUID.randomUUID().toString();
+        final BusinessOverdueStatus firstOverdueStatus = createOverdueStatus(externalKey);
+
+        // Verify initial state
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundle(externalKey).size(), 0);
+
+        // Add the overdue status
+        Assert.assertEquals(overdueStatusSqlDao.createOverdueStatus(firstOverdueStatus), 1);
+
+        // Retrieve it
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundle(externalKey).size(), 1);
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundle(externalKey).get(0), firstOverdueStatus);
+
+        // Add a second one
+        final BusinessOverdueStatus secondOverdueStatus = createOverdueStatus(externalKey);
+        Assert.assertEquals(overdueStatusSqlDao.createOverdueStatus(secondOverdueStatus), 1);
+
+        // Retrieve both
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundle(externalKey).size(), 2);
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundle(externalKey).get(0), firstOverdueStatus);
+        Assert.assertEquals(overdueStatusSqlDao.getOverdueStatusesForBundle(externalKey).get(1), secondOverdueStatus);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            overdueStatusSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+
+    private BusinessOverdueStatus createOverdueStatus(final String externalKey) {
+        final DateTime endDate = new DateTime(DateTimeZone.UTC);
+        final DateTime startDate = new DateTime(DateTimeZone.UTC);
+        final String status = UUID.randomUUID().toString();
+
+        return new BusinessOverdueStatus(endDate, externalKey, startDate, status);
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java
new file mode 100644
index 0000000..5233229
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionFieldSqlDao.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionField;
+
+public class TestBusinessSubscriptionTransitionFieldSqlDao extends TestWithEmbeddedDB {
+    private BusinessSubscriptionTransitionFieldSqlDao subscriptionTransitionFieldSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        subscriptionTransitionFieldSqlDao = dbi.onDemand(BusinessSubscriptionTransitionFieldSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final String externalKey = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString().substring(0, 30);
+        final String value = UUID.randomUUID().toString();
+
+        // Verify initial state
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransition(externalKey).size(), 0);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.removeField(externalKey, name), 0);
+
+        // Add an entry
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.addField(externalKey, name, value), 1);
+        final List<BusinessSubscriptionTransitionField> fieldsForBusinessSubscriptionTransition = subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransition(externalKey);
+        Assert.assertEquals(fieldsForBusinessSubscriptionTransition.size(), 1);
+
+        // Retrieve it
+        final BusinessSubscriptionTransitionField subscriptionTransitionField = fieldsForBusinessSubscriptionTransition.get(0);
+        Assert.assertEquals(subscriptionTransitionField.getExternalKey(), externalKey);
+        Assert.assertEquals(subscriptionTransitionField.getName(), name);
+        Assert.assertEquals(subscriptionTransitionField.getValue(), value);
+
+        // Delete it
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.removeField(externalKey, name), 1);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransition(externalKey).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final String externalKey1 = UUID.randomUUID().toString();
+        final String name1 = UUID.randomUUID().toString().substring(0, 30);
+        final String externalKey2 = UUID.randomUUID().toString();
+        final String name2 = UUID.randomUUID().toString().substring(0, 30);
+
+        // Add a field to both transitions
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.addField(externalKey1, name1, UUID.randomUUID().toString()), 1);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.addField(externalKey2, name2, UUID.randomUUID().toString()), 1);
+
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransition(externalKey1).size(), 1);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransition(externalKey2).size(), 1);
+
+        // Remove the field for the first transition
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.removeField(externalKey1, name1), 1);
+
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransition(externalKey1).size(), 0);
+        Assert.assertEquals(subscriptionTransitionFieldSqlDao.getFieldsForBusinessSubscriptionTransition(externalKey2).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            subscriptionTransitionFieldSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java
new file mode 100644
index 0000000..8b4740f
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestBusinessSubscriptionTransitionTagSqlDao.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransitionTag;
+
+public class TestBusinessSubscriptionTransitionTagSqlDao extends TestWithEmbeddedDB {
+    private BusinessSubscriptionTransitionTagSqlDao subscriptionTransitionTagSqlDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        subscriptionTransitionTagSqlDao = dbi.onDemand(BusinessSubscriptionTransitionTagSqlDao.class);
+    }
+
+    @Test(groups = "slow")
+    public void testCRUD() throws Exception {
+        final String externalKey = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString().substring(0, 20);
+
+        // Verify initial state
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransition(externalKey).size(), 0);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.removeTag(externalKey, name), 0);
+
+        // Add an entry
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.addTag(externalKey, name), 1);
+        final List<BusinessSubscriptionTransitionTag> tagsForBusinessSubscriptionTransition = subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransition(externalKey);
+        Assert.assertEquals(tagsForBusinessSubscriptionTransition.size(), 1);
+
+        // Retrieve it
+        final BusinessSubscriptionTransitionTag subscriptionTransitionTag = tagsForBusinessSubscriptionTransition.get(0);
+        Assert.assertEquals(subscriptionTransitionTag.getExternalKey(), externalKey);
+        Assert.assertEquals(subscriptionTransitionTag.getName(), name);
+
+        // Delete it
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.removeTag(externalKey, name), 1);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransition(externalKey).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testSegmentation() throws Exception {
+        final String externalKey1 = UUID.randomUUID().toString();
+        final String name1 = UUID.randomUUID().toString().substring(0, 20);
+        final String externalKey2 = UUID.randomUUID().toString();
+        final String name2 = UUID.randomUUID().toString().substring(0, 20);
+
+        // Add a tag to both transitions
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.addTag(externalKey1, name1), 1);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.addTag(externalKey2, name2), 1);
+
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransition(externalKey1).size(), 1);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransition(externalKey2).size(), 1);
+
+        // Remove the tag for the first transition
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.removeTag(externalKey1, name1), 1);
+
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransition(externalKey1).size(), 0);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransition(externalKey2).size(), 1);
+    }
+
+    @Test(groups = "slow")
+    public void testHealthCheck() throws Exception {
+        // HealthCheck test to make sure MySQL is setup properly
+        try {
+            subscriptionTransitionTagSqlDao.test();
+        } catch (Throwable t) {
+            Assert.fail(t.toString());
+        }
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestDefaultAnalyticsDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestDefaultAnalyticsDao.java
new file mode 100644
index 0000000..7ab6a66
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestDefaultAnalyticsDao.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.dao;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.TestWithEmbeddedDB;
+import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.catalog.api.Currency;
+
+public class TestDefaultAnalyticsDao extends TestWithEmbeddedDB {
+    private BusinessAccountSqlDao accountSqlDao;
+    private BusinessInvoiceSqlDao invoiceSqlDao;
+    private BusinessInvoiceItemSqlDao invoiceItemSqlDao;
+    private AnalyticsDao analyticsDao;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        accountSqlDao = dbi.onDemand(BusinessAccountSqlDao.class);
+        final BusinessSubscriptionTransitionSqlDao subscriptionTransitionSqlDao = dbi.onDemand(BusinessSubscriptionTransitionSqlDao.class);
+        invoiceSqlDao = dbi.onDemand(BusinessInvoiceSqlDao.class);
+        invoiceItemSqlDao = dbi.onDemand(BusinessInvoiceItemSqlDao.class);
+        final BusinessAccountTagSqlDao accountTagSqlDao = dbi.onDemand(BusinessAccountTagSqlDao.class);
+        analyticsDao = new DefaultAnalyticsDao(accountSqlDao, subscriptionTransitionSqlDao, invoiceSqlDao, invoiceItemSqlDao, accountTagSqlDao);
+    }
+
+    @Test(groups = "slow")
+    public void testCreateInvoice() throws Exception {
+        // Create and verify the initial state
+        BusinessAccount account = new BusinessAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(),
+                                                      BigDecimal.ONE, new DateTime(DateTimeZone.UTC), BigDecimal.TEN,
+                                                      "ERROR_NOT_ENOUGH_FUNDS", "CreditCard", "Visa", "FRANCE");
+        Assert.assertEquals(accountSqlDao.createAccount(account), 1);
+        Assert.assertEquals(invoiceSqlDao.getInvoicesForAccount(account.getKey()).size(), 0);
+        account = accountSqlDao.getAccount(account.getKey());
+
+        // Generate the invoices
+        final BusinessInvoice invoice = createInvoice(account.getKey());
+        final List<BusinessInvoiceItem> invoiceItems = new ArrayList<BusinessInvoiceItem>();
+        for (int i = 0; i < 10; i++) {
+            invoiceItems.add(createInvoiceItem(invoice.getInvoiceId(), BigDecimal.valueOf(1242 + i)));
+        }
+        analyticsDao.createInvoice(account.getKey(), invoice, invoiceItems);
+
+        // Verify the final state
+        final List<BusinessInvoice> invoicesForAccount = invoiceSqlDao.getInvoicesForAccount(account.getKey());
+        Assert.assertEquals(invoicesForAccount.size(), 1);
+        Assert.assertEquals(invoicesForAccount.get(0).getInvoiceId(), invoice.getInvoiceId());
+
+        Assert.assertEquals(invoiceItemSqlDao.getInvoiceItemsForInvoice(invoice.getInvoiceId().toString()).size(), 10);
+
+        final BusinessAccount finalAccount = accountSqlDao.getAccount(account.getKey());
+        Assert.assertEquals(finalAccount.getCreatedDt(), account.getCreatedDt());
+        Assert.assertTrue(finalAccount.getUpdatedDt().isAfter(account.getCreatedDt()));
+        Assert.assertTrue(finalAccount.getUpdatedDt().isAfter(account.getUpdatedDt()));
+        Assert.assertTrue(finalAccount.getLastInvoiceDate().equals(invoice.getInvoiceDate()));
+        // invoice.getBalance() is not the sum of all the items here - but in practice it will be
+        Assert.assertEquals(finalAccount.getTotalInvoiceBalance(), account.getTotalInvoiceBalance().add(invoice.getBalance()));
+    }
+
+    private BusinessInvoice createInvoice(final String accountKey) {
+        final BigDecimal amountCharged = BigDecimal.ZERO;
+        final BigDecimal amountCredited = BigDecimal.ONE;
+        final BigDecimal amountPaid = BigDecimal.TEN;
+        final BigDecimal balance = BigDecimal.valueOf(123L);
+        final DateTime createdDate = new DateTime(DateTimeZone.UTC);
+        final Currency currency = Currency.MXN;
+        final DateTime invoiceDate = new DateTime(DateTimeZone.UTC);
+        final UUID invoiceId = UUID.randomUUID();
+        final DateTime targetDate = new DateTime(DateTimeZone.UTC);
+        final DateTime updatedDate = new DateTime(DateTimeZone.UTC);
+
+        return new BusinessInvoice(accountKey, amountCharged, amountCredited, amountPaid, balance,
+                                   createdDate, currency, invoiceDate, invoiceId, targetDate, updatedDate);
+    }
+
+    private BusinessInvoiceItem createInvoiceItem(final UUID invoiceId, final BigDecimal amount) {
+        final String billingPeriod = UUID.randomUUID().toString().substring(0, 20);
+        final DateTime createdDate = new DateTime(DateTimeZone.UTC);
+        final Currency currency = Currency.AUD;
+        final DateTime endDate = new DateTime(DateTimeZone.UTC);
+        final String externalKey = UUID.randomUUID().toString();
+        final UUID itemId = UUID.randomUUID();
+        final String itemType = UUID.randomUUID().toString().substring(0, 20);
+        final String phase = UUID.randomUUID().toString().substring(0, 20);
+        final String productCategory = UUID.randomUUID().toString().substring(0, 20);
+        final String productName = UUID.randomUUID().toString().substring(0, 20);
+        final String productType = UUID.randomUUID().toString().substring(0, 20);
+        final String slug = UUID.randomUUID().toString().substring(0, 20);
+        final DateTime startDate = new DateTime(DateTimeZone.UTC);
+        final DateTime updatedDate = new DateTime(DateTimeZone.UTC);
+
+        return new BusinessInvoiceItem(amount, billingPeriod, createdDate, currency,
+                                       endDate, externalKey, invoiceId, itemId, itemType,
+                                       phase, productCategory, productName, productType,
+                                       slug, startDate, updatedDate);
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java b/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java
index 2bc723b..6810e0e 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.analytics;
 
-import org.apache.commons.lang.NotImplementedException;
 import org.joda.time.DateTime;
 import org.joda.time.Period;
 
@@ -37,8 +36,8 @@ public class MockDuration {
             }
 
             @Override
-            public DateTime addToDateTime(DateTime dateTime) {
-                throw new NotImplementedException();
+            public DateTime addToDateTime(final DateTime dateTime) {
+                throw new UnsupportedOperationException();
             }
 
             @Override
@@ -61,8 +60,8 @@ public class MockDuration {
             }
 
             @Override
-            public DateTime addToDateTime(DateTime dateTime) {
-                throw new NotImplementedException();
+            public DateTime addToDateTime(final DateTime dateTime) {
+                throw new UnsupportedOperationException();
             }
 
             @Override
@@ -85,8 +84,8 @@ public class MockDuration {
             }
 
             @Override
-            public DateTime addToDateTime(DateTime dateTime) {
-                throw new NotImplementedException();
+            public DateTime addToDateTime(final DateTime dateTime) {
+                throw new UnsupportedOperationException();
             }
 
             @Override
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockPlan.java b/analytics/src/test/java/com/ning/billing/analytics/MockPlan.java
index 49dc993..3bb28c2 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockPlan.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockPlan.java
@@ -82,7 +82,7 @@ public class MockPlan implements Plan {
     }
 
     @Override
-    public PlanPhase findPhase(String name) throws CatalogApiException {
+    public PlanPhase findPhase(final String name) throws CatalogApiException {
         throw new UnsupportedOperationException();
     }
 
@@ -93,7 +93,7 @@ public class MockPlan implements Plan {
 
     @Override
     public DateTime dateOfFirstRecurringNonZeroCharge(
-            DateTime subscriptionStartDate) {
+            final DateTime subscriptionStartDate) {
         throw new UnsupportedOperationException();
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java b/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
index 385599f..c6dc330 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
@@ -50,12 +50,12 @@ public class MockSubscription implements Subscription {
     }
 
     @Override
-    public boolean cancel(DateTime requestedDate, boolean eot, CallContext context) {
+    public boolean cancel(final DateTime requestedDate, final boolean eot, final CallContext context) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public boolean changePlan(final String productName, final BillingPeriod term, final String planSet, DateTime requestedDate, CallContext context) {
+    public boolean changePlan(final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate, final CallContext context) {
         throw new UnsupportedOperationException();
     }
 
@@ -91,7 +91,7 @@ public class MockSubscription implements Subscription {
 
 
     @Override
-    public boolean uncancel(CallContext context) throws EntitlementUserApiException {
+    public boolean uncancel(final CallContext context) throws EntitlementUserApiException {
         throw new UnsupportedOperationException();
     }
 
@@ -131,7 +131,7 @@ public class MockSubscription implements Subscription {
     }
 
     @Override
-    public boolean recreate(PlanPhaseSpecifier spec, DateTime requestedDate, CallContext context)
+    public boolean recreate(final PlanPhaseSpecifier spec, final DateTime requestedDate, final CallContext context)
             throws EntitlementUserApiException {
         throw new UnsupportedOperationException();
     }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountField.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountField.java
new file mode 100644
index 0000000..ebe3c9e
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountField.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+
+public class TestBusinessAccountField extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final String accountKey = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString();
+        final String value = UUID.randomUUID().toString();
+        final BusinessAccountField accountField = new BusinessAccountField(accountKey,
+                                                                           name,
+                                                                           value);
+        Assert.assertSame(accountField, accountField);
+        Assert.assertEquals(accountField, accountField);
+        Assert.assertTrue(accountField.equals(accountField));
+        Assert.assertEquals(accountField.getAccountKey(), accountKey);
+        Assert.assertEquals(accountField.getName(), name);
+        Assert.assertEquals(accountField.getValue(), value);
+
+        final BusinessAccountField otherAccountField = new BusinessAccountField(UUID.randomUUID().toString(),
+                                                                                UUID.randomUUID().toString(),
+                                                                                UUID.randomUUID().toString());
+        Assert.assertFalse(accountField.equals(otherAccountField));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountTag.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountTag.java
new file mode 100644
index 0000000..1d9c072
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessAccountTag.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+
+public class TestBusinessAccountTag extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final String accountKey = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString();
+        final BusinessAccountTag accountTag = new BusinessAccountTag(accountKey, name);
+        Assert.assertSame(accountTag, accountTag);
+        Assert.assertEquals(accountTag, accountTag);
+        Assert.assertTrue(accountTag.equals(accountTag));
+        Assert.assertEquals(accountTag.getAccountKey(), accountKey);
+        Assert.assertEquals(accountTag.getName(), name);
+
+        final BusinessAccountTag otherAccountTag = new BusinessAccountTag(UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        Assert.assertFalse(accountTag.equals(otherAccountTag));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoice.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoice.java
new file mode 100644
index 0000000..869284d
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoice.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+import com.ning.billing.catalog.api.Currency;
+
+public class TestBusinessInvoice extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final String accountKey = UUID.randomUUID().toString();
+        final BigDecimal amountCharged = BigDecimal.ZERO;
+        final BigDecimal amountCredited = BigDecimal.ONE;
+        final BigDecimal amountPaid = BigDecimal.TEN;
+        final BigDecimal balance = BigDecimal.valueOf(123L);
+        final DateTime createdDate = new DateTime(DateTimeZone.UTC);
+        final Currency currency = Currency.MXN;
+        final DateTime invoiceDate = new DateTime(DateTimeZone.UTC);
+        final UUID invoiceId = UUID.randomUUID();
+        final DateTime targetDate = new DateTime(DateTimeZone.UTC);
+        final DateTime updatedDate = new DateTime(DateTimeZone.UTC);
+        final BusinessInvoice invoice = new BusinessInvoice(accountKey, amountCharged, amountCredited, amountPaid, balance,
+                                                            createdDate, currency, invoiceDate, invoiceId, targetDate, updatedDate);
+        Assert.assertSame(invoice, invoice);
+        Assert.assertEquals(invoice, invoice);
+        Assert.assertTrue(invoice.equals(invoice));
+        Assert.assertEquals(invoice.getAccountKey(), accountKey);
+        Assert.assertEquals(invoice.getAmountCharged(), amountCharged);
+        Assert.assertEquals(invoice.getAmountCredited(), amountCredited);
+        Assert.assertEquals(invoice.getAmountPaid(), amountPaid);
+        Assert.assertEquals(invoice.getBalance(), balance);
+        Assert.assertEquals(invoice.getCreatedDate(), createdDate);
+        Assert.assertEquals(invoice.getCurrency(), currency);
+        Assert.assertEquals(invoice.getInvoiceDate(), invoiceDate);
+        Assert.assertEquals(invoice.getInvoiceId(), invoiceId);
+        Assert.assertEquals(invoice.getTargetDate(), targetDate);
+        Assert.assertEquals(invoice.getUpdatedDate(), updatedDate);
+
+        final BusinessInvoice otherInvoice = new BusinessInvoice(null, null, null, null, null, createdDate, null,
+                                                                 null, invoiceId, null, null);
+        Assert.assertFalse(invoice.equals(otherInvoice));
+
+        // Test setters
+        otherInvoice.setAccountKey(accountKey);
+        otherInvoice.setAmountCharged(amountCharged);
+        otherInvoice.setAmountCredited(amountCredited);
+        otherInvoice.setAmountPaid(amountPaid);
+        otherInvoice.setBalance(balance);
+        otherInvoice.setCurrency(currency);
+        otherInvoice.setInvoiceDate(invoiceDate);
+        otherInvoice.setTargetDate(targetDate);
+        otherInvoice.setUpdatedDate(updatedDate);
+        Assert.assertTrue(invoice.equals(otherInvoice));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceField.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceField.java
new file mode 100644
index 0000000..b2c0937
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceField.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+
+public class TestBusinessInvoiceField extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final UUID invoiceId = UUID.randomUUID();
+        final String name = UUID.randomUUID().toString();
+        final String value = UUID.randomUUID().toString();
+        final BusinessInvoiceField invoiceField = new BusinessInvoiceField(invoiceId,
+                                                                           name,
+                                                                           value);
+        Assert.assertSame(invoiceField, invoiceField);
+        Assert.assertEquals(invoiceField, invoiceField);
+        Assert.assertTrue(invoiceField.equals(invoiceField));
+        Assert.assertEquals(invoiceField.getInvoiceId(), invoiceId);
+        Assert.assertEquals(invoiceField.getName(), name);
+        Assert.assertEquals(invoiceField.getValue(), value);
+
+        final BusinessInvoiceField otherInvoiceField = new BusinessInvoiceField(UUID.randomUUID(),
+                                                                                UUID.randomUUID().toString(),
+                                                                                UUID.randomUUID().toString());
+        Assert.assertFalse(invoiceField.equals(otherInvoiceField));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceItem.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceItem.java
new file mode 100644
index 0000000..e4460f6
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceItem.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+import com.ning.billing.catalog.api.Currency;
+
+public class TestBusinessInvoiceItem extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final BigDecimal amount = BigDecimal.TEN;
+        final String billingPeriod = UUID.randomUUID().toString();
+        final DateTime createdDate = new DateTime(DateTimeZone.UTC);
+        final Currency currency = Currency.AUD;
+        final DateTime endDate = new DateTime(DateTimeZone.UTC);
+        final String externalKey = UUID.randomUUID().toString();
+        final UUID invoiceId = UUID.randomUUID();
+        final UUID itemId = UUID.randomUUID();
+        final String itemType = UUID.randomUUID().toString();
+        final String phase = UUID.randomUUID().toString();
+        final String productCategory = UUID.randomUUID().toString();
+        final String productName = UUID.randomUUID().toString();
+        final String productType = UUID.randomUUID().toString();
+        final String slug = UUID.randomUUID().toString();
+        final DateTime startDate = new DateTime(DateTimeZone.UTC);
+        final DateTime updatedDate = new DateTime(DateTimeZone.UTC);
+        final BusinessInvoiceItem invoiceItem = new BusinessInvoiceItem(amount, billingPeriod, createdDate, currency,
+                                                                        endDate, externalKey, invoiceId, itemId, itemType,
+                                                                        phase, productCategory, productName, productType,
+                                                                        slug, startDate, updatedDate);
+        Assert.assertSame(invoiceItem, invoiceItem);
+        Assert.assertEquals(invoiceItem, invoiceItem);
+        Assert.assertTrue(invoiceItem.equals(invoiceItem));
+        Assert.assertEquals(invoiceItem.getAmount(), amount);
+        Assert.assertEquals(invoiceItem.getBillingPeriod(), billingPeriod);
+        Assert.assertEquals(invoiceItem.getCreatedDate(), createdDate);
+        Assert.assertEquals(invoiceItem.getCurrency(), currency);
+        Assert.assertEquals(invoiceItem.getEndDate(), endDate);
+        Assert.assertEquals(invoiceItem.getExternalKey(), externalKey);
+        Assert.assertEquals(invoiceItem.getInvoiceId(), invoiceId);
+        Assert.assertEquals(invoiceItem.getItemId(), itemId);
+        Assert.assertEquals(invoiceItem.getItemType(), itemType);
+        Assert.assertEquals(invoiceItem.getPhase(), phase);
+        Assert.assertEquals(invoiceItem.getProductCategory(), productCategory);
+        Assert.assertEquals(invoiceItem.getProductName(), productName);
+        Assert.assertEquals(invoiceItem.getProductType(), productType);
+        Assert.assertEquals(invoiceItem.getSlug(), slug);
+        Assert.assertEquals(invoiceItem.getStartDate(), startDate);
+        Assert.assertEquals(invoiceItem.getUpdatedDate(), updatedDate);
+
+        final BusinessInvoiceItem otherInvoiceItem = new BusinessInvoiceItem(null, null, createdDate, null, null, null, null, itemId,
+                                                                             null, null, null, null, null, null, null, null);
+        Assert.assertFalse(invoiceItem.equals(otherInvoiceItem));
+
+        // Test setters
+        otherInvoiceItem.setAmount(amount);
+        otherInvoiceItem.setBillingPeriod(billingPeriod);
+        otherInvoiceItem.setCurrency(currency);
+        otherInvoiceItem.setEndDate(endDate);
+        otherInvoiceItem.setExternalKey(externalKey);
+        otherInvoiceItem.setInvoiceId(invoiceId);
+        otherInvoiceItem.setItemType(itemType);
+        otherInvoiceItem.setPhase(phase);
+        otherInvoiceItem.setProductCategory(productCategory);
+        otherInvoiceItem.setProductName(productName);
+        otherInvoiceItem.setProductType(productType);
+        otherInvoiceItem.setSlug(slug);
+        otherInvoiceItem.setStartDate(startDate);
+        otherInvoiceItem.setUpdatedDate(updatedDate);
+        Assert.assertTrue(invoiceItem.equals(otherInvoiceItem));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePayment.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePayment.java
new file mode 100644
index 0000000..709db0f
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePayment.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+import com.ning.billing.catalog.api.Currency;
+
+public class TestBusinessInvoicePayment extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final String accountKey = UUID.randomUUID().toString();
+        final BigDecimal amount = BigDecimal.ONE;
+        final UUID attemptId = UUID.randomUUID();
+        final String cardCountry = UUID.randomUUID().toString();
+        final String cardType = UUID.randomUUID().toString();
+        final DateTime createdDate = new DateTime(DateTimeZone.UTC);
+        final Currency currency = Currency.BRL;
+        final DateTime effectiveDate = new DateTime(DateTimeZone.UTC);
+        final UUID invoiceId = UUID.randomUUID();
+        final String paymentError = UUID.randomUUID().toString();
+        final UUID paymentId = UUID.randomUUID();
+        final String paymentMethod = UUID.randomUUID().toString();
+        final String paymentType = UUID.randomUUID().toString();
+        final String pluginName = UUID.randomUUID().toString();
+        final String processingStatus = UUID.randomUUID().toString();
+        final BigDecimal requestedAmount = BigDecimal.ZERO;
+        final DateTime updatedDate = new DateTime(DateTimeZone.UTC);
+        final BusinessInvoicePayment invoicePayment = new BusinessInvoicePayment(accountKey, amount, attemptId,
+                                                                                 cardCountry, cardType, createdDate,
+                                                                                 currency, effectiveDate, invoiceId,
+                                                                                 paymentError, paymentId, paymentMethod,
+                                                                                 paymentType, pluginName, processingStatus,
+                                                                                 requestedAmount, updatedDate);
+        Assert.assertSame(invoicePayment, invoicePayment);
+        Assert.assertEquals(invoicePayment, invoicePayment);
+        Assert.assertTrue(invoicePayment.equals(invoicePayment));
+        Assert.assertEquals(invoicePayment.getAccountKey(), accountKey);
+        Assert.assertEquals(invoicePayment.getAmount(), amount);
+        Assert.assertEquals(invoicePayment.getAttemptId(), attemptId);
+        Assert.assertEquals(invoicePayment.getCardCountry(), cardCountry);
+        Assert.assertEquals(invoicePayment.getCardType(), cardType);
+        Assert.assertEquals(invoicePayment.getCreatedDate(), createdDate);
+        Assert.assertEquals(invoicePayment.getCurrency(), currency);
+        Assert.assertEquals(invoicePayment.getEffectiveDate(), effectiveDate);
+        Assert.assertEquals(invoicePayment.getInvoiceId(), invoiceId);
+        Assert.assertEquals(invoicePayment.getPaymentError(), paymentError);
+        Assert.assertEquals(invoicePayment.getPaymentId(), paymentId);
+        Assert.assertEquals(invoicePayment.getPaymentMethod(), paymentMethod);
+        Assert.assertEquals(invoicePayment.getPaymentType(), paymentType);
+        Assert.assertEquals(invoicePayment.getPluginName(), pluginName);
+        Assert.assertEquals(invoicePayment.getProcessingStatus(), processingStatus);
+        Assert.assertEquals(invoicePayment.getRequestedAmount(), requestedAmount);
+        Assert.assertEquals(invoicePayment.getUpdatedDate(), updatedDate);
+
+        final BusinessInvoicePayment otherInvoicePayment = new BusinessInvoicePayment(null, null, attemptId, null, null, createdDate,
+                                                                                      null, null, null, null, paymentId, null,
+                                                                                      null, null, null, null, null);
+        Assert.assertFalse(invoicePayment.equals(otherInvoicePayment));
+
+        // Test setters
+        otherInvoicePayment.setAccountKey(accountKey);
+        otherInvoicePayment.setAmount(amount);
+        otherInvoicePayment.setCardCountry(cardCountry);
+        otherInvoicePayment.setCardType(cardType);
+        otherInvoicePayment.setCurrency(currency);
+        otherInvoicePayment.setEffectiveDate(effectiveDate);
+        otherInvoicePayment.setInvoiceId(invoiceId);
+        otherInvoicePayment.setPaymentError(paymentError);
+        otherInvoicePayment.setPaymentMethod(paymentMethod);
+        otherInvoicePayment.setPaymentType(paymentType);
+        otherInvoicePayment.setPluginName(pluginName);
+        otherInvoicePayment.setProcessingStatus(processingStatus);
+        otherInvoicePayment.setRequestedAmount(requestedAmount);
+        otherInvoicePayment.setUpdatedDate(updatedDate);
+        Assert.assertTrue(invoicePayment.equals(otherInvoicePayment));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentField.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentField.java
new file mode 100644
index 0000000..2d73c48
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentField.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+
+public class TestBusinessInvoicePaymentField extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final UUID paymentId = UUID.randomUUID();
+        final String name = UUID.randomUUID().toString();
+        final String value = UUID.randomUUID().toString();
+        final BusinessInvoicePaymentField invoiceField = new BusinessInvoicePaymentField(paymentId,
+                                                                                         name,
+                                                                                         value);
+        Assert.assertSame(invoiceField, invoiceField);
+        Assert.assertEquals(invoiceField, invoiceField);
+        Assert.assertTrue(invoiceField.equals(invoiceField));
+        Assert.assertEquals(invoiceField.getPaymentId(), paymentId);
+        Assert.assertEquals(invoiceField.getName(), name);
+        Assert.assertEquals(invoiceField.getValue(), value);
+
+        final BusinessInvoicePaymentField otherInvoicePaymentField = new BusinessInvoicePaymentField(UUID.randomUUID(),
+                                                                                                     UUID.randomUUID().toString(),
+                                                                                                     UUID.randomUUID().toString());
+        Assert.assertFalse(invoiceField.equals(otherInvoicePaymentField));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentTag.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentTag.java
new file mode 100644
index 0000000..b5ae515
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoicePaymentTag.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+
+public class TestBusinessInvoicePaymentTag extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final UUID paymentId = UUID.randomUUID();
+        final String name = UUID.randomUUID().toString();
+        final BusinessInvoicePaymentTag invoicePaymentTag = new BusinessInvoicePaymentTag(paymentId, name);
+        Assert.assertSame(invoicePaymentTag, invoicePaymentTag);
+        Assert.assertEquals(invoicePaymentTag, invoicePaymentTag);
+        Assert.assertTrue(invoicePaymentTag.equals(invoicePaymentTag));
+        Assert.assertEquals(invoicePaymentTag.getPaymentId(), paymentId);
+        Assert.assertEquals(invoicePaymentTag.getName(), name);
+
+        final BusinessInvoicePaymentTag otherInvoicePaymentTag = new BusinessInvoicePaymentTag(UUID.randomUUID(),
+                                                                                               UUID.randomUUID().toString());
+        Assert.assertFalse(invoicePaymentTag.equals(otherInvoicePaymentTag));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceTag.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceTag.java
new file mode 100644
index 0000000..3e92eae
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessInvoiceTag.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+
+public class TestBusinessInvoiceTag extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final UUID invoiceId = UUID.randomUUID();
+        final String name = UUID.randomUUID().toString();
+        final BusinessInvoiceTag invoiceTag = new BusinessInvoiceTag(invoiceId, name);
+        Assert.assertSame(invoiceTag, invoiceTag);
+        Assert.assertEquals(invoiceTag, invoiceTag);
+        Assert.assertTrue(invoiceTag.equals(invoiceTag));
+        Assert.assertEquals(invoiceTag.getInvoiceId(), invoiceId);
+        Assert.assertEquals(invoiceTag.getName(), name);
+
+        final BusinessInvoiceTag otherInvoiceTag = new BusinessInvoiceTag(UUID.randomUUID(), UUID.randomUUID().toString());
+        Assert.assertFalse(invoiceTag.equals(otherInvoiceTag));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessOverdueStatus.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessOverdueStatus.java
new file mode 100644
index 0000000..b92ee12
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessOverdueStatus.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+
+public class TestBusinessOverdueStatus extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final DateTime endDate = new DateTime(DateTimeZone.UTC);
+        final String externalKey = UUID.randomUUID().toString();
+        final DateTime startDate = new DateTime(DateTimeZone.UTC);
+        final String status = UUID.randomUUID().toString();
+        final BusinessOverdueStatus overdueStatus = new BusinessOverdueStatus(endDate, externalKey, startDate, status);
+        Assert.assertSame(overdueStatus, overdueStatus);
+        Assert.assertEquals(overdueStatus, overdueStatus);
+        Assert.assertTrue(overdueStatus.equals(overdueStatus));
+        Assert.assertEquals(overdueStatus.getEndDate(), endDate);
+        Assert.assertEquals(overdueStatus.getExternalKey(), externalKey);
+        Assert.assertEquals(overdueStatus.getStartDate(), startDate);
+        Assert.assertEquals(overdueStatus.getStatus(), status);
+
+        final BusinessOverdueStatus otherOverdueStatus = new BusinessOverdueStatus(new DateTime(DateTimeZone.UTC), UUID.randomUUID().toString(),
+                                                                                   new DateTime(DateTimeZone.UTC), UUID.randomUUID().toString());
+        Assert.assertFalse(overdueStatus.equals(otherOverdueStatus));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionField.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionField.java
new file mode 100644
index 0000000..5a1e31b
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionField.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+
+public class TestBusinessSubscriptionTransitionField extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final String externalKey = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString();
+        final String value = UUID.randomUUID().toString();
+        final BusinessSubscriptionTransitionField subscriptionTransitionField = new BusinessSubscriptionTransitionField(externalKey,
+                                                                                                                        name,
+                                                                                                                        value);
+        Assert.assertSame(subscriptionTransitionField, subscriptionTransitionField);
+        Assert.assertEquals(subscriptionTransitionField, subscriptionTransitionField);
+        Assert.assertTrue(subscriptionTransitionField.equals(subscriptionTransitionField));
+        Assert.assertEquals(subscriptionTransitionField.getExternalKey(), externalKey);
+        Assert.assertEquals(subscriptionTransitionField.getName(), name);
+        Assert.assertEquals(subscriptionTransitionField.getValue(), value);
+
+        final BusinessSubscriptionTransitionField otherSubscriptionField = new BusinessSubscriptionTransitionField(UUID.randomUUID().toString(),
+                                                                                                                   UUID.randomUUID().toString(),
+                                                                                                                   UUID.randomUUID().toString());
+        Assert.assertFalse(subscriptionTransitionField.equals(otherSubscriptionField));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionTag.java b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionTag.java
new file mode 100644
index 0000000..b5a40d1
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/model/TestBusinessSubscriptionTransitionTag.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics.model;
+
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.analytics.AnalyticsTestSuite;
+
+public class TestBusinessSubscriptionTransitionTag extends AnalyticsTestSuite {
+    @Test(groups = "fast")
+    public void testEquals() throws Exception {
+        final String externalKey = UUID.randomUUID().toString();
+        final String name = UUID.randomUUID().toString();
+        final BusinessSubscriptionTransitionTag subscriptionTransitionTag = new BusinessSubscriptionTransitionTag(externalKey, name);
+        Assert.assertSame(subscriptionTransitionTag, subscriptionTransitionTag);
+        Assert.assertEquals(subscriptionTransitionTag, subscriptionTransitionTag);
+        Assert.assertTrue(subscriptionTransitionTag.equals(subscriptionTransitionTag));
+        Assert.assertEquals(subscriptionTransitionTag.getExternalKey(), externalKey);
+        Assert.assertEquals(subscriptionTransitionTag.getName(), name);
+
+        final BusinessSubscriptionTransitionTag otherTransitionTag = new BusinessSubscriptionTransitionTag(UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        Assert.assertFalse(subscriptionTransitionTag.equals(otherTransitionTag));
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java b/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
index 6a03abc..0b3287e 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
@@ -27,6 +27,10 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import com.ning.billing.account.api.Account;
+import com.ning.billing.analytics.model.BusinessSubscription;
+import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
@@ -42,13 +46,17 @@ import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
+import com.ning.billing.mock.MockAccountBuilder;
+import com.ning.billing.mock.api.MockAccountUserApi;
+import com.ning.billing.mock.api.MockEntitlementUserApi;
+import com.ning.billing.util.callcontext.CallContext;
 
 public class TestAnalyticsListener extends AnalyticsTestSuite {
-    private static final String KEY = "1234";
+    private static final String EXTERNAL_KEY = "1234";
     private static final String ACCOUNT_KEY = "pierre-1234";
     private final Currency CURRENCY = Currency.BRL;
 
-    private final MockBusinessSubscriptionTransitionDao dao = new MockBusinessSubscriptionTransitionDao();
+    private final MockBusinessSubscriptionTransitionSqlDao dao = new MockBusinessSubscriptionTransitionSqlDao();
     private final UUID subscriptionId = UUID.randomUUID();
     private final UUID bundleUUID = UUID.randomUUID();
     private final Product product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
@@ -59,6 +67,7 @@ public class TestAnalyticsListener extends AnalyticsTestSuite {
     private final CatalogService catalogService = Mockito.mock(CatalogService.class);
     private final Catalog catalog = Mockito.mock(Catalog.class);
 
+    private UUID accountId;
     private AnalyticsListener listener;
 
     @BeforeClass(groups = "fast")
@@ -70,8 +79,16 @@ public class TestAnalyticsListener extends AnalyticsTestSuite {
 
     @BeforeMethod(groups = "fast")
     public void setUp() throws Exception {
-        final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(dao, catalogService, new MockEntitlementUserApi(bundleUUID, KEY), new MockAccountUserApi(ACCOUNT_KEY, CURRENCY));
-        listener = new AnalyticsListener(recorder, null);
+        final MockAccountUserApi accountApi = new MockAccountUserApi();
+        final Account accountData = new MockAccountBuilder().externalKey(ACCOUNT_KEY).currency(CURRENCY).build();
+        final Account account = accountApi.createAccount(accountData, Mockito.mock(CallContext.class));
+        accountId = account.getId();
+
+        final MockEntitlementUserApi entitlementApi = new MockEntitlementUserApi();
+        entitlementApi.addBundle(bundleUUID, EXTERNAL_KEY, accountId);
+
+        final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(dao, catalogService, entitlementApi, accountApi);
+        listener = new AnalyticsListener(recorder, null, null, null);
     }
 
     @Test(groups = "fast")
@@ -80,59 +97,59 @@ public class TestAnalyticsListener extends AnalyticsTestSuite {
         final DateTime effectiveTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedTransitionTime = effectiveTransitionTime;
         final SubscriptionTransitionData firstTransition = createFirstSubscriptionTransition(requestedTransitionTime, effectiveTransitionTime);
-        final BusinessSubscriptionTransition firstBST = createExpectedFirstBST(firstTransition.getId(), requestedTransitionTime, effectiveTransitionTime);
+        final BusinessSubscriptionTransition firstBST = createExpectedFirstBST(firstTransition.getTotalOrdering(), requestedTransitionTime, effectiveTransitionTime);
         listener.handleSubscriptionTransitionChange(new DefaultSubscriptionEvent(firstTransition, effectiveTransitionTime));
-        Assert.assertEquals(dao.getTransitions(KEY).size(), 1);
-        Assert.assertEquals(dao.getTransitions(KEY).get(0), firstBST);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).size(), 1);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).get(0), firstBST);
 
         // Cancel it
         final DateTime effectiveCancelTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedCancelTransitionTime = effectiveCancelTransitionTime;
         final SubscriptionTransitionData cancelledSubscriptionTransition = createCancelSubscriptionTransition(requestedCancelTransitionTime, effectiveCancelTransitionTime, firstTransition.getNextState());
-        final BusinessSubscriptionTransition cancelledBST = createExpectedCancelledBST(cancelledSubscriptionTransition.getId(), requestedCancelTransitionTime, effectiveCancelTransitionTime, firstBST.getNextSubscription());
+        final BusinessSubscriptionTransition cancelledBST = createExpectedCancelledBST(cancelledSubscriptionTransition.getTotalOrdering(), requestedCancelTransitionTime, effectiveCancelTransitionTime, firstBST.getNextSubscription());
         listener.handleSubscriptionTransitionChange(new DefaultSubscriptionEvent(cancelledSubscriptionTransition, effectiveTransitionTime));
-        Assert.assertEquals(dao.getTransitions(KEY).size(), 2);
-        Assert.assertEquals(dao.getTransitions(KEY).get(1), cancelledBST);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).size(), 2);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).get(1), cancelledBST);
 
         // Recreate it
         final DateTime effectiveRecreatedTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedRecreatedTransitionTime = effectiveRecreatedTransitionTime;
         final SubscriptionTransitionData recreatedSubscriptionTransition = createRecreatedSubscriptionTransition(requestedRecreatedTransitionTime, effectiveRecreatedTransitionTime, cancelledSubscriptionTransition.getNextState());
-        final BusinessSubscriptionTransition recreatedBST = createExpectedRecreatedBST(recreatedSubscriptionTransition.getId(), requestedRecreatedTransitionTime, effectiveRecreatedTransitionTime, cancelledBST.getNextSubscription());
+        final BusinessSubscriptionTransition recreatedBST = createExpectedRecreatedBST(recreatedSubscriptionTransition.getTotalOrdering(), requestedRecreatedTransitionTime, effectiveRecreatedTransitionTime, cancelledBST.getNextSubscription());
         listener.handleSubscriptionTransitionChange(new DefaultSubscriptionEvent(recreatedSubscriptionTransition, effectiveTransitionTime));
-        Assert.assertEquals(dao.getTransitions(KEY).size(), 3);
-        Assert.assertEquals(dao.getTransitions(KEY).get(2), recreatedBST);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).size(), 3);
+        Assert.assertEquals(dao.getTransitions(EXTERNAL_KEY).get(2), recreatedBST);
 
     }
 
-    private BusinessSubscriptionTransition createExpectedFirstBST(final UUID id, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime) {
+    private BusinessSubscriptionTransition createExpectedFirstBST(final Long totalOrdering, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime) {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCreated(plan.getName(), catalog, effectiveTransitionTime, effectiveTransitionTime);
 
         final Subscription.SubscriptionState subscriptionState = Subscription.SubscriptionState.ACTIVE;
-        return createExpectedBST(id, event, requestedTransitionTime, effectiveTransitionTime, null, subscriptionState);
+        return createExpectedBST(totalOrdering, event, requestedTransitionTime, effectiveTransitionTime, null, subscriptionState);
     }
 
-    private BusinessSubscriptionTransition createExpectedCancelledBST(final UUID id, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription) {
+    private BusinessSubscriptionTransition createExpectedCancelledBST(final Long totalOrdering, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription) {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCancelled(plan.getName(), catalog, effectiveTransitionTime, effectiveTransitionTime);
-        return createExpectedBST(id, event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, null);
+        return createExpectedBST(totalOrdering, event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, null);
     }
 
-    private BusinessSubscriptionTransition createExpectedRecreatedBST(final UUID id, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription) {
+    private BusinessSubscriptionTransition createExpectedRecreatedBST(final Long totalOrdering, final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription) {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionRecreated(plan.getName(), catalog, effectiveTransitionTime, effectiveTransitionTime);
         final Subscription.SubscriptionState subscriptionState = Subscription.SubscriptionState.ACTIVE;
-        return createExpectedBST(id, event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, subscriptionState);
+        return createExpectedBST(totalOrdering, event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, subscriptionState);
     }
 
     private BusinessSubscriptionTransition createExpectedBST(
-            final UUID eventId,
+            final Long totalOrdering,
             final BusinessSubscriptionEvent eventType,
             final DateTime requestedTransitionTime,
             final DateTime effectiveTransitionTime,
             @Nullable final BusinessSubscription previousSubscription,
             @Nullable final Subscription.SubscriptionState nextState) {
         return new BusinessSubscriptionTransition(
-                eventId,
-                KEY,
+                totalOrdering,
+                EXTERNAL_KEY,
                 ACCOUNT_KEY,
                 requestedTransitionTime,
                 eventType,
@@ -224,4 +241,4 @@ public class TestAnalyticsListener extends AnalyticsTestSuite {
                 true
         );
     }
-}
\ No newline at end of file
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
index b5cf557..531ab7b 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransitionRecorder.java
@@ -26,7 +26,10 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountUserApi;
-import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionDao;
+import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionSqlDao;
+import com.ning.billing.analytics.model.BusinessSubscription;
+import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
 import com.ning.billing.catalog.api.Catalog;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Currency;
@@ -38,14 +41,14 @@ import com.ning.billing.entitlement.api.user.SubscriptionEvent;
 public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSuite {
     @Test(groups = "fast")
     public void testCreateAddOn() throws Exception {
-        final UUID key = UUID.randomUUID();
+        final UUID externalKey = UUID.randomUUID();
 
         // Setup the catalog
         final CatalogService catalogService = Mockito.mock(CatalogService.class);
         Mockito.when(catalogService.getFullCatalog()).thenReturn(Mockito.mock(Catalog.class));
 
         // Setup the dao
-        final BusinessSubscriptionTransitionDao dao = new MockBusinessSubscriptionTransitionDao();
+        final BusinessSubscriptionTransitionSqlDao sqlDao = new MockBusinessSubscriptionTransitionSqlDao();
         // Add a previous subscription to make sure it doesn't impact the addon
         final BusinessSubscription nextPrevSubscription = new BusinessSubscription(UUID.randomUUID().toString(),
                                                                                    UUID.randomUUID().toString(),
@@ -56,8 +59,8 @@ public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSui
                                                                                    UUID.randomUUID(),
                                                                                    UUID.randomUUID(),
                                                                                    catalogService.getFullCatalog());
-        dao.createTransition(new BusinessSubscriptionTransition(UUID.randomUUID(),
-                                                                key.toString(),
+        sqlDao.createTransition(new BusinessSubscriptionTransition(10L,
+                                                                externalKey.toString(),
                                                                 UUID.randomUUID().toString(),
                                                                 new DateTime(DateTimeZone.UTC),
                                                                 BusinessSubscriptionEvent.valueOf("ADD_MISC"),
@@ -66,17 +69,17 @@ public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSui
 
         // Setup the entitlement API
         final SubscriptionBundle bundle = Mockito.mock(SubscriptionBundle.class);
-        Mockito.when(bundle.getKey()).thenReturn(key.toString());
+        Mockito.when(bundle.getKey()).thenReturn(externalKey.toString());
         final EntitlementUserApi entitlementApi = Mockito.mock(EntitlementUserApi.class);
         Mockito.when(entitlementApi.getBundleFromId(Mockito.<UUID>any())).thenReturn(bundle);
 
         // Setup the account API
         final Account account = Mockito.mock(Account.class);
-        Mockito.when(account.getExternalKey()).thenReturn(key.toString());
+        Mockito.when(account.getExternalKey()).thenReturn(externalKey.toString());
         final AccountUserApi accountApi = Mockito.mock(AccountUserApi.class);
         Mockito.when(accountApi.getAccountById(bundle.getAccountId())).thenReturn(account);
 
-        final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(dao, catalogService, entitlementApi, accountApi);
+        final BusinessSubscriptionTransitionRecorder recorder = new BusinessSubscriptionTransitionRecorder(sqlDao, catalogService, entitlementApi, accountApi);
 
         // Create an new subscription event
         final SubscriptionEvent event = Mockito.mock(SubscriptionEvent.class);
@@ -87,10 +90,10 @@ public class TestBusinessSubscriptionTransitionRecorder extends AnalyticsTestSui
         Mockito.when(event.getSubscriptionStartDate()).thenReturn(new DateTime(DateTimeZone.UTC));
         recorder.subscriptionCreated(event);
 
-        Assert.assertEquals(dao.getTransitions(key.toString()).size(), 2);
-        final BusinessSubscriptionTransition transition = dao.getTransitions(key.toString()).get(1);
-        Assert.assertEquals(transition.getId(), event.getId());
-        Assert.assertEquals(transition.getAccountKey(), key.toString());
+        Assert.assertEquals(sqlDao.getTransitions(externalKey.toString()).size(), 2);
+        final BusinessSubscriptionTransition transition = sqlDao.getTransitions(externalKey.toString()).get(1);
+        Assert.assertEquals(transition.getTotalOrdering(), (long) event.getTotalOrdering());
+        Assert.assertEquals(transition.getAccountKey(), externalKey.toString());
         // Make sure all the prev_ columns are null
         Assert.assertNull(transition.getPreviousSubscription());
     }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
new file mode 100644
index 0000000..6f18739
--- /dev/null
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.analytics;
+
+import java.util.UUID;
+
+import org.mockito.Mockito;
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.account.api.user.DefaultAccountUserApi;
+import com.ning.billing.account.dao.AccountDao;
+import com.ning.billing.account.dao.AccountEmailDao;
+import com.ning.billing.account.dao.AuditedAccountDao;
+import com.ning.billing.account.dao.AuditedAccountEmailDao;
+import com.ning.billing.analytics.dao.BusinessAccountTagSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoicePaymentTagSqlDao;
+import com.ning.billing.analytics.dao.BusinessInvoiceTagSqlDao;
+import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionTagSqlDao;
+import com.ning.billing.catalog.DefaultCatalogService;
+import com.ning.billing.catalog.api.CatalogService;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.io.VersionedCatalogLoader;
+import com.ning.billing.config.CatalogConfig;
+import com.ning.billing.entitlement.alignment.PlanAligner;
+import com.ning.billing.entitlement.api.user.DefaultEntitlementUserApi;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionApiService;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.entitlement.engine.addon.AddonUtils;
+import com.ning.billing.entitlement.engine.dao.AuditedEntitlementDao;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
+import com.ning.billing.mock.MockAccountBuilder;
+import com.ning.billing.util.bus.InMemoryBus;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.clock.DefaultClock;
+import com.ning.billing.util.dao.ObjectType;
+import com.ning.billing.util.notificationq.DefaultNotificationQueueService;
+
+public class TestBusinessTagRecorder extends TestWithEmbeddedDB {
+    private BusinessAccountTagSqlDao accountTagSqlDao;
+    private BusinessSubscriptionTransitionTagSqlDao subscriptionTransitionTagSqlDao;
+    private InMemoryBus eventBus;
+    private DefaultCallContextFactory callContextFactory;
+    private AccountUserApi accountUserApi;
+    private EntitlementUserApi entitlementUserApi;
+    private BusinessTagRecorder tagRecorder;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        final IDBI dbi = helper.getDBI();
+        accountTagSqlDao = dbi.onDemand(BusinessAccountTagSqlDao.class);
+        final BusinessInvoiceTagSqlDao invoiceTagSqlDao = dbi.onDemand(BusinessInvoiceTagSqlDao.class);
+        final BusinessInvoicePaymentTagSqlDao invoicePaymentTagSqlDao = dbi.onDemand(BusinessInvoicePaymentTagSqlDao.class);
+        subscriptionTransitionTagSqlDao = dbi.onDemand(BusinessSubscriptionTransitionTagSqlDao.class);
+        eventBus = new InMemoryBus();
+        final AccountDao accountDao = new AuditedAccountDao(dbi, eventBus);
+        final AccountEmailDao accountEmailDao = new AuditedAccountEmailDao(dbi);
+        final DefaultClock clock = new DefaultClock();
+        callContextFactory = new DefaultCallContextFactory(clock);
+        accountUserApi = new DefaultAccountUserApi(callContextFactory, accountDao, accountEmailDao);
+        final CatalogService catalogService = new DefaultCatalogService(Mockito.mock(CatalogConfig.class), Mockito.mock(VersionedCatalogLoader.class));
+        final AddonUtils addonUtils = new AddonUtils(catalogService);
+        final DefaultNotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi, clock);
+        final EntitlementDao entitlementDao = new AuditedEntitlementDao(dbi, clock, addonUtils, notificationQueueService, eventBus);
+        final PlanAligner planAligner = new PlanAligner(catalogService);
+        final DefaultSubscriptionApiService apiService = new DefaultSubscriptionApiService(clock, entitlementDao, catalogService, planAligner);
+        final DefaultSubscriptionFactory subscriptionFactory = new DefaultSubscriptionFactory(apiService, clock, catalogService);
+        entitlementUserApi = new DefaultEntitlementUserApi(clock, entitlementDao, catalogService,
+                                                           apiService, subscriptionFactory, addonUtils);
+        tagRecorder = new BusinessTagRecorder(accountTagSqlDao, invoicePaymentTagSqlDao, invoiceTagSqlDao, subscriptionTransitionTagSqlDao,
+                                              accountUserApi, entitlementUserApi);
+
+        eventBus.start();
+    }
+
+    @AfterMethod(groups = "slow")
+    public void tearDown() throws Exception {
+        eventBus.stop();
+    }
+
+    @Test(groups = "slow")
+    public void testAddAndRemoveTagsForAccount() throws Exception {
+        final String name = UUID.randomUUID().toString().substring(0, 20);
+        final CallContext callContext = callContextFactory.createCallContext(UUID.randomUUID().toString(), CallOrigin.TEST, UserType.TEST);
+        final String accountKey = UUID.randomUUID().toString();
+
+        final Account accountData = new MockAccountBuilder()
+                .externalKey(accountKey)
+                .currency(Currency.MXN)
+                .build();
+        final Account account = accountUserApi.createAccount(accountData, callContext);
+        final UUID accountId = account.getId();
+
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccount(accountKey).size(), 0);
+        tagRecorder.tagAdded(ObjectType.ACCOUNT, accountId, name);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccount(accountKey).size(), 1);
+        tagRecorder.tagRemoved(ObjectType.ACCOUNT, accountId, name);
+        Assert.assertEquals(accountTagSqlDao.getTagsForAccount(accountKey).size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testAddAndRemoveTagsForBundle() throws Exception {
+        final String name = UUID.randomUUID().toString().substring(0, 20);
+        final CallContext callContext = callContextFactory.createCallContext(UUID.randomUUID().toString(), CallOrigin.TEST, UserType.TEST);
+        final String externalKey = UUID.randomUUID().toString();
+
+        final Account accountData = new MockAccountBuilder()
+                .currency(Currency.MXN)
+                .build();
+        final Account account = accountUserApi.createAccount(accountData, callContext);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), externalKey, callContext);
+        final UUID bundleId = bundle.getId();
+
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransition(externalKey).size(), 0);
+        tagRecorder.tagAdded(ObjectType.BUNDLE, bundleId, name);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransition(externalKey).size(), 1);
+        tagRecorder.tagRemoved(ObjectType.BUNDLE, bundleId, name);
+        Assert.assertEquals(subscriptionTransitionTagSqlDao.getTagsForBusinessSubscriptionTransition(externalKey).size(), 0);
+    }
+}
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestWithEmbeddedDB.java b/analytics/src/test/java/com/ning/billing/analytics/TestWithEmbeddedDB.java
index ad99469..9f60771 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestWithEmbeddedDB.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestWithEmbeddedDB.java
@@ -20,13 +20,13 @@ import java.io.IOException;
 import java.net.URISyntaxException;
 import java.sql.SQLException;
 
-import org.apache.commons.io.IOUtils;
 import org.testng.annotations.AfterSuite;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.BeforeSuite;
 
 import com.google.common.io.Resources;
 import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.util.io.IOUtils;
 
 public abstract class TestWithEmbeddedDB extends AnalyticsTestSuite {
     protected static final MysqlTestingHelper helper = new MysqlTestingHelper();
@@ -47,7 +47,7 @@ public abstract class TestWithEmbeddedDB extends AnalyticsTestSuite {
         helper.cleanupAllTables();
     }
 
-    @BeforeMethod(alwaysRun = true)
+    @BeforeMethod(groups = "slow")
     public void cleanup() {
         try {
             helper.cleanupAllTables();

api/pom.xml 10(+1 -9)

diff --git a/api/pom.xml b/api/pom.xml
index cd76c4d..538901a 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-api</artifactId>
@@ -43,10 +43,6 @@
             <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.skife.config</groupId>
             <artifactId>config-magic</artifactId>
         </dependency>
@@ -54,10 +50,6 @@
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-annotations</artifactId>
         </dependency>
-        <dependency>
-            <groupId>commons-lang</groupId>
-            <artifactId>commons-lang</artifactId>
-        </dependency>
     </dependencies>
     <build>
     </build>
diff --git a/api/src/main/java/com/ning/billing/account/api/Account.java b/api/src/main/java/com/ning/billing/account/api/Account.java
index f69af41..dd6804a 100644
--- a/api/src/main/java/com/ning/billing/account/api/Account.java
+++ b/api/src/main/java/com/ning/billing/account/api/Account.java
@@ -20,5 +20,7 @@ import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.util.entity.UpdatableEntity;
 
 public interface Account extends AccountData, UpdatableEntity, Blockable {
-    public MutableAccountData toMutableAccountData(); 
+    public MutableAccountData toMutableAccountData();
+
+    public Account mergeWithDelegate(final Account delegate);
 }
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountApiException.java b/api/src/main/java/com/ning/billing/account/api/AccountApiException.java
index a6b1460..a0d9061 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountApiException.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountApiException.java
@@ -20,17 +20,17 @@ import com.ning.billing.BillingExceptionBase;
 import com.ning.billing.ErrorCode;
 
 public class AccountApiException extends BillingExceptionBase {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public AccountApiException(Throwable cause, int code, final String msg) {
+    public AccountApiException(final Throwable cause, final int code, final String msg) {
         super(cause, code, msg);
     }
 
-    public AccountApiException(Throwable cause, ErrorCode code, final Object... args) {
+    public AccountApiException(final Throwable cause, final ErrorCode code, final Object... args) {
         super(cause, code, args);
     }
 
-    public AccountApiException(ErrorCode code, final Object... args) {
+    public AccountApiException(final ErrorCode code, final Object... args) {
         super(code, args);
     }
 
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountChangeEvent.java b/api/src/main/java/com/ning/billing/account/api/AccountChangeEvent.java
index 792d0ea..1c78280 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountChangeEvent.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountChangeEvent.java
@@ -16,11 +16,11 @@
 
 package com.ning.billing.account.api;
 
-import com.ning.billing.util.bus.BusEvent;
-
 import java.util.List;
 import java.util.UUID;
 
+import com.ning.billing.util.bus.BusEvent;
+
 public interface AccountChangeEvent extends BusEvent {
     public UUID getAccountId();
 
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountCreationEvent.java b/api/src/main/java/com/ning/billing/account/api/AccountCreationEvent.java
index 983cbf1..3749e5a 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountCreationEvent.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountCreationEvent.java
@@ -16,12 +16,13 @@
 
 package com.ning.billing.account.api;
 
-import com.ning.billing.util.bus.BusEvent;
-
 import java.util.UUID;
 
+import com.ning.billing.util.bus.BusEvent;
+
 public interface AccountCreationEvent extends BusEvent {
-	
+
     public UUID getId();
+
     public AccountData getData();
 }
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountData.java b/api/src/main/java/com/ning/billing/account/api/AccountData.java
index fa3e135..055338b 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountData.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountData.java
@@ -23,16 +23,15 @@ import org.joda.time.DateTimeZone;
 import com.ning.billing.catalog.api.Currency;
 
 public interface AccountData {
-
     public String getExternalKey();
 
     public String getName();
 
-    public int getFirstNameLength();
+    public Integer getFirstNameLength();
 
     public String getEmail();
 
-    public int getBillCycleDay();
+    public Integer getBillCycleDay();
 
     public Currency getCurrency();
 
@@ -58,7 +57,7 @@ public interface AccountData {
 
     public String getPhone();
 
-    public boolean isMigrated();
+    public Boolean isMigrated();
 
-    public boolean isNotifiedForInvoices();
+    public Boolean isNotifiedForInvoices();
 }
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountEmail.java b/api/src/main/java/com/ning/billing/account/api/AccountEmail.java
index 88ec469..a1b535f 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountEmail.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountEmail.java
@@ -16,11 +16,12 @@
 
 package com.ning.billing.account.api;
 
-import com.ning.billing.util.entity.UpdatableEntity;
-
 import java.util.UUID;
 
+import com.ning.billing.util.entity.UpdatableEntity;
+
 public interface AccountEmail extends UpdatableEntity {
     UUID getAccountId();
+
     String getEmail();
 }
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java b/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
index 5cea963..85e03cf 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
@@ -20,19 +20,15 @@ import java.util.List;
 import java.util.UUID;
 
 import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.customfield.CustomField;
-import com.ning.billing.util.tag.TagDefinition;
-
-import javax.annotation.Nullable;
 
 public interface AccountUserApi {
     public Account createAccount(AccountData data, CallContext context) throws AccountApiException;
 
     public Account migrateAccount(MigrationAccountData data, CallContext context) throws AccountApiException;
 
-    /***
-     *
+    /**
      * Note: does not update the external key
+     *
      * @param account account to be updated
      * @param context contains specific information about the call
      * @throws AccountApiException if a failure occurs
@@ -54,4 +50,8 @@ public interface AccountUserApi {
     public List<AccountEmail> getEmails(UUID accountId);
 
     public void saveEmails(UUID accountId, List<AccountEmail> emails, CallContext context);
+
+    public void addEmail(UUID accountId, AccountEmail email, CallContext context);
+
+    public void removeEmail(UUID accountId, AccountEmail email, CallContext context);
 }
diff --git a/api/src/main/java/com/ning/billing/account/api/ChangedField.java b/api/src/main/java/com/ning/billing/account/api/ChangedField.java
index 8bf2ef1..5c7505b 100644
--- a/api/src/main/java/com/ning/billing/account/api/ChangedField.java
+++ b/api/src/main/java/com/ning/billing/account/api/ChangedField.java
@@ -20,7 +20,10 @@ import org.joda.time.DateTime;
 
 public interface ChangedField {
     public DateTime getChangeDate();
+
     public String getFieldName();
+
     public String getOldValue();
+
     public String getNewValue();
 }
diff --git a/api/src/main/java/com/ning/billing/account/api/DefaultMutableAccountData.java b/api/src/main/java/com/ning/billing/account/api/DefaultMutableAccountData.java
index 5ac7f50..566822a 100644
--- a/api/src/main/java/com/ning/billing/account/api/DefaultMutableAccountData.java
+++ b/api/src/main/java/com/ning/billing/account/api/DefaultMutableAccountData.java
@@ -43,14 +43,14 @@ public class DefaultMutableAccountData implements MutableAccountData {
     private String phone;
     private boolean isMigrated;
     private boolean isNotifiedForInvoices;
-    
-    public DefaultMutableAccountData(String externalKey, String email, String name,
-            int firstNameLength, Currency currency, int billCycleDay,
-            UUID paymentMethodId, TagStore tags, DateTimeZone timeZone,
-            String locale, String address1, String address2,
-            String companyName, String city, String stateOrProvince,
-            String country, String postalCode, String phone,
-            boolean isMigrated, boolean isNotifiedForInvoices) {
+
+    public DefaultMutableAccountData(final String externalKey, final String email, final String name,
+                                     final int firstNameLength, final Currency currency, final int billCycleDay,
+                                     final UUID paymentMethodId, final TagStore tags, final DateTimeZone timeZone,
+                                     final String locale, final String address1, final String address2,
+                                     final String companyName, final String city, final String stateOrProvince,
+                                     final String country, final String postalCode, final String phone,
+                                     final boolean isMigrated, final boolean isNotifiedForInvoices) {
         super();
         this.externalKey = externalKey;
         this.email = email;
@@ -72,8 +72,8 @@ public class DefaultMutableAccountData implements MutableAccountData {
         this.isMigrated = isMigrated;
         this.isNotifiedForInvoices = isNotifiedForInvoices;
     }
-    
-    public DefaultMutableAccountData(AccountData accountData) {
+
+    public DefaultMutableAccountData(final AccountData accountData) {
         super();
         this.externalKey = accountData.getExternalKey();
         this.email = accountData.getEmail();
@@ -103,259 +103,294 @@ public class DefaultMutableAccountData implements MutableAccountData {
     public String getExternalKey() {
         return externalKey;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getEmail()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getEmail()
+    */
     @Override
     public String getEmail() {
         return email;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getName()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getName()
+    */
     @Override
     public String getName() {
         return name;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getFirstNameLength()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getFirstNameLength()
+    */
     @Override
-    public int getFirstNameLength() {
+    public Integer getFirstNameLength() {
         return firstNameLength;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getCurrency()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getCurrency()
+    */
     @Override
     public Currency getCurrency() {
         return currency;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getBillCycleDay()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getBillCycleDay()
+    */
     @Override
-    public int getBillCycleDay() {
+    public Integer getBillCycleDay() {
         return billCycleDay;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getPaymentProviderName()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getPaymentProviderName()
+    */
     @Override
     public UUID getPaymentMethodId() {
         return paymentMethodId;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getTimeZone()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getTimeZone()
+    */
     @Override
     public DateTimeZone getTimeZone() {
         return timeZone;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getLocale()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getLocale()
+    */
     @Override
     public String getLocale() {
         return locale;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getAddress1()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getAddress1()
+    */
     @Override
     public String getAddress1() {
         return address1;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getAddress2()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getAddress2()
+    */
     @Override
     public String getAddress2() {
         return address2;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getCompanyName()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getCompanyName()
+    */
     @Override
     public String getCompanyName() {
         return companyName;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getCity()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getCity()
+    */
     @Override
     public String getCity() {
         return city;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getStateOrProvince()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getStateOrProvince()
+    */
     @Override
     public String getStateOrProvince() {
         return stateOrProvince;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getCountry()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getCountry()
+    */
     @Override
     public String getCountry() {
         return country;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getPostalCode()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getPostalCode()
+    */
     @Override
     public String getPostalCode() {
         return postalCode;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getPhone()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getPhone()
+    */
     @Override
     public String getPhone() {
         return phone;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#isMigrated()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#isMigrated()
+    */
     @Override
-    public boolean isMigrated() {
+    public Boolean isMigrated() {
         return isMigrated;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#getSendInvoiceEmails()
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#getSendInvoiceEmails()
+    */
     @Override
-    public boolean isNotifiedForInvoices() {
+    public Boolean isNotifiedForInvoices() {
         return isNotifiedForInvoices;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setExternalKey(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setExternalKey(java.lang.String)
+    */
     @Override
-    public void setExternalKey(String externalKey) {
+    public void setExternalKey(final String externalKey) {
         this.externalKey = externalKey;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setEmail(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setEmail(java.lang.String)
+    */
     @Override
-    public void setEmail(String email) {
+    public void setEmail(final String email) {
         this.email = email;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setName(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setName(java.lang.String)
+    */
     @Override
-    public void setName(String name) {
+    public void setName(final String name) {
         this.name = name;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setFirstNameLength(int)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setFirstNameLength(int)
+    */
     @Override
-    public void setFirstNameLength(int firstNameLength) {
+    public void setFirstNameLength(final int firstNameLength) {
         this.firstNameLength = firstNameLength;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setCurrency(com.ning.billing.catalog.api.Currency)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setCurrency(com.ning.billing.catalog.api.Currency)
+    */
     @Override
-    public void setCurrency(Currency currency) {
+    public void setCurrency(final Currency currency) {
         this.currency = currency;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setBillCycleDay(int)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setBillCycleDay(int)
+    */
     @Override
-    public void setBillCycleDay(int billCycleDay) {
+    public void setBillCycleDay(final int billCycleDay) {
         this.billCycleDay = billCycleDay;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setPaymentProviderName(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setPaymentProviderName(java.lang.String)
+    */
     @Override
-    public void setPaymentMethodId(UUID paymentMethodId) {
+    public void setPaymentMethodId(final UUID paymentMethodId) {
         this.paymentMethodId = paymentMethodId;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setTimeZone(org.joda.time.DateTimeZone)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setTimeZone(org.joda.time.DateTimeZone)
+    */
     @Override
-    public void setTimeZone(DateTimeZone timeZone) {
+    public void setTimeZone(final DateTimeZone timeZone) {
         this.timeZone = timeZone;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setLocale(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setLocale(java.lang.String)
+    */
     @Override
-    public void setLocale(String locale) {
+    public void setLocale(final String locale) {
         this.locale = locale;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setAddress1(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setAddress1(java.lang.String)
+    */
     @Override
-    public void setAddress1(String address1) {
+    public void setAddress1(final String address1) {
         this.address1 = address1;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setAddress2(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setAddress2(java.lang.String)
+    */
     @Override
-    public void setAddress2(String address2) {
+    public void setAddress2(final String address2) {
         this.address2 = address2;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setCompanyName(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setCompanyName(java.lang.String)
+    */
     @Override
-    public void setCompanyName(String companyName) {
+    public void setCompanyName(final String companyName) {
         this.companyName = companyName;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setCity(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setCity(java.lang.String)
+    */
     @Override
-    public void setCity(String city) {
+    public void setCity(final String city) {
         this.city = city;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setStateOrProvince(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setStateOrProvince(java.lang.String)
+    */
     @Override
-    public void setStateOrProvince(String stateOrProvince) {
+    public void setStateOrProvince(final String stateOrProvince) {
         this.stateOrProvince = stateOrProvince;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setCountry(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setCountry(java.lang.String)
+    */
     @Override
-    public void setCountry(String country) {
+    public void setCountry(final String country) {
         this.country = country;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setPostalCode(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setPostalCode(java.lang.String)
+    */
     @Override
-    public void setPostalCode(String postalCode) {
+    public void setPostalCode(final String postalCode) {
         this.postalCode = postalCode;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.account.api.MutableAccountData#setPhone(java.lang.String)
-     */
+    * @see com.ning.billing.account.api.MutableAccountData#setPhone(java.lang.String)
+    */
     @Override
-    public void setPhone(String phone) {
+    public void setPhone(final String phone) {
         this.phone = phone;
     }
 
     @Override
-    public void setIsMigrated(boolean isMigrated) {
+    public void setIsMigrated(final boolean isMigrated) {
         this.isMigrated = isMigrated;
     }
 
     @Override
-    public void setIsNotifiedForInvoices(boolean isNotifiedForInvoices) {
+    public void setIsNotifiedForInvoices(final boolean isNotifiedForInvoices) {
         this.isNotifiedForInvoices = isNotifiedForInvoices;
     }
 
diff --git a/api/src/main/java/com/ning/billing/account/api/MigrationAccountData.java b/api/src/main/java/com/ning/billing/account/api/MigrationAccountData.java
index 34f7023..7b44ef8 100644
--- a/api/src/main/java/com/ning/billing/account/api/MigrationAccountData.java
+++ b/api/src/main/java/com/ning/billing/account/api/MigrationAccountData.java
@@ -20,7 +20,7 @@ import org.joda.time.DateTime;
 
 public interface MigrationAccountData extends AccountData {
 
-	public DateTime getCreatedDate();
-	
-	public DateTime getUpdatedDate();
+    public DateTime getCreatedDate();
+
+    public DateTime getUpdatedDate();
 }
diff --git a/api/src/main/java/com/ning/billing/BillingExceptionBase.java b/api/src/main/java/com/ning/billing/BillingExceptionBase.java
index a4ff3cd..a074d3e 100644
--- a/api/src/main/java/com/ning/billing/BillingExceptionBase.java
+++ b/api/src/main/java/com/ning/billing/BillingExceptionBase.java
@@ -22,7 +22,7 @@ import org.slf4j.LoggerFactory;
 
 public class BillingExceptionBase extends Exception {
 
-    private final static Logger log = LoggerFactory.getLogger(BillingExceptionBase.class);
+    private static final Logger log = LoggerFactory.getLogger(BillingExceptionBase.class);
 
     private static final long serialVersionUID = 165720101383L;
 
@@ -30,23 +30,23 @@ public class BillingExceptionBase extends Exception {
     private final int code;
     private final String formattedMsg;
 
-    public BillingExceptionBase(Throwable cause, int code, final String msg) {
+    public BillingExceptionBase(final Throwable cause, final int code, final String msg) {
         this.formattedMsg = msg;
         this.code = code;
         this.cause = cause;
     }
-    
-    public BillingExceptionBase(BillingExceptionBase cause) {
+
+    public BillingExceptionBase(final BillingExceptionBase cause) {
         this.formattedMsg = cause.getMessage();
         this.code = cause.getCode();
         this.cause = cause;
     }
 
 
-    public BillingExceptionBase(Throwable cause, ErrorCode code, final Object... args) {
+    public BillingExceptionBase(final Throwable cause, final ErrorCode code, final Object... args) {
         String tmp = null;
         try {
-           tmp = String.format(code.getFormat(), args);
+            tmp = String.format(code.getFormat(), args);
         } catch (RuntimeException e) {
             log.error("Failed to format msg for error code " + code.getCode(), e);
             throw e;
@@ -56,7 +56,7 @@ public class BillingExceptionBase extends Exception {
         this.cause = cause;
     }
 
-    public BillingExceptionBase(ErrorCode code, final Object... args) {
+    public BillingExceptionBase(final ErrorCode code, final Object... args) {
         this(null, code, args);
     }
 
diff --git a/api/src/main/java/com/ning/billing/catalog/api/ActionPolicy.java b/api/src/main/java/com/ning/billing/catalog/api/ActionPolicy.java
index 4719d4d..831a3f2 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/ActionPolicy.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/ActionPolicy.java
@@ -17,7 +17,7 @@
 package com.ning.billing.catalog.api;
 
 public enum ActionPolicy {
-	END_OF_TERM, // transition occurs at end of term
-	IMMEDIATE,   // transition occurs immediately
-	ILLEGAL      // transition is not allowed
+    END_OF_TERM, // transition occurs at end of term
+    IMMEDIATE,   // transition occurs immediately
+    ILLEGAL      // transition is not allowed
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/BillingAlignment.java b/api/src/main/java/com/ning/billing/catalog/api/BillingAlignment.java
index 5dce39d..a774936 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/BillingAlignment.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/BillingAlignment.java
@@ -17,7 +17,7 @@
 package com.ning.billing.catalog.api;
 
 public enum BillingAlignment {
-	ACCOUNT,
-	BUNDLE,
-	SUBSCRIPTION
+    ACCOUNT,
+    BUNDLE,
+    SUBSCRIPTION
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/BillingPeriod.java b/api/src/main/java/com/ning/billing/catalog/api/BillingPeriod.java
index 7d129af..6ab91ed 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/BillingPeriod.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/BillingPeriod.java
@@ -17,20 +17,20 @@
 package com.ning.billing.catalog.api;
 
 public enum BillingPeriod {
-	MONTHLY(1),
-	QUARTERLY(3),
-	//SEMI_ANNUAL(6), ** not yet supported
-	ANNUAL(12),
-	//BI_ANNUAL(24); ** not yet supported
-	NO_BILLING_PERIOD(0);
+    MONTHLY(1),
+    QUARTERLY(3),
+    //SEMI_ANNUAL(6), ** not yet supported
+    ANNUAL(12),
+    //BI_ANNUAL(24); ** not yet supported
+    NO_BILLING_PERIOD(0);
 
     private final int numberOfMonths;
 
-    BillingPeriod(int numberOfMonths) {
+    BillingPeriod(final int numberOfMonths) {
         this.numberOfMonths = numberOfMonths;
     }
 
     public int getNumberOfMonths() {
         return numberOfMonths;
     }
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/Catalog.java b/api/src/main/java/com/ning/billing/catalog/api/Catalog.java
index 924a5e4..af96414 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/Catalog.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/Catalog.java
@@ -19,35 +19,35 @@ package com.ning.billing.catalog.api;
 import org.joda.time.DateTime;
 
 public interface Catalog {
-	//
+    //
     // Simple getters
     //
     public abstract String getCatalogName();
 
     public abstract Currency[] getSupportedCurrencies(DateTime requestedDate) throws CatalogApiException;
 
-	public abstract Product[] getProducts(DateTime requestedDate) throws CatalogApiException;
-	
-	public abstract Plan[] getPlans(DateTime requestedDate) throws CatalogApiException;
+    public abstract Product[] getProducts(DateTime requestedDate) throws CatalogApiException;
+
+    public abstract Plan[] getPlans(DateTime requestedDate) throws CatalogApiException;
+
+
+    //
+    // Find a plan
+    //
+
+    public abstract Plan findPlan(String name, DateTime requestedDate) throws CatalogApiException;
 
-	
-	//
-	// Find a plan
-	//
+    public abstract Plan findPlan(String productName, BillingPeriod term, String priceListName,
+                                  DateTime requestedDate) throws CatalogApiException;
 
-	public abstract Plan findPlan(String name, DateTime requestedDate) throws CatalogApiException;
+    public abstract Plan findPlan(String name, DateTime effectiveDate, DateTime subscriptionStartDate) throws CatalogApiException;
 
-	public abstract Plan findPlan(String productName, BillingPeriod term, String priceListName,
-									DateTime requestedDate) throws CatalogApiException;
-	
-	public abstract Plan findPlan(String name, DateTime effectiveDate, DateTime subscriptionStartDate) throws CatalogApiException;
+    public abstract Plan findPlan(String productName, BillingPeriod term, String priceListName,
+                                  DateTime requestedDate, DateTime subscriptionStartDate) throws CatalogApiException;
 
-	public abstract Plan findPlan(String productName, BillingPeriod term, String priceListName,
-									DateTime requestedDate, DateTime subscriptionStartDate) throws CatalogApiException;
-	
-	//
-	// Find a product
-	//
+    //
+    // Find a product
+    //
     public abstract Product findProduct(String name, DateTime requestedDate) throws CatalogApiException;
 
     //
@@ -63,11 +63,11 @@ public interface Catalog {
     //
     // Rules
     //
-	public abstract ActionPolicy planChangePolicy(PlanPhaseSpecifier from,
-			PlanSpecifier to, DateTime requestedDate) throws CatalogApiException;
+    public abstract ActionPolicy planChangePolicy(PlanPhaseSpecifier from,
+                                                  PlanSpecifier to, DateTime requestedDate) throws CatalogApiException;
 
-	public abstract PlanChangeResult planChange(PlanPhaseSpecifier from,
-			PlanSpecifier to, DateTime requestedDate) throws CatalogApiException;
+    public abstract PlanChangeResult planChange(PlanPhaseSpecifier from,
+                                                PlanSpecifier to, DateTime requestedDate) throws CatalogApiException;
 
     public abstract ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase, DateTime requestedDate) throws CatalogApiException;
 
@@ -76,8 +76,8 @@ public interface Catalog {
     public abstract BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase, DateTime requestedDate) throws CatalogApiException;
 
     public abstract PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from,
-			PlanSpecifier to, DateTime requestedDate) throws CatalogApiException;
+                                                            PlanSpecifier to, DateTime requestedDate) throws CatalogApiException;
 
     public abstract boolean canCreatePlan(PlanSpecifier specifier, DateTime requestedDate) throws CatalogApiException;
-		
+
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/CatalogApiException.java b/api/src/main/java/com/ning/billing/catalog/api/CatalogApiException.java
index 3de9eb8..5473f15 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/CatalogApiException.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/CatalogApiException.java
@@ -20,14 +20,14 @@ import com.ning.billing.BillingExceptionBase;
 import com.ning.billing.ErrorCode;
 
 public class CatalogApiException extends BillingExceptionBase {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public CatalogApiException(Throwable cause, ErrorCode code, Object... args) {
-		super(cause, code, args);
-	}
+    public CatalogApiException(final Throwable cause, final ErrorCode code, final Object... args) {
+        super(cause, code, args);
+    }
 
-	public CatalogApiException(ErrorCode code, Object... args) {
-		super(code, args);
-	}
+    public CatalogApiException(final ErrorCode code, final Object... args) {
+        super(code, args);
+    }
 
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/CatalogService.java b/api/src/main/java/com/ning/billing/catalog/api/CatalogService.java
index c363a87..6b7b673 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/CatalogService.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/CatalogService.java
@@ -20,7 +20,8 @@ import com.ning.billing.lifecycle.KillbillService;
 
 public interface CatalogService extends KillbillService {
 
-	public abstract Catalog getFullCatalog();
-	public abstract StaticCatalog getCurrentCatalog();
+    public abstract Catalog getFullCatalog();
 
-}
\ No newline at end of file
+    public abstract StaticCatalog getCurrentCatalog();
+
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/Currency.java b/api/src/main/java/com/ning/billing/catalog/api/Currency.java
index 3bef242..09e9211 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/Currency.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/Currency.java
@@ -21,12 +21,12 @@ import javax.xml.bind.annotation.XmlEnum;
 
 @XmlEnum
 public enum Currency {
-	GBP,
-	MXN,
-	BRL,
-	EUR,
-	AUD,
-	USD;
+    GBP,
+    MXN,
+    BRL,
+    EUR,
+    AUD,
+    USD;
 // Unsupported
 //	CAD,
 //	JPY
diff --git a/api/src/main/java/com/ning/billing/catalog/api/CurrencyValueNull.java b/api/src/main/java/com/ning/billing/catalog/api/CurrencyValueNull.java
index 4130f9f..5cbd5ef 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/CurrencyValueNull.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/CurrencyValueNull.java
@@ -19,14 +19,14 @@ package com.ning.billing.catalog.api;
 import com.ning.billing.ErrorCode;
 
 public class CurrencyValueNull extends CatalogApiException {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public CurrencyValueNull(Throwable cause, Object... args) {
-		super(cause, ErrorCode.CAT_PRICE_VALUE_NULL_FOR_CURRENCY, args);
-	}
+    public CurrencyValueNull(final Throwable cause, final Object... args) {
+        super(cause, ErrorCode.CAT_PRICE_VALUE_NULL_FOR_CURRENCY, args);
+    }
 
-	public CurrencyValueNull(Object... args) {
-		super(ErrorCode.CAT_PRICE_VALUE_NULL_FOR_CURRENCY, args);
-	}
+    public CurrencyValueNull(final Object... args) {
+        super(ErrorCode.CAT_PRICE_VALUE_NULL_FOR_CURRENCY, args);
+    }
 
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/Duration.java b/api/src/main/java/com/ning/billing/catalog/api/Duration.java
index 90ea5c2..fe1b01a 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/Duration.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/Duration.java
@@ -21,11 +21,11 @@ import org.joda.time.Period;
 
 public interface Duration {
 
-	public abstract TimeUnit getUnit();
+    public abstract TimeUnit getUnit();
 
-	public abstract int getNumber();
+    public abstract int getNumber();
 
     public DateTime addToDateTime(DateTime dateTime);
 
     public Period toJodaPeriod();
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/IllegalPlanChange.java b/api/src/main/java/com/ning/billing/catalog/api/IllegalPlanChange.java
index 21bd513..be661fb 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/IllegalPlanChange.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/IllegalPlanChange.java
@@ -19,17 +19,17 @@ package com.ning.billing.catalog.api;
 import com.ning.billing.ErrorCode;
 
 public class IllegalPlanChange extends CatalogApiException {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public IllegalPlanChange(Throwable cause, PlanPhaseSpecifier from,
-			PlanSpecifier to) {
-		super(cause, ErrorCode.CAT_ILLEGAL_CHANGE_REQUEST, from.getProductName(), from.getBillingPeriod(), from.getPriceListName(), to.getProductName(), to.getBillingPeriod(), to.getPriceListName());
-	}
+    public IllegalPlanChange(final Throwable cause, final PlanPhaseSpecifier from,
+                             final PlanSpecifier to) {
+        super(cause, ErrorCode.CAT_ILLEGAL_CHANGE_REQUEST, from.getProductName(), from.getBillingPeriod(), from.getPriceListName(), to.getProductName(), to.getBillingPeriod(), to.getPriceListName());
+    }
 
-	public IllegalPlanChange(PlanPhaseSpecifier from,
-			PlanSpecifier to) {
-		super(ErrorCode.CAT_ILLEGAL_CHANGE_REQUEST, from.getProductName(), from.getBillingPeriod(), from.getPriceListName(), to.getProductName(), to.getBillingPeriod(), to.getPriceListName());
-	}
+    public IllegalPlanChange(final PlanPhaseSpecifier from,
+                             final PlanSpecifier to) {
+        super(ErrorCode.CAT_ILLEGAL_CHANGE_REQUEST, from.getProductName(), from.getBillingPeriod(), from.getPriceListName(), to.getProductName(), to.getBillingPeriod(), to.getPriceListName());
+    }
 
 
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/InternationalPrice.java b/api/src/main/java/com/ning/billing/catalog/api/InternationalPrice.java
index e047175..7f8ffef 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/InternationalPrice.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/InternationalPrice.java
@@ -21,10 +21,10 @@ import java.math.BigDecimal;
 
 public interface InternationalPrice {
 
-	public abstract Price[] getPrices();
+    public abstract Price[] getPrices();
 
-	public abstract BigDecimal getPrice(Currency currency) throws CatalogApiException;
+    public abstract BigDecimal getPrice(Currency currency) throws CatalogApiException;
 
-	public abstract boolean isZero();
+    public abstract boolean isZero();
 
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/InvalidConfigException.java b/api/src/main/java/com/ning/billing/catalog/api/InvalidConfigException.java
index 328abaa..301ca3c 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/InvalidConfigException.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/InvalidConfigException.java
@@ -17,14 +17,14 @@
 package com.ning.billing.catalog.api;
 
 public class InvalidConfigException extends Exception {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public InvalidConfigException(String arg0, Throwable arg1) {
-		super(arg0, arg1);
-	}
+    public InvalidConfigException(final String arg0, final Throwable arg1) {
+        super(arg0, arg1);
+    }
 
-	public InvalidConfigException(String arg0) {
-		super(arg0);
-	}
+    public InvalidConfigException(final String arg0) {
+        super(arg0);
+    }
 
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/Listing.java b/api/src/main/java/com/ning/billing/catalog/api/Listing.java
index 3fa0229..69ac8b5 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/Listing.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/Listing.java
@@ -17,8 +17,8 @@
 package com.ning.billing.catalog.api;
 
 public interface Listing {
-    
+
     Plan getPlan();
-    
+
     PriceList getPriceList();
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/MigrationPlan.java b/api/src/main/java/com/ning/billing/catalog/api/MigrationPlan.java
index a6f4e91..cdb0433 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/MigrationPlan.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/MigrationPlan.java
@@ -17,6 +17,6 @@
 package com.ning.billing.catalog.api;
 
 public interface MigrationPlan extends Plan {
-	public static final String MIGRATION_PLAN_NAME = "__KILLBILL_MIGRATION_PLAN__";
-	public static final String MIGRATION_PLAN_PHASE_NAME = "__KILLBILL_MIGRATION_PLAN_PHASE__";
+    public static final String MIGRATION_PLAN_NAME = "__KILLBILL_MIGRATION_PLAN__";
+    public static final String MIGRATION_PLAN_PHASE_NAME = "__KILLBILL_MIGRATION_PLAN_PHASE__";
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/OverdueActions.java b/api/src/main/java/com/ning/billing/catalog/api/OverdueActions.java
index 8525d91..d73db06 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/OverdueActions.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/OverdueActions.java
@@ -16,7 +16,7 @@
 
 package com.ning.billing.catalog.api;
 
-public enum OverdueActions  {
-	CANCEL,
-	PAYMENT_RETRY
+public enum OverdueActions {
+    CANCEL,
+    PAYMENT_RETRY
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/PhaseType.java b/api/src/main/java/com/ning/billing/catalog/api/PhaseType.java
index 06678c7..3a302ed 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/PhaseType.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/PhaseType.java
@@ -17,8 +17,8 @@
 package com.ning.billing.catalog.api;
 
 public enum PhaseType {
-	TRIAL,
-	DISCOUNT,
-	FIXEDTERM,
-	EVERGREEN
+    TRIAL,
+    DISCOUNT,
+    FIXEDTERM,
+    EVERGREEN
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/Plan.java b/api/src/main/java/com/ning/billing/catalog/api/Plan.java
index 3abbfbe..8518b94 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/Plan.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/Plan.java
@@ -23,28 +23,28 @@ import org.joda.time.DateTime;
 
 public interface Plan {
 
-	public abstract PlanPhase[] getInitialPhases();
+    public abstract PlanPhase[] getInitialPhases();
 
-	public abstract Product getProduct();
+    public abstract Product getProduct();
 
-	public abstract String getName();
+    public abstract String getName();
 
-	public abstract boolean isRetired();
+    public abstract boolean isRetired();
 
-	public abstract Iterator<PlanPhase> getInitialPhaseIterator();
+    public abstract Iterator<PlanPhase> getInitialPhaseIterator();
 
-	public abstract PlanPhase getFinalPhase();
+    public abstract PlanPhase getFinalPhase();
 
-	public abstract BillingPeriod getBillingPeriod();
+    public abstract BillingPeriod getBillingPeriod();
 
-	public abstract int getPlansAllowedInBundle();
+    public abstract int getPlansAllowedInBundle();
 
-	public abstract PlanPhase[] getAllPhases();
+    public abstract PlanPhase[] getAllPhases();
 
-	public abstract Date getEffectiveDateForExistingSubscriptons();
+    public abstract Date getEffectiveDateForExistingSubscriptons();
 
-	public abstract PlanPhase findPhase(String name) throws CatalogApiException;
+    public abstract PlanPhase findPhase(String name) throws CatalogApiException;
 
-	public abstract DateTime dateOfFirstRecurringNonZeroCharge(DateTime subscriptionStartDate);
-	
-}
\ No newline at end of file
+    public abstract DateTime dateOfFirstRecurringNonZeroCharge(DateTime subscriptionStartDate);
+
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/PlanAlignmentChange.java b/api/src/main/java/com/ning/billing/catalog/api/PlanAlignmentChange.java
index c883690..fc56ccd 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/PlanAlignmentChange.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/PlanAlignmentChange.java
@@ -17,8 +17,8 @@
 package com.ning.billing.catalog.api;
 
 public enum PlanAlignmentChange {
-	START_OF_BUNDLE,
-	START_OF_SUBSCRIPTION,
-	CHANGE_OF_PLAN,
-	CHANGE_OF_PRICELIST
+    START_OF_BUNDLE,
+    START_OF_SUBSCRIPTION,
+    CHANGE_OF_PLAN,
+    CHANGE_OF_PRICELIST
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/PlanAlignmentCreate.java b/api/src/main/java/com/ning/billing/catalog/api/PlanAlignmentCreate.java
index 7603d5e..5f4a851 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/PlanAlignmentCreate.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/PlanAlignmentCreate.java
@@ -17,6 +17,6 @@
 package com.ning.billing.catalog.api;
 
 public enum PlanAlignmentCreate {
-	START_OF_BUNDLE,
-	START_OF_SUBSCRIPTION,
+    START_OF_BUNDLE,
+    START_OF_SUBSCRIPTION,
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/PlanChangeResult.java b/api/src/main/java/com/ning/billing/catalog/api/PlanChangeResult.java
index 3974e87..705df5a 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/PlanChangeResult.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/PlanChangeResult.java
@@ -17,29 +17,29 @@
 package com.ning.billing.catalog.api;
 
 public class PlanChangeResult {
- 
-	private final PriceList newPriceList;
-	private final ActionPolicy policy;
-	private final PlanAlignmentChange alignment;
-	
-	public PlanChangeResult(PriceList newPriceList, ActionPolicy policy, PlanAlignmentChange alignment) {
-		super();
-		this.newPriceList = newPriceList;
-		this.policy = policy;
-		this.alignment = alignment;
-	}
-
-	public PriceList getNewPriceList() {
-		return newPriceList;
-	}
-
-	public ActionPolicy getPolicy() {
-		return policy;
-	}
-
-	public PlanAlignmentChange getAlignment() {
-		return alignment;
-	}	
-	 
-	
+
+    private final PriceList newPriceList;
+    private final ActionPolicy policy;
+    private final PlanAlignmentChange alignment;
+
+    public PlanChangeResult(final PriceList newPriceList, final ActionPolicy policy, final PlanAlignmentChange alignment) {
+        super();
+        this.newPriceList = newPriceList;
+        this.policy = policy;
+        this.alignment = alignment;
+    }
+
+    public PriceList getNewPriceList() {
+        return newPriceList;
+    }
+
+    public ActionPolicy getPolicy() {
+        return policy;
+    }
+
+    public PlanAlignmentChange getAlignment() {
+        return alignment;
+    }
+
+
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/PlanPhase.java b/api/src/main/java/com/ning/billing/catalog/api/PlanPhase.java
index 299909c..fa43433 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/PlanPhase.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/PlanPhase.java
@@ -19,21 +19,19 @@ package com.ning.billing.catalog.api;
 
 public interface PlanPhase {
 
-	public abstract InternationalPrice getRecurringPrice();
+    public abstract InternationalPrice getRecurringPrice();
 
-	public abstract InternationalPrice getFixedPrice();
+    public abstract InternationalPrice getFixedPrice();
 
-	public abstract BillingPeriod getBillingPeriod();
+    public abstract BillingPeriod getBillingPeriod();
 
-	public abstract String getName();
+    public abstract String getName();
 
-	public abstract Plan getPlan();
+    public abstract Plan getPlan();
 
-	public abstract Duration getDuration();
+    public abstract Duration getDuration();
 
-	public abstract PhaseType getPhaseType();
+    public abstract PhaseType getPhaseType();
 
 
-	
-
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/PlanPhaseSpecifier.java b/api/src/main/java/com/ning/billing/catalog/api/PlanPhaseSpecifier.java
index 18c864a..d737426 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/PlanPhaseSpecifier.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/PlanPhaseSpecifier.java
@@ -16,41 +16,44 @@
 
 package com.ning.billing.catalog.api;
 
-public class PlanPhaseSpecifier  {
-
-	private final PhaseType phaseType;
-	private final String productName;
-	private final ProductCategory productCategory;
-	private final BillingPeriod billingPeriod;
-	private final String priceListName;
-	
-	public PlanPhaseSpecifier(String productName, ProductCategory productCategory, BillingPeriod billingPeriod,
-			String priceListName, PhaseType phaseType) {
-		this.phaseType = phaseType;
-		this.productName = productName;
-		this.productCategory = productCategory;
-		this.billingPeriod = billingPeriod;
-		this.priceListName = priceListName;
-	}
-	
-	public String getProductName() {
-		return productName;
-	}
-	public ProductCategory getProductCategory() {
-		return productCategory;
-	}
-	public BillingPeriod getBillingPeriod() {
-		return billingPeriod;
-	}
-	public String getPriceListName() {
-		return priceListName;
-	}
-
-	public PhaseType getPhaseType() {
-		return phaseType;
-	}
-
-	public PlanSpecifier toPlanSpecifier() {
-		return new PlanSpecifier(productName, productCategory, billingPeriod, priceListName);
-	}
+public class PlanPhaseSpecifier {
+
+    private final PhaseType phaseType;
+    private final String productName;
+    private final ProductCategory productCategory;
+    private final BillingPeriod billingPeriod;
+    private final String priceListName;
+
+    public PlanPhaseSpecifier(final String productName, final ProductCategory productCategory, final BillingPeriod billingPeriod,
+                              final String priceListName, final PhaseType phaseType) {
+        this.phaseType = phaseType;
+        this.productName = productName;
+        this.productCategory = productCategory;
+        this.billingPeriod = billingPeriod;
+        this.priceListName = priceListName;
+    }
+
+    public String getProductName() {
+        return productName;
+    }
+
+    public ProductCategory getProductCategory() {
+        return productCategory;
+    }
+
+    public BillingPeriod getBillingPeriod() {
+        return billingPeriod;
+    }
+
+    public String getPriceListName() {
+        return priceListName;
+    }
+
+    public PhaseType getPhaseType() {
+        return phaseType;
+    }
+
+    public PlanSpecifier toPlanSpecifier() {
+        return new PlanSpecifier(productName, productCategory, billingPeriod, priceListName);
+    }
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/PlanSpecifier.java b/api/src/main/java/com/ning/billing/catalog/api/PlanSpecifier.java
index 39bba68..bc88ae6 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/PlanSpecifier.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/PlanSpecifier.java
@@ -17,38 +17,41 @@
 package com.ning.billing.catalog.api;
 
 public class PlanSpecifier {
-	private final String productName;
-	private final ProductCategory productCategory;
-	private final BillingPeriod billingPeriod;
-	private final String priceListName;
-	
-	public PlanSpecifier(String productName, ProductCategory productCategory, BillingPeriod billingPeriod,
-			String priceListName) {
-		super();
-		this.productName = productName;
-		this.productCategory = productCategory;
-		this.billingPeriod = billingPeriod;
-		this.priceListName = priceListName;
-	}
-	
-	public PlanSpecifier(PlanPhaseSpecifier planPhase) {
-		super();
-		this.productName = planPhase.getProductName();
-		this.productCategory = planPhase.getProductCategory();
-		this.billingPeriod = planPhase.getBillingPeriod();
-		this.priceListName = planPhase.getPriceListName();
-	}
-	
-	public String getProductName() {
-		return productName;
-	}
-	public ProductCategory getProductCategory() {
-		return productCategory;
-	}
-	public BillingPeriod getBillingPeriod() {
-		return billingPeriod;
-	}
-	public String getPriceListName() {
-		return priceListName;
-	}
+    private final String productName;
+    private final ProductCategory productCategory;
+    private final BillingPeriod billingPeriod;
+    private final String priceListName;
+
+    public PlanSpecifier(final String productName, final ProductCategory productCategory, final BillingPeriod billingPeriod,
+                         final String priceListName) {
+        super();
+        this.productName = productName;
+        this.productCategory = productCategory;
+        this.billingPeriod = billingPeriod;
+        this.priceListName = priceListName;
+    }
+
+    public PlanSpecifier(final PlanPhaseSpecifier planPhase) {
+        super();
+        this.productName = planPhase.getProductName();
+        this.productCategory = planPhase.getProductCategory();
+        this.billingPeriod = planPhase.getBillingPeriod();
+        this.priceListName = planPhase.getPriceListName();
+    }
+
+    public String getProductName() {
+        return productName;
+    }
+
+    public ProductCategory getProductCategory() {
+        return productCategory;
+    }
+
+    public BillingPeriod getBillingPeriod() {
+        return billingPeriod;
+    }
+
+    public String getPriceListName() {
+        return priceListName;
+    }
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/Price.java b/api/src/main/java/com/ning/billing/catalog/api/Price.java
index cf33ab0..a98275a 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/Price.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/Price.java
@@ -21,8 +21,8 @@ import java.math.BigDecimal;
 
 public interface Price {
 
-	public abstract Currency getCurrency();
+    public abstract Currency getCurrency();
 
-	public abstract BigDecimal getValue() throws CurrencyValueNull;
+    public abstract BigDecimal getValue() throws CurrencyValueNull;
 
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/PriceList.java b/api/src/main/java/com/ning/billing/catalog/api/PriceList.java
index 58a98fa..7ba912a 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/PriceList.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/PriceList.java
@@ -19,10 +19,10 @@ package com.ning.billing.catalog.api;
 
 public interface PriceList {
 
-	public abstract String getName();
+    public abstract String getName();
 
-	public abstract boolean isRetired();
+    public abstract boolean isRetired();
 
-	public abstract Plan findPlan(Product product, BillingPeriod period);
+    public abstract Plan findPlan(Product product, BillingPeriod period);
 
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/PriceListSet.java b/api/src/main/java/com/ning/billing/catalog/api/PriceListSet.java
index 33adcca..5e78044 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/PriceListSet.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/PriceListSet.java
@@ -18,8 +18,8 @@ package com.ning.billing.catalog.api;
 
 public interface PriceListSet {
 
-	public static final String DEFAULT_PRICELIST_NAME="DEFAULT";
+    public static final String DEFAULT_PRICELIST_NAME = "DEFAULT";
 
-	public abstract Plan getPlanListFrom(String priceListName, Product product, BillingPeriod period);
+    public abstract Plan getPlanListFrom(String priceListName, Product product, BillingPeriod period);
 
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/Product.java b/api/src/main/java/com/ning/billing/catalog/api/Product.java
index e226a0d..cb08271 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/Product.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/Product.java
@@ -19,17 +19,17 @@ package com.ning.billing.catalog.api;
 
 public interface Product {
 
-	public abstract String getName();
+    public abstract String getName();
 
-	public abstract boolean isRetired();
+    public abstract boolean isRetired();
 
-	public abstract Product[] getAvailable();
+    public abstract Product[] getAvailable();
 
-	public abstract Product[] getIncluded();
+    public abstract Product[] getIncluded();
 
-	public abstract ProductCategory getCategory();
+    public abstract ProductCategory getCategory();
 
-	public abstract String getCatalogName();
+    public abstract String getCatalogName();
 
 
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/ProductCategory.java b/api/src/main/java/com/ning/billing/catalog/api/ProductCategory.java
index 22eb658..5c67ec2 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/ProductCategory.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/ProductCategory.java
@@ -17,7 +17,7 @@
 package com.ning.billing.catalog.api;
 
 public enum ProductCategory {
-	BASE,
-	ADD_ON,
-	STANDALONE
+    BASE,
+    ADD_ON,
+    STANDALONE
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java b/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java
index 0b2ef57..3c35e29 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/StaticCatalog.java
@@ -25,45 +25,45 @@ public interface StaticCatalog {
     // Simple getters
     //
     public abstract String getCatalogName();
-    
+
     public abstract Date getEffectiveDate() throws CatalogApiException;
 
     public abstract Currency[] getCurrentSupportedCurrencies() throws CatalogApiException;
 
-	public abstract Product[] getCurrentProducts() throws CatalogApiException;
-	
-	public abstract Plan[] getCurrentPlans() throws CatalogApiException;
-	
-	//
-	// Find a plan
-	//
-	public abstract Plan findCurrentPlan(String productName, BillingPeriod term, String priceList) throws CatalogApiException;
+    public abstract Product[] getCurrentProducts() throws CatalogApiException;
+
+    public abstract Plan[] getCurrentPlans() throws CatalogApiException;
+
+    //
+    // Find a plan
+    //
+    public abstract Plan findCurrentPlan(String productName, BillingPeriod term, String priceList) throws CatalogApiException;
 
-	public abstract Plan findCurrentPlan(String name) throws CatalogApiException;
+    public abstract Plan findCurrentPlan(String name) throws CatalogApiException;
 
-	//
-	// Find a product
-	//
+    //
+    // Find a product
+    //
     public abstract Product findCurrentProduct(String name) throws CatalogApiException;
 
     //
     // Find a phase
     //
-    public abstract  PlanPhase findCurrentPhase(String name) throws CatalogApiException;
-    
+    public abstract PlanPhase findCurrentPhase(String name) throws CatalogApiException;
+
     //
     // Find a pricelist
     //
     public abstract PriceList findCurrentPricelist(String name) throws CatalogApiException;
-    
+
     //
     //  
     //
-	public abstract ActionPolicy planChangePolicy(PlanPhaseSpecifier from,
-			PlanSpecifier to) throws CatalogApiException;
+    public abstract ActionPolicy planChangePolicy(PlanPhaseSpecifier from,
+                                                  PlanSpecifier to) throws CatalogApiException;
 
-	public abstract PlanChangeResult planChange(PlanPhaseSpecifier from,
-			PlanSpecifier to) throws CatalogApiException;
+    public abstract PlanChangeResult planChange(PlanPhaseSpecifier from,
+                                                PlanSpecifier to) throws CatalogApiException;
 
 
     public abstract ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase) throws CatalogApiException;
@@ -73,10 +73,10 @@ public interface StaticCatalog {
     public abstract BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase) throws CatalogApiException;
 
     public abstract PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from,
-			PlanSpecifier to) throws CatalogApiException;
+                                                            PlanSpecifier to) throws CatalogApiException;
 
     public abstract boolean canCreatePlan(PlanSpecifier specifier) throws CatalogApiException;
 
     public abstract List<Listing> getAvailableAddonListings(String baseProductName) throws CatalogApiException;
 
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/TimeUnit.java b/api/src/main/java/com/ning/billing/catalog/api/TimeUnit.java
index 5271e29..019bfa9 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/TimeUnit.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/TimeUnit.java
@@ -20,8 +20,8 @@ import javax.xml.bind.annotation.XmlEnum;
 
 @XmlEnum
 public enum TimeUnit {
-	DAYS,
-	MONTHS,
-	YEARS,
-	UNLIMITED
-}
\ No newline at end of file
+    DAYS,
+    MONTHS,
+    YEARS,
+    UNLIMITED
+}
diff --git a/api/src/main/java/com/ning/billing/config/CatalogConfig.java b/api/src/main/java/com/ning/billing/config/CatalogConfig.java
index 73ffd9a..554dcea 100644
--- a/api/src/main/java/com/ning/billing/config/CatalogConfig.java
+++ b/api/src/main/java/com/ning/billing/config/CatalogConfig.java
@@ -20,7 +20,6 @@ import org.skife.config.Config;
 import org.skife.config.Default;
 
 public interface CatalogConfig extends KillbillConfig {
-
     @Config("killbill.catalog.uri")
     @Default("jar:///com/ning/billing/irs/catalog/Catalog.xml")
     String getCatalogURI();
diff --git a/api/src/main/java/com/ning/billing/config/EntitlementConfig.java b/api/src/main/java/com/ning/billing/config/EntitlementConfig.java
index 12418c6..088fc45 100644
--- a/api/src/main/java/com/ning/billing/config/EntitlementConfig.java
+++ b/api/src/main/java/com/ning/billing/config/EntitlementConfig.java
@@ -19,17 +19,14 @@ package com.ning.billing.config;
 import org.skife.config.Config;
 import org.skife.config.Default;
 
-import com.google.common.annotations.VisibleForTesting;
-
-public interface EntitlementConfig extends NotificationConfig, KillbillConfig  {
-
-	@Override
+public interface EntitlementConfig extends NotificationConfig, KillbillConfig {
+    @Override
     @Config("killbill.entitlement.engine.notifications.sleep")
     @Default("500")
-    public long getSleepTimeMs();    
+    public long getSleepTimeMs();
 
-	@Override
-    @Config("killbill.notifications.off")
+    @Override
+    @Config("killbill.entitlement.engine.notifications.off")
     @Default("false")
     public boolean isNotificationProcessingOff();
 }
diff --git a/api/src/main/java/com/ning/billing/config/InvoiceConfig.java b/api/src/main/java/com/ning/billing/config/InvoiceConfig.java
index 407f4d3..a8b11df 100644
--- a/api/src/main/java/com/ning/billing/config/InvoiceConfig.java
+++ b/api/src/main/java/com/ning/billing/config/InvoiceConfig.java
@@ -19,19 +19,22 @@ package com.ning.billing.config;
 import org.skife.config.Config;
 import org.skife.config.Default;
 
-public interface InvoiceConfig extends NotificationConfig, KillbillConfig  {
-
-    @Override    
+public interface InvoiceConfig extends NotificationConfig, KillbillConfig {
+    @Override
     @Config("killbill.invoice.engine.notifications.sleep")
     @Default("500")
     public long getSleepTimeMs();
 
     @Override
-    @Config("killbill.notifications.off")
+    @Config("killbill.invoice.engine.notifications.off")
     @Default("false")
     public boolean isNotificationProcessingOff();
 
     @Config("killbill.invoice.maxNumberOfMonthsInFuture")
     @Default("36")
     public int getNumberOfMonthsInFuture();
+
+    @Config("killbill.invoice.emailNotificationsEnabled")
+    @Default("false")
+    public boolean isEmailNotificationsEnabled();
 }
diff --git a/api/src/main/java/com/ning/billing/config/KillbillConfig.java b/api/src/main/java/com/ning/billing/config/KillbillConfig.java
index 336f806..f577d2c 100644
--- a/api/src/main/java/com/ning/billing/config/KillbillConfig.java
+++ b/api/src/main/java/com/ning/billing/config/KillbillConfig.java
@@ -1,5 +1,5 @@
-/* 
- * Copyright 2010-2011 Ning, Inc.
+/*
+ * 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
diff --git a/api/src/main/java/com/ning/billing/config/NotificationConfig.java b/api/src/main/java/com/ning/billing/config/NotificationConfig.java
index 630a2d6..6da8821 100644
--- a/api/src/main/java/com/ning/billing/config/NotificationConfig.java
+++ b/api/src/main/java/com/ning/billing/config/NotificationConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * 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
diff --git a/api/src/main/java/com/ning/billing/config/PaymentConfig.java b/api/src/main/java/com/ning/billing/config/PaymentConfig.java
index 7e8d5cc..efd012e 100644
--- a/api/src/main/java/com/ning/billing/config/PaymentConfig.java
+++ b/api/src/main/java/com/ning/billing/config/PaymentConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * 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
@@ -22,9 +22,7 @@ import org.skife.config.Config;
 import org.skife.config.Default;
 
 
-public interface PaymentConfig extends NotificationConfig, KillbillConfig  {
-	
-
+public interface PaymentConfig extends NotificationConfig, KillbillConfig {
     @Config("killbill.payment.provider.default")
     @Default("noop")
     public String getDefaultPaymentProvider();
@@ -45,13 +43,13 @@ public interface PaymentConfig extends NotificationConfig, KillbillConfig  {
     @Default("8")
     public int getPluginFailureRetryMaxAttempts();
 
-	@Override
+    @Override
     @Config("killbill.payment.engine.notifications.sleep")
     @Default("500")
     public long getSleepTimeMs();
 
-	@Override
-    @Config("killbill.payment.engine.events.off")
+    @Override
+    @Config("killbill.payment.engine.notifications.off")
     @Default("false")
     public boolean isNotificationProcessingOff();
 
diff --git a/api/src/main/java/com/ning/billing/config/PersistentQueueConfig.java b/api/src/main/java/com/ning/billing/config/PersistentQueueConfig.java
index c7e1515..13a9dcb 100644
--- a/api/src/main/java/com/ning/billing/config/PersistentQueueConfig.java
+++ b/api/src/main/java/com/ning/billing/config/PersistentQueueConfig.java
@@ -1,5 +1,5 @@
-/* 
- * Copyright 2010-2011 Ning, Inc.
+/*
+ * 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
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/billing/BillingEvent.java b/api/src/main/java/com/ning/billing/entitlement/api/billing/BillingEvent.java
index db1761e..ee661bc 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/billing/BillingEvent.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/billing/BillingEvent.java
@@ -37,87 +37,75 @@ public interface BillingEvent extends Comparable<BillingEvent> {
     public Account getAccount();
 
     /**
-     *
      * @return the billCycleDay as seen for that subscription at that time
-     *
-     * Note: The billCycleDay may come from the Account, or the bundle or the subscription itself
+     *         <p/>
+     *         Note: The billCycleDay may come from the Account, or the bundle or the subscription itself
      */
     public int getBillCycleDay();
 
     /**
-     *
      * @return the subscription
      */
     public Subscription getSubscription();
 
     /**
-     *
      * @return the date for when that event became effective
      */
     public DateTime getEffectiveDate();
 
     /**
-     *
      * @return the plan phase
      */
     public PlanPhase getPlanPhase();
 
 
     /**
-     *
      * @return the plan
      */
     public Plan getPlan();
 
     /**
-     *
      * @return the billing period for the active phase
      */
     public BillingPeriod getBillingPeriod();
 
     /**
-     *
      * @return the billing mode for the current event
      */
     public BillingModeType getBillingMode();
 
     /**
-     *
      * @return the description of the billing event
      */
     public String getDescription();
 
     /**
-     *
      * @return the fixed price for the phase
      */
     public BigDecimal getFixedPrice();
 
     /**
-     *
      * @return the recurring price for the phase
      */
     public BigDecimal getRecurringPrice();
 
     /**
-     *
      * @return the currency for the account being invoiced
      */
     public Currency getCurrency();
 
-	/**
-	 * @return the transition type of the underlying subscription event that triggered this
-	 */
-	public SubscriptionTransitionType getTransitionType();
-
-	/**
-	 * @return a unique long indicating the ordering on which events got inserted on disk-- used for sorting only
-	 */
-	public Long getTotalOrdering();
-	
-	/**
-	 * 
-	 * @return The TimeZone of the account
-	 */
+    /**
+     * @return the transition type of the underlying subscription event that triggered this
+     */
+    public SubscriptionTransitionType getTransitionType();
+
+    /**
+     * @return a unique long indicating the ordering on which events got inserted on disk-- used for sorting only
+     */
+    public Long getTotalOrdering();
+
+    /**
+     * @return The TimeZone of the account
+     */
     public DateTimeZone getTimeZone();
- }
+}
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/billing/ChargeThruApi.java b/api/src/main/java/com/ning/billing/entitlement/api/billing/ChargeThruApi.java
index 69eb454..25a643f 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/billing/ChargeThruApi.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/billing/ChargeThruApi.java
@@ -19,7 +19,6 @@ package com.ning.billing.entitlement.api.billing;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
-import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
 import com.ning.billing.util.callcontext.CallContext;
 
@@ -30,10 +29,10 @@ public interface ChargeThruApi {
      * @return UUID of
      */
     public UUID getAccountIdFromSubscriptionId(UUID subscriptionId) throws EntitlementBillingApiException;
-    
+
     /**
      * Sets the charged through date for the subscription with that Id.
-     * 
+     *
      * @param subscriptionId
      * @param ctd
      * @param context
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/billing/EntitlementBillingApiException.java b/api/src/main/java/com/ning/billing/entitlement/api/billing/EntitlementBillingApiException.java
index 4c20f7c..7e16c7e 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/billing/EntitlementBillingApiException.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/billing/EntitlementBillingApiException.java
@@ -22,15 +22,15 @@ import com.ning.billing.ErrorCode;
 public class EntitlementBillingApiException extends BillingExceptionBase {
     private static final long serialVersionUID = 127392038L;
 
-    public EntitlementBillingApiException(Throwable cause, int code, final String msg) {
+    public EntitlementBillingApiException(final Throwable cause, final int code, final String msg) {
         super(cause, code, msg);
     }
 
-    public EntitlementBillingApiException(Throwable cause, ErrorCode code, final Object... args) {
+    public EntitlementBillingApiException(final Throwable cause, final ErrorCode code, final Object... args) {
         super(cause, code, args);
     }
 
-    public EntitlementBillingApiException(ErrorCode code, final Object... args) {
+    public EntitlementBillingApiException(final ErrorCode code, final Object... args) {
         super(code, args);
     }
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/migration/EntitlementMigrationApi.java b/api/src/main/java/com/ning/billing/entitlement/api/migration/EntitlementMigrationApi.java
index 09ac359..f0352e7 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/migration/EntitlementMigrationApi.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/migration/EntitlementMigrationApi.java
@@ -18,38 +18,43 @@ package com.ning.billing.entitlement.api.migration;
 
 import java.util.UUID;
 
-import com.ning.billing.util.callcontext.CallContext;
 import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.util.callcontext.CallContext;
 
 public interface EntitlementMigrationApi {
 
 
     public interface EntitlementAccountMigration {
         public UUID getAccountKey();
-        public EntitlementBundleMigration [] getBundles();
+
+        public EntitlementBundleMigration[] getBundles();
     }
 
     public interface EntitlementBundleMigration {
         public String getBundleKey();
-        public EntitlementSubscriptionMigration [] getSubscriptions();
+
+        public EntitlementSubscriptionMigration[] getSubscriptions();
     }
 
     public interface EntitlementSubscriptionMigration {
         public ProductCategory getCategory();
+
         public DateTime getChargedThroughDate();
-        public EntitlementSubscriptionMigrationCase [] getSubscriptionCases();
+
+        public EntitlementSubscriptionMigrationCase[] getSubscriptionCases();
     }
 
     /**
-     *
      * Each case is either a PHASE or a different PlanSpecifier
      */
     public interface EntitlementSubscriptionMigrationCase {
         public PlanPhaseSpecifier getPlanPhaseSpecifier();
+
         public DateTime getEffectiveDate();
+
         public DateTime getCancelledDate();
     }
 
@@ -59,9 +64,9 @@ public interface EntitlementMigrationApi {
      * The semantics is 'all or nothing' (atomic operation)
      *
      * @param toBeMigrated all the bundles and associated subscription that should be migrated for the account
-     * @throws EntitlementMigrationApiException an entitlement api exception
-     *
+     * @throws EntitlementMigrationApiException
+     *          an entitlement api exception
      */
     public void migrate(EntitlementAccountMigration toBeMigrated, CallContext context)
-        throws EntitlementMigrationApiException;
+            throws EntitlementMigrationApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/migration/EntitlementMigrationApiException.java b/api/src/main/java/com/ning/billing/entitlement/api/migration/EntitlementMigrationApiException.java
index 55835fd..8a9881f 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/migration/EntitlementMigrationApiException.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/migration/EntitlementMigrationApiException.java
@@ -24,15 +24,15 @@ public class EntitlementMigrationApiException extends Exception {
         super();
     }
 
-    public EntitlementMigrationApiException(String message, Throwable cause) {
+    public EntitlementMigrationApiException(final String message, final Throwable cause) {
         super(message, cause);
     }
 
-    public EntitlementMigrationApiException(String message) {
+    public EntitlementMigrationApiException(final String message) {
         super(message);
     }
 
-    public EntitlementMigrationApiException(Throwable cause) {
+    public EntitlementMigrationApiException(final Throwable cause) {
         super(cause);
     }
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/timeline/BundleTimeline.java b/api/src/main/java/com/ning/billing/entitlement/api/timeline/BundleTimeline.java
index 6b12f9d..ff8823f 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/timeline/BundleTimeline.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/timeline/BundleTimeline.java
@@ -21,9 +21,9 @@ import java.util.UUID;
 public interface BundleTimeline {
 
     String getViewId();
-    
+
     UUID getBundleId();
-    
+
     String getExternalKey();
 
     List<SubscriptionTimeline> getSubscriptions();
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementRepairException.java b/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementRepairException.java
index 56cdd99..0e38426 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementRepairException.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementRepairException.java
@@ -24,18 +24,19 @@ public class EntitlementRepairException extends BillingExceptionBase {
 
     private static final long serialVersionUID = 19067233L;
 
-    public EntitlementRepairException(EntitlementUserApiException e) {
+    public EntitlementRepairException(final EntitlementUserApiException e) {
         super(e, e.getCode(), e.getMessage());
     }
-    
-    public EntitlementRepairException(CatalogApiException e) {
+
+    public EntitlementRepairException(final CatalogApiException e) {
         super(e, e.getCode(), e.getMessage());
     }
-    public EntitlementRepairException(Throwable e, ErrorCode code, Object...args) {
+
+    public EntitlementRepairException(final Throwable e, final ErrorCode code, final Object... args) {
         super(e, code, args);
     }
 
-    public EntitlementRepairException(ErrorCode code, Object...args) {
+    public EntitlementRepairException(final ErrorCode code, final Object... args) {
         super(code, args);
     }
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementTimelineApi.java b/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementTimelineApi.java
index b76f25a..0bdf47f 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementTimelineApi.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/timeline/EntitlementTimelineApi.java
@@ -20,8 +20,8 @@ import java.util.UUID;
 import com.ning.billing.util.callcontext.CallContext;
 
 public interface EntitlementTimelineApi {
-    
+
     public BundleTimeline getBundleRepair(final UUID bundleId) throws EntitlementRepairException;
-    
+
     public BundleTimeline repairBundle(final BundleTimeline input, final boolean dryRun, final CallContext context) throws EntitlementRepairException;
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementEvent.java b/api/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementEvent.java
index 0ab6720..9a32c61 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementEvent.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementEvent.java
@@ -24,7 +24,7 @@ import com.ning.billing.util.bus.BusEvent;
 public interface RepairEntitlementEvent extends BusEvent {
 
     public UUID getAccountId();
-    
+
     public UUID getBundleId();
 
     public DateTime getEffectiveDate();
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionTimeline.java b/api/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionTimeline.java
index 434cb39..9374c62 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionTimeline.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionTimeline.java
@@ -26,24 +26,26 @@ import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 public interface SubscriptionTimeline {
 
     public UUID getId();
-    
+
     public List<DeletedEvent> getDeletedEvents();
 
-    public List<NewEvent> getNewEvents();    
-   
-    public List<ExistingEvent> getExistingEvents();    
-    
+    public List<NewEvent> getNewEvents();
+
+    public List<ExistingEvent> getExistingEvents();
+
     public interface DeletedEvent {
         public UUID getEventId();
     }
-    
+
     public interface NewEvent {
         public PlanPhaseSpecifier getPlanPhaseSpecifier();
+
         public DateTime getRequestedDate();
+
         public SubscriptionTransitionType getSubscriptionTransitionType();
-        
+
     }
-    
+
     public interface ExistingEvent extends DeletedEvent, NewEvent {
         public DateTime getEffectiveDate();
     }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java b/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
index 1e8d7fd..3757319 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
@@ -19,11 +19,10 @@ package com.ning.billing.entitlement.api.user;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.callcontext.CallContext;
 import org.joda.time.DateTime;
 
-import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
+import com.ning.billing.util.callcontext.CallContext;
 
 
 public interface EntitlementUserApi {
@@ -39,17 +38,17 @@ public interface EntitlementUserApi {
     public List<Subscription> getSubscriptionsForBundle(UUID bundleId);
 
     public List<Subscription> getSubscriptionsForKey(String bundleKey);
-    
+
     public Subscription getBaseSubscription(UUID bundleId) throws EntitlementUserApiException;
 
     public SubscriptionBundle createBundleForAccount(UUID accountId, String bundleKey, CallContext context)
-        throws EntitlementUserApiException;
+            throws EntitlementUserApiException;
 
     public Subscription createSubscription(UUID bundleId, PlanPhaseSpecifier spec, DateTime requestedDate, CallContext context)
-        throws EntitlementUserApiException;
+            throws EntitlementUserApiException;
 
     public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(UUID subscriptionId, String productName, DateTime requestedDate)
-    throws EntitlementUserApiException;
-    
+            throws EntitlementUserApiException;
+
     public DateTime getNextBillingDate(UUID account);
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApiException.java b/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApiException.java
index 11cf455..b4ecc4d 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApiException.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApiException.java
@@ -24,18 +24,19 @@ public class EntitlementUserApiException extends BillingExceptionBase {
 
     private static final long serialVersionUID = 19083233L;
 
-    public EntitlementUserApiException(CatalogApiException e) {
+    public EntitlementUserApiException(final CatalogApiException e) {
         super(e, e.getCode(), e.getMessage());
     }
-    public EntitlementUserApiException(Throwable e, ErrorCode code, Object...args) {
+
+    public EntitlementUserApiException(final Throwable e, final ErrorCode code, final Object... args) {
         super(e, code, args);
     }
 
-    public EntitlementUserApiException(Throwable e, int code, String message) {
+    public EntitlementUserApiException(final Throwable e, final int code, final String message) {
         super(e, code, message);
     }
 
-    public EntitlementUserApiException(ErrorCode code, Object...args) {
+    public EntitlementUserApiException(final ErrorCode code, final Object... args) {
         super(code, args);
     }
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java b/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
index 37f4ed8..e6f024c 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
@@ -35,16 +35,16 @@ import com.ning.billing.util.entity.Entity;
 public interface Subscription extends Entity, Blockable {
 
     public boolean cancel(DateTime requestedDate, boolean eot, CallContext context)
-    throws EntitlementUserApiException;
+            throws EntitlementUserApiException;
 
     public boolean uncancel(CallContext context)
-    throws EntitlementUserApiException;
+            throws EntitlementUserApiException;
 
     public boolean changePlan(String productName, BillingPeriod term, String planSet, DateTime requestedDate, CallContext context)
-    throws EntitlementUserApiException;
+            throws EntitlementUserApiException;
 
     public boolean recreate(PlanPhaseSpecifier spec, DateTime requestedDate, CallContext context)
-        throws EntitlementUserApiException;
+            throws EntitlementUserApiException;
 
     public enum SubscriptionState {
         ACTIVE,
@@ -74,6 +74,6 @@ public interface Subscription extends Entity, Blockable {
     public SubscriptionEvent getPendingTransition();
 
     public SubscriptionEvent getPreviousTransition();
-    
+
     public List<SubscriptionEvent> getBillingTransitions();
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java
index fddb5e9..61c76ee 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundle.java
@@ -18,12 +18,11 @@ package com.ning.billing.entitlement.api.user;
 
 import java.util.UUID;
 
-import com.ning.billing.util.entity.Entity;
 import org.joda.time.DateTime;
 
 import com.ning.billing.junction.api.Blockable;
-import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.overdue.OverdueState;
+import com.ning.billing.util.entity.Entity;
 
 public interface SubscriptionBundle extends Blockable, Entity {
 
@@ -34,5 +33,5 @@ public interface SubscriptionBundle extends Blockable, Entity {
     public String getKey();
 
     public OverdueState<SubscriptionBundle> getOverdueState();
-    
+
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvent.java b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvent.java
index 2745c33..6d22268 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvent.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvent.java
@@ -20,13 +20,7 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.ning.billing.catalog.api.Plan;
-import com.ning.billing.catalog.api.PlanPhase;
-
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
-
-import com.ning.billing.catalog.api.PriceList;
-
 import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.util.bus.BusEvent;
 
@@ -39,7 +33,7 @@ public interface SubscriptionEvent extends BusEvent {
     UUID getBundleId();
 
     UUID getSubscriptionId();
-    
+
     DateTime getSubscriptionStartDate();
 
     DateTime getRequestedTransitionTime();
@@ -61,9 +55,9 @@ public interface SubscriptionEvent extends BusEvent {
     SubscriptionState getNextState();
 
     String getNextPriceList();
-    
+
     Integer getRemainingEventsForUserOperation();
-    
+
     Long getTotalOrdering();
-    
+
 }
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionStatusDryRun.java b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionStatusDryRun.java
index 36048fa..a659446 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionStatusDryRun.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionStatusDryRun.java
@@ -23,17 +23,17 @@ import com.ning.billing.catalog.api.PhaseType;
 public interface SubscriptionStatusDryRun {
 
     public UUID getId();
-    
+
     public String getProductName();
-    
+
     public BillingPeriod getBillingPeriod();
-    
+
     public String getPriceList();
-    
+
     public PhaseType getPhaseType();
 
     public DryRunChangeReason getReason();
-    
+
     public enum DryRunChangeReason {
         AO_INCLUDED_IN_NEW_PLAN,
         AO_NOT_AVAILABLE_IN_NEW_PLAN,
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 5ceb670..0cda076 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -44,7 +44,7 @@ public enum ErrorCode {
     ENT_CHANGE_NON_ACTIVE(1021, "Subscription %s is in state %s: Failed to change plan"),
     ENT_CHANGE_FUTURE_CANCELLED(1022, "Subscription %s is future cancelled: Failed to change plan"),
     ENT_CHANGE_DRY_RUN_NOT_BP(1022, "Change DryRun API is only available for BP"),
-    
+
     /* Cancellation */
     ENT_CANCEL_BAD_STATE(1031, "Subscription %s is in state %s: Failed to cancel"),
     /* Recreation */
@@ -62,26 +62,26 @@ public enum ErrorCode {
 
     /* Repair */
     ENT_REPAIR_INVALID_DELETE_SET(1091, "Event %s is not deleted for subscription %s but prior events were"),
-    ENT_REPAIR_NON_EXISTENT_DELETE_EVENT(1092, "Event %s does not exist for subscription %s"),    
+    ENT_REPAIR_NON_EXISTENT_DELETE_EVENT(1092, "Event %s does not exist for subscription %s"),
     ENT_REPAIR_MISSING_AO_DELETE_EVENT(1093, "Event %s should be in deleted set for subscription %s because BP events got deleted earlier"),
     ENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING(1094, "New event %s for subscription %s is before last remaining event for BP"),
     ENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING(1095, "New event %s for subscription %s is before last remaining event"),
     ENT_REPAIR_UNKNOWN_TYPE(1096, "Unknown new event type %s for subscription %s"),
-    ENT_REPAIR_UNKNOWN_BUNDLE(1097, "Unknown bundle %s"), 
-    ENT_REPAIR_UNKNOWN_SUBSCRIPTION(1098, "Unknown subscription %s"),     
-    ENT_REPAIR_NO_ACTIVE_SUBSCRIPTIONS(1099, "No active subscriptions on bundle %s"),         
-    ENT_REPAIR_VIEW_CHANGED(1100, "View for bundle %s has changed from %s to %s"),             
-    ENT_REPAIR_SUB_RECREATE_NOT_EMPTY(1101, "Subscription %s with recreation for bundle %s should specify all existing events to be deleted"),    
-    ENT_REPAIR_SUB_EMPTY(1102, "Subscription %s with recreation for bundle %s should specify all existing events to be deleted"),    
-    ENT_REPAIR_BP_RECREATE_MISSING_AO(1103, "BP recreation for bundle %s implies repair all subscriptions"),    
-    ENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE(1104, "BP recreation for bundle %s implies that all AO should be start also with a CREATE"),        
-    ENT_REPAIR_AO_CREATE_BEFORE_BP_START(1105, "Can't recreate AO %s for bundle %s before BP starts"),    
-    
-    
+    ENT_REPAIR_UNKNOWN_BUNDLE(1097, "Unknown bundle %s"),
+    ENT_REPAIR_UNKNOWN_SUBSCRIPTION(1098, "Unknown subscription %s"),
+    ENT_REPAIR_NO_ACTIVE_SUBSCRIPTIONS(1099, "No active subscriptions on bundle %s"),
+    ENT_REPAIR_VIEW_CHANGED(1100, "View for bundle %s has changed from %s to %s"),
+    ENT_REPAIR_SUB_RECREATE_NOT_EMPTY(1101, "Subscription %s with recreation for bundle %s should specify all existing events to be deleted"),
+    ENT_REPAIR_SUB_EMPTY(1102, "Subscription %s with recreation for bundle %s should specify all existing events to be deleted"),
+    ENT_REPAIR_BP_RECREATE_MISSING_AO(1103, "BP recreation for bundle %s implies repair all subscriptions"),
+    ENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE(1104, "BP recreation for bundle %s implies that all AO should be start also with a CREATE"),
+    ENT_REPAIR_AO_CREATE_BEFORE_BP_START(1105, "Can't recreate AO %s for bundle %s before BP starts"),
+
+
     ENT_BUNDLE_IS_OVERDUE_BLOCKED(1090, "Changes to this bundle are blocked by overdue enforcement (%s :  %s)"),
     ENT_ACCOUNT_IS_OVERDUE_BLOCKED(1091, "Changes to this account are blocked by overdue enforcement (%s)"),
- 
-    
+
+
     /*
     *
     * Range 2000 : CATALOG
@@ -94,35 +94,35 @@ public enum ErrorCode {
 
     /* Plan change is disallowed by the catalog */
     CAT_ILLEGAL_CHANGE_REQUEST(2001, "Attempting to change plan from (product: '%s', billing period: '%s', " +
-    		"pricelist '%s') to (product: '%s', billing period: '%s', pricelist '%s'). This transition is not allowed by catalog rules"),
+            "pricelist '%s') to (product: '%s', billing period: '%s', pricelist '%s'). This transition is not allowed by catalog rules"),
 
-	/*
-	 * Price list
-	 */
+    /*
+      * Price list
+      */
 
-	/*Attempt to reference a price that is not present - should only happen if it is a currency not available in the catalog */
+    /*Attempt to reference a price that is not present - should only happen if it is a currency not available in the catalog */
     CAT_NO_PRICE_FOR_CURRENCY(2010, "This price does not have a value for the currency '%s'."),
 
     /* Price value explicitly set to NULL meaning there is no price available in that currency */
     CAT_PRICE_VALUE_NULL_FOR_CURRENCY(2011, "The value for the currency '%s' is NULL. This plan cannot be bought in this currency."),
-    CAT_NULL_PRICE_LIST_NAME(2012,"Price list name was null"),
+    CAT_NULL_PRICE_LIST_NAME(2012, "Price list name was null"),
     CAT_PRICE_LIST_NOT_FOUND(2013, "Could not find a pricelist with name '%s'"),
     /*
      * Plans
      */
-    CAT_PLAN_NOT_FOUND(2020,"Could not find a plan matching: (product: '%s', billing period: '%s', pricelist '%s')"),
-    CAT_NO_SUCH_PLAN(2021,"Could not find any plans named '%s'"),
+    CAT_PLAN_NOT_FOUND(2020, "Could not find a plan matching: (product: '%s', billing period: '%s', pricelist '%s')"),
+    CAT_NO_SUCH_PLAN(2021, "Could not find any plans named '%s'"),
 
     /*
      * Products
      */
-    CAT_NO_SUCH_PRODUCT(2030,"Could not find any product named '%s'"),
-    CAT_NULL_PRODUCT_NAME(2031,"Product name was null"),
+    CAT_NO_SUCH_PRODUCT(2030, "Could not find any product named '%s'"),
+    CAT_NULL_PRODUCT_NAME(2031, "Product name was null"),
     /*
      * Phases
      */
-    CAT_NO_SUCH_PHASE(2040,"Could not find any phases named '%s'"),
-    CAT_BAD_PHASE_NAME(2041,"Bad phase name '%s'"),
+    CAT_NO_SUCH_PHASE(2040, "Could not find any phases named '%s'"),
+    CAT_BAD_PHASE_NAME(2041, "Bad phase name '%s'"),
     /*
      * Versioned Catalog
      */
@@ -139,7 +139,7 @@ public enum ErrorCode {
     CAT_NO_SUCH_OVEDUE_STATE(2070, "No such overdue state '%s'"),
     CAT_MISSING_CLEAR_STATE(2071, "Missing a clear state"),
     CAT_NO_OVERDUEABLE_TYPE(2072, "No such overdueable type: "),
-   /*
+    /*
     *
     * Range 3000 : ACCOUNT
     *
@@ -153,7 +153,7 @@ public enum ErrorCode {
     ACCOUNT_CREATION_FAILED(3006, "Account creation failed."),
     ACCOUNT_UPDATE_FAILED(3007, "Account update failed."),
 
-   /*
+    /*
     *
     * Range 3900: Tag definitions
     *
@@ -162,17 +162,17 @@ public enum ErrorCode {
     TAG_DEFINITION_ALREADY_EXISTS(3901, "The tag definition name already exists (name: %s)"),
     TAG_DEFINITION_DOES_NOT_EXIST(3902, "The tag definition name does not exist (name: %s)"),
     TAG_DEFINITION_IN_USE(3903, "The tag definition name is currently in use (name: %s)"),
-    
+
     CONTROL_TAG_DOES_NOT_EXIST(3904, "The control tag does not exist (name: %s)"),
 
-   /*
+    /*
     *
     * Range 3950: Tags
     *
     */
     TAG_DOES_NOT_EXIST(3950, "The tag does not exist (name: %s)"),
 
-   /*
+    /*
     *
     * Range 4000: INVOICE
     *
@@ -182,7 +182,9 @@ public enum ErrorCode {
     INVOICE_NO_ACCOUNT_ID_FOR_SUBSCRIPTION_ID(4003, "No account id was retrieved for subscription id %s"),
     INVOICE_INVALID_DATE_SEQUENCE(4004, "Date sequence was invalid. Start Date: %s; End Date: %s; Target Date: %s"),
     INVOICE_TARGET_DATE_TOO_FAR_IN_THE_FUTURE(4005, "The target date was too far in the future. Target Date: %s"),
-
+    INVOICE_NOT_FOUND(4006, "No invoice could be found for id %s."),
+    INVOICE_NOTHING_TO_DO(4007, "No invoice to generate for account %s and date %s"),
+    
     /*
      *
      * Range 4900: Invoice payment
@@ -198,9 +200,9 @@ public enum ErrorCode {
      * Range 5000: Overdue system
      * 
      */
-    OVERDUE_CAT_ERROR_ENCOUNTERED(5001,"Catalog error encountered on Overdueable: id='%s', type='%s'"),  
-    OVERDUE_TYPE_NOT_SUPPORTED(5002,"Overdue of this type is not supported: id='%s', type='%s'"),  
-    OVERDUE_NO_REEVALUATION_INTERVAL(5003,"No valid reevaluation interval for state (name: %s)"),
+    OVERDUE_CAT_ERROR_ENCOUNTERED(5001, "Catalog error encountered on Overdueable: id='%s', type='%s'"),
+    OVERDUE_TYPE_NOT_SUPPORTED(5002, "Overdue of this type is not supported: id='%s', type='%s'"),
+    OVERDUE_NO_REEVALUATION_INTERVAL(5003, "No valid reevaluation interval for state (name: %s)"),
     OVERDUE_NOT_CONFIGURED(5004, "No configuration was found for the overdue system"),
     /*
      * 
@@ -209,40 +211,40 @@ public enum ErrorCode {
      */
     BLOCK_BLOCKED_ACTION(6000, "The action %s is block on this %s with id=%s"),
     BLOCK_TYPE_NOT_SUPPORTED(6001, "The Blockable type '%s' is not supported"),
-    
-    
+
+
     /*
-     * Range 7000 : Payment
-     */
-    
+    * Range 7000 : Payment
+    */
+
     PAYMENT_NO_SUCH_PAYMENT_METHOD(7000, "Payment method for account %s, and paymentId %s does not exist"),
     PAYMENT_NO_PAYMENT_METHODS(7001, "Payment methods for account %s don't exist"),
     PAYMENT_UPD_GATEWAY_FAILED(7002, "Failed to update payment gateway for account %s : %s"),
-    PAYMENT_GET_PAYMENT_PROVIDER(7003, "Failed to retrieve payment provider for account %s : %s"),    
-    PAYMENT_GET_PAYMENT_METHODS(7004, "Failed to retrieve payment method for account %s : %s"),        
-    PAYMENT_ADD_PAYMENT_METHOD(7005, "Failed to add payment method for account %s : %s"),        
-    PAYMENT_REFRESH_PAYMENT_METHOD(7006, "Failed to resfresh payment methods for account %s : %s"),            
-    PAYMENT_DEL_PAYMENT_METHOD(7007, "Failed to delete payment method for account %s : %s"),        
-    PAYMENT_UPD_PAYMENT_METHOD(7008, "Failed to update payment method for account %s : %s"),            
-    PAYMENT_CREATE_PAYMENT(7009, "Failed to create payment for account %s : %s"),                
-    PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT(70010, "Failed to create payment for account %s and attempt %s : %s"),                    
-    PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT_WITH_NON_POSITIVE_INV(7011, "Got payment attempt with negative or null invoice for account %s"),                        
-    PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT_BAD(7012, "Failed to create payment for attempts %s "),                    
-    PAYMENT_CREATE_PAYMENT_PROVIDER_ACCOUNT(7013, "Failed to create payment provider account for account %s : %s"),                
+    PAYMENT_GET_PAYMENT_PROVIDER(7003, "Failed to retrieve payment provider for account %s : %s"),
+    PAYMENT_GET_PAYMENT_METHODS(7004, "Failed to retrieve payment method for account %s : %s"),
+    PAYMENT_ADD_PAYMENT_METHOD(7005, "Failed to add payment method for account %s : %s"),
+    PAYMENT_REFRESH_PAYMENT_METHOD(7006, "Failed to resfresh payment methods for account %s : %s"),
+    PAYMENT_DEL_PAYMENT_METHOD(7007, "Failed to delete payment method for account %s : %s"),
+    PAYMENT_UPD_PAYMENT_METHOD(7008, "Failed to update payment method for account %s : %s"),
+    PAYMENT_CREATE_PAYMENT(7009, "Failed to create payment for account %s : %s"),
+    PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT(70010, "Failed to create payment for account %s and attempt %s : %s"),
+    PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT_WITH_NON_POSITIVE_INV(7011, "Got payment attempt with negative or null invoice for account %s"),
+    PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT_BAD(7012, "Failed to create payment for attempts %s "),
+    PAYMENT_CREATE_PAYMENT_PROVIDER_ACCOUNT(7013, "Failed to create payment provider account for account %s : %s"),
     PAYMENT_UPD_PAYMENT_PROVIDER_ACCOUNT(7014, "Failed to update payment provider account for account %s : %s"),
-    PAYMENT_GET_PAYMENT_PROVIDER_ACCOUNT(7015, "Failed to retrieve payment provider account for account %s : %s"),                        
-    PAYMENT_CREATE_REFUND(7016, "Failed to create refund for account %s : %s"),                
-    PAYMENT_NULL_INVOICE(7017, "Invoice %s has a balance <= 0 "),      
-    PAYMENT_AMOUNT_DENIED(7018, "Payment amount requested for invoice %s is greater than invoice balance [%f/%f]"),         
+    PAYMENT_GET_PAYMENT_PROVIDER_ACCOUNT(7015, "Failed to retrieve payment provider account for account %s : %s"),
+    PAYMENT_CREATE_REFUND(7016, "Failed to create refund for account %s : %s"),
+    PAYMENT_NULL_INVOICE(7017, "Invoice %s has a balance <= 0 "),
+    PAYMENT_AMOUNT_DENIED(7018, "Payment amount requested for invoice %s is greater than invoice balance [%f/%f]"),
     PAYMENT_INTERNAL_ERROR(7019, "Internal payment error : %s"),
     PAYMENT_NO_SUCH_PAYMENT(7020, "Payment %s does not exist"),
     PAYMENT_NO_DEFAULT_PAYMENT_METHOD(7021, "Account %s does not have a default payment method set"),
-    PAYMENT_DEL_DEFAULT_PAYMENT_METHOD(7022, "Cannot delete default payment method for account %s"),            
+    PAYMENT_DEL_DEFAULT_PAYMENT_METHOD(7022, "Cannot delete default payment method for account %s"),
+
+    PAYMENT_PLUGIN_TIMEOUT(7100, "Plugin timeout for account %s and invoice %s"),
+    PAYMENT_PLUGIN_ACCOUNT_INIT(7101, "Account initialization for account %s and plugin % s failed: %s"),
 
-    PAYMENT_PLUGIN_TIMEOUT(7100, "Plugin timeout for account %s and invoice %s"),    
-    PAYMENT_PLUGIN_ACCOUNT_INIT(7101, "Account initialization for account %s and plugin % s failed: %s"),        
 
-    
     /*
     *
     * Range 9000: Miscellaneous
@@ -253,11 +255,11 @@ public enum ErrorCode {
     MISSING_TRANSLATION_RESOURCE(9010, "The resources for %s translation could not be found."),
     MISSING_DEFAULT_TRANSLATION_RESOURCE(9011, "The default resource for %s translation could not be found.");
 
-    
-    private int code;
-    private String format;
 
-    ErrorCode(int code, String format) {
+    private final int code;
+    private final String format;
+
+    ErrorCode(final int code, final String format) {
         this.code = code;
         this.format = format;
     }
diff --git a/api/src/main/java/com/ning/billing/glue/JunctionModule.java b/api/src/main/java/com/ning/billing/glue/JunctionModule.java
index 413e99c..16ea788 100644
--- a/api/src/main/java/com/ning/billing/glue/JunctionModule.java
+++ b/api/src/main/java/com/ning/billing/glue/JunctionModule.java
@@ -20,10 +20,10 @@ package com.ning.billing.glue;
 public interface JunctionModule {
 
     public void installBillingApi();
-   
-    public void installAccountUserApi() ;
-    
-    public void installBlockingApi() ;
+
+    public void installAccountUserApi();
+
+    public void installBlockingApi();
 
     public void installEntitlementUserApi();
 
diff --git a/api/src/main/java/com/ning/billing/invoice/api/formatters/InvoiceFormatterFactory.java b/api/src/main/java/com/ning/billing/invoice/api/formatters/InvoiceFormatterFactory.java
index af4af92..eb1d8b8 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/formatters/InvoiceFormatterFactory.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/formatters/InvoiceFormatterFactory.java
@@ -16,11 +16,11 @@
 
 package com.ning.billing.invoice.api.formatters;
 
+import java.util.Locale;
+
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.util.template.translation.TranslatorConfig;
 
-import java.util.Locale;
-
 public interface InvoiceFormatterFactory {
     public InvoiceFormatter createInvoiceFormatter(TranslatorConfig config, Invoice invoice, Locale locale);
 }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/formatters/InvoiceItemFormatter.java b/api/src/main/java/com/ning/billing/invoice/api/formatters/InvoiceItemFormatter.java
index c14e621..7175fde 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/formatters/InvoiceItemFormatter.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/formatters/InvoiceItemFormatter.java
@@ -20,5 +20,6 @@ import com.ning.billing.invoice.api.InvoiceItem;
 
 public interface InvoiceItemFormatter extends InvoiceItem {
     public String getFormattedStartDate();
+
     public String getFormattedEndDate();
 }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/Invoice.java b/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
index bf7fd7b..8fbf0cf 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
@@ -16,14 +16,15 @@
 
 package com.ning.billing.invoice.api;
 
-import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.entity.Entity;
-import org.joda.time.DateTime;
-
 import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.entity.Entity;
+
 public interface Invoice extends Entity {
     boolean addInvoiceItem(InvoiceItem item);
 
@@ -65,5 +66,5 @@ public interface Invoice extends Entity {
 
     boolean isDueForPayment(DateTime targetDate, int numberOfDays);
 
-	boolean isMigrationInvoice();
+    boolean isMigrationInvoice();
 }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceApiException.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceApiException.java
index a9275e8..087c16e 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceApiException.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceApiException.java
@@ -20,15 +20,15 @@ import com.ning.billing.BillingExceptionBase;
 import com.ning.billing.ErrorCode;
 
 public class InvoiceApiException extends BillingExceptionBase {
-    public InvoiceApiException(Throwable cause, int code, final String msg) {
+    public InvoiceApiException(final Throwable cause, final int code, final String msg) {
         super(cause, code, msg);
     }
 
-    public InvoiceApiException(Throwable cause, ErrorCode code, final Object... args) {
+    public InvoiceApiException(final Throwable cause, final ErrorCode code, final Object... args) {
         super(cause, code, args);
     }
 
-    public InvoiceApiException(ErrorCode code, final Object... args) {
+    public InvoiceApiException(final ErrorCode code, final Object... args) {
         super(code, args);
     }
 }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceCreationEvent.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceCreationEvent.java
index 2561c8b..0385827 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceCreationEvent.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceCreationEvent.java
@@ -26,9 +26,13 @@ import com.ning.billing.util.bus.BusEvent;
 
 public interface InvoiceCreationEvent extends BusEvent {
     public UUID getInvoiceId();
+
     public UUID getAccountId();
+
     public BigDecimal getAmountOwed();
+
     public Currency getCurrency();
+
     public DateTime getInvoiceCreationDate();
 
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
index 9f898c7..ca7f7af 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceItem.java
@@ -16,13 +16,14 @@
 
 package com.ning.billing.invoice.api;
 
-import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.entity.Entity;
-import org.joda.time.DateTime;
-
 import java.math.BigDecimal;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.entity.Entity;
+
 public interface InvoiceItem extends Entity, Comparable<InvoiceItem> {
     UUID getInvoiceId();
 
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceMigrationApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceMigrationApi.java
index 8e17007..c1d4490 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceMigrationApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceMigrationApi.java
@@ -26,15 +26,14 @@ import com.ning.billing.catalog.api.Currency;
 public interface InvoiceMigrationApi {
 
 
-	/**
-	 * @param accountId
-	 * @param targetDate
-	 * @param balance
-	 * @param currency
-	 * 
-	 * @return The UUID of the created invoice
-	 */
-	public UUID createMigrationInvoice(UUID accountId, DateTime targetDate,
-			BigDecimal balance, Currency currency);
+    /**
+     * @param accountId
+     * @param targetDate
+     * @param balance
+     * @param currency
+     * @return The UUID of the created invoice
+     */
+    public UUID createMigrationInvoice(UUID accountId, DateTime targetDate,
+                                       BigDecimal balance, Currency currency);
 
 }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceNotifier.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceNotifier.java
index cd0b7b6..d335a71 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceNotifier.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceNotifier.java
@@ -16,11 +16,8 @@
 
 package com.ning.billing.invoice.api;
 
-import com.ning.billing.BillingExceptionBase;
 import com.ning.billing.account.api.Account;
 
-import java.io.IOException;
-
 public interface InvoiceNotifier {
     public void notify(Account account, Invoice invoice) throws InvoiceApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoicePayment.java b/api/src/main/java/com/ning/billing/invoice/api/InvoicePayment.java
index 4ba42c1..4a04248 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoicePayment.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoicePayment.java
@@ -18,7 +18,9 @@ package com.ning.billing.invoice.api;
 
 import java.math.BigDecimal;
 import java.util.UUID;
+
 import org.joda.time.DateTime;
+
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.entity.Entity;
 
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
index ecc477b..9c6eb69 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
@@ -20,10 +20,10 @@ import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.callcontext.CallContext;
 import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.callcontext.CallContext;
 
 public interface InvoicePaymentApi {
     /**
@@ -41,12 +41,12 @@ public interface InvoicePaymentApi {
     public void notifyOfPaymentAttempt(InvoicePayment invoicePayment, CallContext context);
 
     public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context);
-    
+
     public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate, CallContext context);
 
-    public void processChargeback(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException;
+    public InvoicePayment processChargeback(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException;
 
-    public void processChargeback(UUID invoicePaymentId, CallContext context) throws InvoiceApiException;
+    public InvoicePayment processChargeback(UUID invoicePaymentId, CallContext context) throws InvoiceApiException;
 
     public BigDecimal getRemainingAmountPaid(UUID invoicePaymentId);
 
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
index 1b8afb3..d95f56d 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
@@ -16,16 +16,19 @@
 
 package com.ning.billing.invoice.api;
 
-import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.api.TagApiException;
-import com.ning.billing.util.callcontext.CallContext;
-import org.joda.time.DateTime;
-
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.List;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.api.TagApiException;
+import com.ning.billing.util.callcontext.CallContext;
+
 public interface InvoiceUserApi {
     public List<Invoice> getInvoicesByAccount(UUID accountId);
 
@@ -38,7 +41,7 @@ public interface InvoiceUserApi {
     public void notifyOfPaymentAttempt(InvoicePayment invoicePayment, CallContext context);
 
     public Collection<Invoice> getUnpaidInvoicesByAccountId(UUID accountId, DateTime upToDate);
-    
+
     public Invoice triggerInvoiceGeneration(UUID accountId, DateTime targetDate, boolean dryRun, CallContext context) throws InvoiceApiException;
 
     public void tagInvoiceAsWrittenOff(UUID invoiceId, CallContext context) throws TagApiException;
@@ -47,6 +50,8 @@ public interface InvoiceUserApi {
 
     public InvoiceItem getCreditById(UUID creditId) throws InvoiceApiException;
 
-    public InvoiceItem insertCredit( UUID accountId,  BigDecimal amount,  DateTime effectiveDate,
-                              Currency currency,  CallContext context) throws InvoiceApiException;
+    public InvoiceItem insertCredit(UUID accountId, BigDecimal amount, DateTime effectiveDate,
+                                    Currency currency, CallContext context) throws InvoiceApiException;
+
+    public String getInvoiceAsHTML(UUID invoiceId) throws AccountApiException, IOException, InvoiceApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/junction/api/BillingApi.java b/api/src/main/java/com/ning/billing/junction/api/BillingApi.java
index bb38e8d..6a2c665 100644
--- a/api/src/main/java/com/ning/billing/junction/api/BillingApi.java
+++ b/api/src/main/java/com/ning/billing/junction/api/BillingApi.java
@@ -22,10 +22,8 @@ import com.ning.billing.entitlement.api.billing.ChargeThruApi;
 
 public interface BillingApi extends ChargeThruApi {
     /**
-     *
-     * @param accountId 
+     * @param accountId
      * @return an ordered list of billing event for the given accounts
-     *
      */
     public BillingEventSet getBillingEventsForAccountAndUpdateAccountBCD(UUID accountId);
 }
diff --git a/api/src/main/java/com/ning/billing/junction/api/BillingEventSet.java b/api/src/main/java/com/ning/billing/junction/api/BillingEventSet.java
index aed5c6a..66f604d 100644
--- a/api/src/main/java/com/ning/billing/junction/api/BillingEventSet.java
+++ b/api/src/main/java/com/ning/billing/junction/api/BillingEventSet.java
@@ -27,7 +27,7 @@ public interface BillingEventSet extends SortedSet<BillingEvent> {
     public abstract boolean isAccountAutoInvoiceOff();
 
     public abstract List<UUID> getSubscriptionIdsWithAutoInvoiceOff();
-    
+
     public boolean isLast(BillingEvent event);
 
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/junction/api/Blockable.java b/api/src/main/java/com/ning/billing/junction/api/Blockable.java
index 39900cc..73be651 100644
--- a/api/src/main/java/com/ning/billing/junction/api/Blockable.java
+++ b/api/src/main/java/com/ning/billing/junction/api/Blockable.java
@@ -29,19 +29,19 @@ public interface Blockable {
         ACCOUNT,
         SUBSCRIPTION_BUNDLE,
         SUBSCRIPTION;
-        
-        public static Type get(Blockable o) throws BlockingApiException{
-            if (o instanceof Account){
+
+        public static Type get(final Blockable o) throws BlockingApiException {
+            if (o instanceof Account) {
                 return ACCOUNT;
-            } else if (o instanceof SubscriptionBundle){
+            } else if (o instanceof SubscriptionBundle) {
                 return SUBSCRIPTION_BUNDLE;
-            } else if (o instanceof Subscription){
+            } else if (o instanceof Subscription) {
                 return SUBSCRIPTION;
             }
-            throw new BlockingApiException(ErrorCode.BLOCK_TYPE_NOT_SUPPORTED , o.getClass().getName());
+            throw new BlockingApiException(ErrorCode.BLOCK_TYPE_NOT_SUPPORTED, o.getClass().getName());
         }
-        
-        public static Type get(String type) throws BlockingApiException {
+
+        public static Type get(final String type) throws BlockingApiException {
             if (type.equalsIgnoreCase(ACCOUNT.name())) {
                 return ACCOUNT;
             } else if (type.equalsIgnoreCase(SUBSCRIPTION_BUNDLE.name())) {
@@ -49,12 +49,12 @@ public interface Blockable {
             } else if (type.equalsIgnoreCase(SUBSCRIPTION.name())) {
                 return SUBSCRIPTION;
             }
-            throw new BlockingApiException(ErrorCode.BLOCK_TYPE_NOT_SUPPORTED , type);
+            throw new BlockingApiException(ErrorCode.BLOCK_TYPE_NOT_SUPPORTED, type);
         }
 
     }
 
     public UUID getId();
-    
+
     public BlockingState getBlockingState();
 }
diff --git a/api/src/main/java/com/ning/billing/junction/api/BlockingApi.java b/api/src/main/java/com/ning/billing/junction/api/BlockingApi.java
index d7fc678..d6a1de6 100644
--- a/api/src/main/java/com/ning/billing/junction/api/BlockingApi.java
+++ b/api/src/main/java/com/ning/billing/junction/api/BlockingApi.java
@@ -26,11 +26,11 @@ public interface BlockingApi {
     public BlockingState getBlockingStateFor(Blockable overdueable);
 
     public BlockingState getBlockingStateFor(UUID overdueableId);
-    
+
     public SortedSet<BlockingState> getBlockingHistory(Blockable overdueable);
 
     public SortedSet<BlockingState> getBlockingHistory(UUID overdueableId);
-    
-    public <T extends Blockable> void  setBlockingState(BlockingState state);
-    
+
+    public <T extends Blockable> void setBlockingState(BlockingState state);
+
 }
diff --git a/api/src/main/java/com/ning/billing/junction/api/BlockingApiException.java b/api/src/main/java/com/ning/billing/junction/api/BlockingApiException.java
index 3a7a6c5..0a53790 100644
--- a/api/src/main/java/com/ning/billing/junction/api/BlockingApiException.java
+++ b/api/src/main/java/com/ning/billing/junction/api/BlockingApiException.java
@@ -20,14 +20,14 @@ import com.ning.billing.BillingExceptionBase;
 import com.ning.billing.ErrorCode;
 
 public class BlockingApiException extends BillingExceptionBase {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public BlockingApiException(Throwable cause, ErrorCode code, Object... args) {
-		super(cause, code, args);
-	}
+    public BlockingApiException(final Throwable cause, final ErrorCode code, final Object... args) {
+        super(cause, code, args);
+    }
 
-	public BlockingApiException(ErrorCode code, Object... args) {
-		super(code, args);
-	}
+    public BlockingApiException(final ErrorCode code, final Object... args) {
+        super(code, args);
+    }
 
 }
diff --git a/api/src/main/java/com/ning/billing/junction/api/BlockingState.java b/api/src/main/java/com/ning/billing/junction/api/BlockingState.java
index 08202a2..577ba15 100644
--- a/api/src/main/java/com/ning/billing/junction/api/BlockingState.java
+++ b/api/src/main/java/com/ning/billing/junction/api/BlockingState.java
@@ -21,7 +21,7 @@ import org.joda.time.DateTime;
 public interface BlockingState extends Comparable<BlockingState> {
 
     public abstract String getStateName();
-    
+
     public abstract Blockable.Type getType();
 
     public abstract DateTime getTimestamp();
@@ -39,4 +39,4 @@ public interface BlockingState extends Comparable<BlockingState> {
     public abstract String getDescription();
 
     public abstract String toString();
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/junction/api/DefaultBlockingState.java b/api/src/main/java/com/ning/billing/junction/api/DefaultBlockingState.java
index 332cb85..5a179c6 100644
--- a/api/src/main/java/com/ning/billing/junction/api/DefaultBlockingState.java
+++ b/api/src/main/java/com/ning/billing/junction/api/DefaultBlockingState.java
@@ -21,10 +21,10 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 
 
-public class DefaultBlockingState implements BlockingState{
+public class DefaultBlockingState implements BlockingState {
+
+    private static BlockingState clearState = null;
 
-    private static BlockingState clearState= null;
-    
     private final UUID blockingId;
     private final Blockable.Type type;
     private final String stateName;
@@ -33,41 +33,41 @@ public class DefaultBlockingState implements BlockingState{
     private final boolean blockEntitlement;
     private final boolean blockBilling;
     private final DateTime timestamp;
-    
+
     public static BlockingState getClearState() {
-        if(clearState == null) {
+        if (clearState == null) {
             clearState = new DefaultBlockingState(null, BlockingApi.CLEAR_STATE_NAME, null, null, false, false, false);
         }
         return clearState;
-    }    
-    
-    public DefaultBlockingState(UUID blockingId, 
-            String stateName, 
-            Blockable.Type type, 
-            String service,
-            boolean blockChange,
-            boolean blockEntitlement,
-            boolean blockBilling
-            ) {
-        this(   blockingId, 
-                 stateName, 
-                 type, 
-                 service,
-                 blockChange,
-                 blockEntitlement,
-                 blockBilling,
-                 null);
-    }    
-    
-    public DefaultBlockingState(UUID blockingId, 
-            String stateName, 
-            Blockable.Type type, 
-            String service,
-            boolean blockChange,
-            boolean blockEntitlement,
-            boolean blockBilling,
-            DateTime timestamp
-            ) {
+    }
+
+    public DefaultBlockingState(final UUID blockingId,
+                                final String stateName,
+                                final Blockable.Type type,
+                                final String service,
+                                final boolean blockChange,
+                                final boolean blockEntitlement,
+                                final boolean blockBilling
+                               ) {
+        this(blockingId,
+             stateName,
+             type,
+             service,
+             blockChange,
+             blockEntitlement,
+             blockBilling,
+             null);
+    }
+
+    public DefaultBlockingState(final UUID blockingId,
+                                final String stateName,
+                                final Blockable.Type type,
+                                final String service,
+                                final boolean blockChange,
+                                final boolean blockEntitlement,
+                                final boolean blockBilling,
+                                final DateTime timestamp
+                               ) {
         super();
         this.blockingId = blockingId;
         this.stateName = stateName;
@@ -78,13 +78,14 @@ public class DefaultBlockingState implements BlockingState{
         this.type = type;
         this.timestamp = timestamp;
     }
-    
+
     public UUID getBlockedId() {
         return blockingId;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.junction.api.blocking.BlockingState#getStateName()
-     */
+    * @see com.ning.billing.junction.api.blocking.BlockingState#getStateName()
+    */
     @Override
     public String getStateName() {
         return stateName;
@@ -94,9 +95,10 @@ public class DefaultBlockingState implements BlockingState{
     public Blockable.Type getType() {
         return type;
     }
+
     /* (non-Javadoc)
-     * @see com.ning.billing.junction.api.blocking.BlockingState#getTimestamp()
-     */
+    * @see com.ning.billing.junction.api.blocking.BlockingState#getTimestamp()
+    */
     @Override
     public DateTime getTimestamp() {
         return timestamp;
@@ -133,7 +135,7 @@ public class DefaultBlockingState implements BlockingState{
     /* (non-Javadoc)
      * @see com.ning.billing.junction.api.blocking.BlockingState#compareTo(com.ning.billing.junction.api.blocking.DefaultBlockingState)
      */
-    public int compareTo(BlockingState arg0) {
+    public int compareTo(final BlockingState arg0) {
         if (timestamp.compareTo(arg0.getTimestamp()) != 0) {
             return timestamp.compareTo(arg0.getTimestamp());
         } else {
@@ -157,59 +159,74 @@ public class DefaultBlockingState implements BlockingState{
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        DefaultBlockingState other = (DefaultBlockingState) obj;
-        if (blockBilling != other.blockBilling)
+        }
+        final DefaultBlockingState other = (DefaultBlockingState) obj;
+        if (blockBilling != other.blockBilling) {
             return false;
-        if (blockChange != other.blockChange)
+        }
+        if (blockChange != other.blockChange) {
             return false;
-        if (blockEntitlement != other.blockEntitlement)
+        }
+        if (blockEntitlement != other.blockEntitlement) {
             return false;
+        }
         if (blockingId == null) {
-            if (other.blockingId != null)
+            if (other.blockingId != null) {
                 return false;
-        } else if (!blockingId.equals(other.blockingId))
+            }
+        } else if (!blockingId.equals(other.blockingId)) {
             return false;
+        }
         if (service == null) {
-            if (other.service != null)
+            if (other.service != null) {
                 return false;
-        } else if (!service.equals(other.service))
+            }
+        } else if (!service.equals(other.service)) {
             return false;
+        }
         if (stateName == null) {
-            if (other.stateName != null)
+            if (other.stateName != null) {
                 return false;
-        } else if (!stateName.equals(other.stateName))
+            }
+        } else if (!stateName.equals(other.stateName)) {
             return false;
+        }
         if (timestamp == null) {
-            if (other.timestamp != null)
+            if (other.timestamp != null) {
                 return false;
-        } else if (!timestamp.equals(other.timestamp))
+            }
+        } else if (!timestamp.equals(other.timestamp)) {
             return false;
-        if (type != other.type)
+        }
+        if (type != other.type) {
             return false;
+        }
         return true;
     }
-    
+
     /* (non-Javadoc)
-     * @see com.ning.billing.junction.api.blocking.BlockingState#getDescription()
-     */
+    * @see com.ning.billing.junction.api.blocking.BlockingState#getDescription()
+    */
     @Override
     public String getDescription() {
-        String entitlement = onOff(isBlockEntitlement());
-        String billing = onOff(isBlockBilling());
-        String change = onOff(isBlockChange());
-               
+        final String entitlement = onOff(isBlockEntitlement());
+        final String billing = onOff(isBlockBilling());
+        final String change = onOff(isBlockChange());
+
         return String.format("(Change: %s, Entitlement: %s, Billing: %s)", change, entitlement, billing);
     }
-    
-    private String onOff(boolean val) {
-        if(val) {
+
+    private String onOff(final boolean val) {
+        if (val) {
             return "Off";
         } else {
             return "On";
@@ -224,5 +241,4 @@ public class DefaultBlockingState implements BlockingState{
     }
 
 
-    
 }
diff --git a/api/src/main/java/com/ning/billing/lifecycle/KillbillService.java b/api/src/main/java/com/ning/billing/lifecycle/KillbillService.java
index 84e1ab6..df00532 100644
--- a/api/src/main/java/com/ning/billing/lifecycle/KillbillService.java
+++ b/api/src/main/java/com/ning/billing/lifecycle/KillbillService.java
@@ -18,7 +18,7 @@ package com.ning.billing.lifecycle;
 
 public interface KillbillService {
 
-    public static class ServiceException extends Exception  {
+    public static class ServiceException extends Exception {
 
         private static final long serialVersionUID = 176191207L;
 
@@ -26,21 +26,20 @@ public interface KillbillService {
             super();
         }
 
-        public ServiceException(String msg, Throwable e) {
+        public ServiceException(final String msg, final Throwable e) {
             super(msg, e);
         }
 
-        public ServiceException(String msg) {
+        public ServiceException(final String msg) {
             super(msg);
         }
 
-        public ServiceException(Throwable msg) {
+        public ServiceException(final Throwable msg) {
             super(msg);
         }
     }
 
     /**
-     *
      * @return the name of the service
      */
     public String getName();
diff --git a/api/src/main/java/com/ning/billing/lifecycle/LifecycleHandlerType.java b/api/src/main/java/com/ning/billing/lifecycle/LifecycleHandlerType.java
index 759cc13..bb86365 100644
--- a/api/src/main/java/com/ning/billing/lifecycle/LifecycleHandlerType.java
+++ b/api/src/main/java/com/ning/billing/lifecycle/LifecycleHandlerType.java
@@ -16,14 +16,14 @@
 
 package com.ning.billing.lifecycle;
 
-import com.google.common.collect.Lists;
-
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 import java.util.List;
 
+import com.google.common.collect.Lists;
+
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 public @interface LifecycleHandlerType {
@@ -81,11 +81,11 @@ public @interface LifecycleHandlerType {
             STARTUP_POST_EVENT_REGISTRATION,
             SHUTDOWN_PRE_EVENT_UNREGISTRATION,
             SHUTDOWN_POST_EVENT_UNREGISTRATION
-        };
+        }
 
-        private Sequence seq;
+        private final Sequence seq;
 
-        LifecycleLevel(Sequence seq) {
+        LifecycleLevel(final Sequence seq) {
             this.seq = seq;
         }
 
@@ -96,9 +96,9 @@ public @interface LifecycleHandlerType {
         //
         // Returns an ordered list of level for a particular sequence
         //
-        public static List<LifecycleLevel> getLevelsForSequence(Sequence seq) {
-            List<LifecycleLevel> result = Lists.newLinkedList();
-            for (LifecycleLevel level : LifecycleLevel.values()) {
+        public static List<LifecycleLevel> getLevelsForSequence(final Sequence seq) {
+            final List<LifecycleLevel> result = Lists.newLinkedList();
+            for (final LifecycleLevel level : LifecycleLevel.values()) {
                 if (level.getSequence() == seq) {
                     result.add(level);
                 }
diff --git a/api/src/main/java/com/ning/billing/overdue/Condition.java b/api/src/main/java/com/ning/billing/overdue/Condition.java
index 8607e91..7ecc40b 100644
--- a/api/src/main/java/com/ning/billing/overdue/Condition.java
+++ b/api/src/main/java/com/ning/billing/overdue/Condition.java
@@ -22,9 +22,8 @@ import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.overdue.config.api.BillingState;
 
 
-
 public interface Condition<T extends Blockable> {
 
     public boolean evaluate(BillingState<T> state, DateTime now);
 
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java b/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java
index dc4aaae..bec3db5 100644
--- a/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java
+++ b/api/src/main/java/com/ning/billing/overdue/config/api/BillingState.java
@@ -25,57 +25,57 @@ import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.util.tag.Tag;
 
 public class BillingState<T extends Blockable> {
-	private final UUID objectId;
-	private final int numberOfUnpaidInvoices;
-	private final BigDecimal balanceOfUnpaidInvoices;
+    private final UUID objectId;
+    private final int numberOfUnpaidInvoices;
+    private final BigDecimal balanceOfUnpaidInvoices;
     private final DateTime dateOfEarliestUnpaidInvoice;
     private final UUID idOfEarliestUnpaidInvoice;
-	private final PaymentResponse responseForLastFailedPayment;
-	private final Tag[] tags;
-	
-	public BillingState(UUID id, 
-	        int numberOfUnpaidInvoices, 
-	        BigDecimal balanceOfUnpaidInvoices,
-			DateTime dateOfEarliestUnpaidInvoice,
-			UUID idOfEarliestUnpaidInvoice,
-			PaymentResponse responseForLastFailedPayment,
-			Tag[] tags) {
-		super();
-		this.objectId = id;
-		this.numberOfUnpaidInvoices = numberOfUnpaidInvoices;
-		this.balanceOfUnpaidInvoices = balanceOfUnpaidInvoices;
+    private final PaymentResponse responseForLastFailedPayment;
+    private final Tag[] tags;
+
+    public BillingState(final UUID id,
+                        final int numberOfUnpaidInvoices,
+                        final BigDecimal balanceOfUnpaidInvoices,
+                        final DateTime dateOfEarliestUnpaidInvoice,
+                        final UUID idOfEarliestUnpaidInvoice,
+                        final PaymentResponse responseForLastFailedPayment,
+                        final Tag[] tags) {
+        super();
+        this.objectId = id;
+        this.numberOfUnpaidInvoices = numberOfUnpaidInvoices;
+        this.balanceOfUnpaidInvoices = balanceOfUnpaidInvoices;
         this.dateOfEarliestUnpaidInvoice = dateOfEarliestUnpaidInvoice;
         this.idOfEarliestUnpaidInvoice = idOfEarliestUnpaidInvoice;
-		this.responseForLastFailedPayment = responseForLastFailedPayment;
-		this.tags = tags;
-	}
+        this.responseForLastFailedPayment = responseForLastFailedPayment;
+        this.tags = tags;
+    }
+
+    public UUID getObjectId() {
+        return objectId;
+    }
+
+    public int getNumberOfUnpaidInvoices() {
+        return numberOfUnpaidInvoices;
+    }
 
-	public UUID getObjectId() {
-		return objectId;
-	}
-	
-	public int getNumberOfUnpaidInvoices() {
-		return numberOfUnpaidInvoices;
-	}
+    public BigDecimal getBalanceOfUnpaidInvoices() {
+        return balanceOfUnpaidInvoices;
+    }
 
-	public BigDecimal getBalanceOfUnpaidInvoices() {
-		return balanceOfUnpaidInvoices;
-	}
+    public DateTime getDateOfEarliestUnpaidInvoice() {
+        return dateOfEarliestUnpaidInvoice;
+    }
 
-	public DateTime getDateOfEarliestUnpaidInvoice() {
-		return dateOfEarliestUnpaidInvoice;
-	}
-	
-	public UUID getIdOfEarliestUnpaidInvoice() {
+    public UUID getIdOfEarliestUnpaidInvoice() {
         return idOfEarliestUnpaidInvoice;
     }
 
     public PaymentResponse getResponseForLastFailedPayment() {
-		return responseForLastFailedPayment;
-	}
+        return responseForLastFailedPayment;
+    }
 
-	public Tag[] getTags() {
-		return tags;
-	}
+    public Tag[] getTags() {
+        return tags;
+    }
 
 }
diff --git a/api/src/main/java/com/ning/billing/overdue/config/api/BillingStateBundle.java b/api/src/main/java/com/ning/billing/overdue/config/api/BillingStateBundle.java
index 14aa4cd..600b1c2 100644
--- a/api/src/main/java/com/ning/billing/overdue/config/api/BillingStateBundle.java
+++ b/api/src/main/java/com/ning/billing/overdue/config/api/BillingStateBundle.java
@@ -33,38 +33,38 @@ public class BillingStateBundle extends BillingState<SubscriptionBundle> {
     private final BillingPeriod basePlanBillingPeriod;
     private final PriceList basePlanPriceList;
     private final PhaseType basePlanPhaseType;
-    
-	public BillingStateBundle(UUID id, 
-	        int numberOfUnpaidInvoices, 
-	        BigDecimal unpaidInvoiceBalance,
-			DateTime dateOfEarliestUnpaidInvoice,
-			UUID idOfEarliestUnpaidInvoice,
-			PaymentResponse responseForLastFailedPayment,
-			Tag[] tags, 
-			Product basePlanProduct,
-			BillingPeriod basePlanBillingPeriod, 
-			PriceList basePlanPriceList, PhaseType basePlanPhaseType) {
-		super(id, numberOfUnpaidInvoices, unpaidInvoiceBalance, 
-				dateOfEarliestUnpaidInvoice, idOfEarliestUnpaidInvoice, 
-				responseForLastFailedPayment, tags);
-		
-		this.basePlanProduct = basePlanProduct;
-		this.basePlanBillingPeriod = basePlanBillingPeriod;
-		this.basePlanPriceList = basePlanPriceList;
-		this.basePlanPhaseType = basePlanPhaseType;
-	}
-	
-	public Product getBasePlanProduct() {
-		return basePlanProduct;
-	}
-	
-	public BillingPeriod getBasePlanBillingPeriod() {
-		return basePlanBillingPeriod;
-	}
-	
-	public PriceList getBasePlanPriceList() {
-		return basePlanPriceList;
-	}
+
+    public BillingStateBundle(final UUID id,
+                              final int numberOfUnpaidInvoices,
+                              final BigDecimal unpaidInvoiceBalance,
+                              final DateTime dateOfEarliestUnpaidInvoice,
+                              final UUID idOfEarliestUnpaidInvoice,
+                              final PaymentResponse responseForLastFailedPayment,
+                              final Tag[] tags,
+                              final Product basePlanProduct,
+                              final BillingPeriod basePlanBillingPeriod,
+                              final PriceList basePlanPriceList, final PhaseType basePlanPhaseType) {
+        super(id, numberOfUnpaidInvoices, unpaidInvoiceBalance,
+              dateOfEarliestUnpaidInvoice, idOfEarliestUnpaidInvoice,
+              responseForLastFailedPayment, tags);
+
+        this.basePlanProduct = basePlanProduct;
+        this.basePlanBillingPeriod = basePlanBillingPeriod;
+        this.basePlanPriceList = basePlanPriceList;
+        this.basePlanPhaseType = basePlanPhaseType;
+    }
+
+    public Product getBasePlanProduct() {
+        return basePlanProduct;
+    }
+
+    public BillingPeriod getBasePlanBillingPeriod() {
+        return basePlanBillingPeriod;
+    }
+
+    public PriceList getBasePlanPriceList() {
+        return basePlanPriceList;
+    }
 
     public PhaseType getBasePlanPhaseType() {
         return basePlanPhaseType;
diff --git a/api/src/main/java/com/ning/billing/overdue/config/api/OverdueError.java b/api/src/main/java/com/ning/billing/overdue/config/api/OverdueError.java
index 78f62c6..b347632 100644
--- a/api/src/main/java/com/ning/billing/overdue/config/api/OverdueError.java
+++ b/api/src/main/java/com/ning/billing/overdue/config/api/OverdueError.java
@@ -21,21 +21,21 @@ import com.ning.billing.ErrorCode;
 
 public class OverdueError extends BillingExceptionBase {
 
-    public OverdueError(BillingExceptionBase cause) {
+    public OverdueError(final BillingExceptionBase cause) {
         super(cause);
-     }
+    }
 
-    public OverdueError(Throwable cause, int code, String msg) {
+    public OverdueError(final Throwable cause, final int code, final String msg) {
         super(cause, code, msg);
     }
 
     private static final long serialVersionUID = 1L;
 
-    public OverdueError(Throwable cause, ErrorCode code, Object... args) {
+    public OverdueError(final Throwable cause, final ErrorCode code, final Object... args) {
         super(cause, code, args);
     }
 
-    public OverdueError(ErrorCode code, Object... args) {
+    public OverdueError(final ErrorCode code, final Object... args) {
         super(code, args);
     }
 
diff --git a/api/src/main/java/com/ning/billing/overdue/config/api/PaymentResponse.java b/api/src/main/java/com/ning/billing/overdue/config/api/PaymentResponse.java
index fb82d7c..df1fa69 100644
--- a/api/src/main/java/com/ning/billing/overdue/config/api/PaymentResponse.java
+++ b/api/src/main/java/com/ning/billing/overdue/config/api/PaymentResponse.java
@@ -19,32 +19,32 @@ package com.ning.billing.overdue.config.api;
 public enum PaymentResponse {
     // Card issues
     INVALID_CARD("The card number, expiry date or cvc is invalid or incorrect"),
-	EXPIRED_CARD("The card has expired"),
-	LOST_OR_STOLEN_CARD("The card has been lost or stolen"),
+    EXPIRED_CARD("The card has expired"),
+    LOST_OR_STOLEN_CARD("The card has been lost or stolen"),
 
-	// Account issues
+    // Account issues
     DO_NOT_HONOR("Do not honor the card - usually a problem with account"),
-	INSUFFICIENT_FUNDS("The account had insufficient funds to fulfil the payment"),
-	DECLINE("Generic payment decline"),
-	
-	//Transaction
-	PROCESSING_ERROR("Error processing card"),
-	INVALID_AMOUNT("An invalid amount was entered"),
-	DUPLICATE_TRANSACTION("A transaction with identical amount and credit card information was submitted very recently."),
+    INSUFFICIENT_FUNDS("The account had insufficient funds to fulfil the payment"),
+    DECLINE("Generic payment decline"),
+
+    //Transaction
+    PROCESSING_ERROR("Error processing card"),
+    INVALID_AMOUNT("An invalid amount was entered"),
+    DUPLICATE_TRANSACTION("A transaction with identical amount and credit card information was submitted very recently."),
+
+    //Other
+    OTHER("Some other error");
+
+    private final String description;
+
+    private PaymentResponse(final String description) {
+        this.description = description;
+    }
+
+    public String getDescription() {
+        return description;
+    }
 
-	//Other
-	OTHER("Some other error");
-	
-	private String description;
-	
-	private PaymentResponse(String description) {
-	    this.description = description;
-	}
-	
-	public String getDescription() {
-	    return description;
-	}
-	
 //	 690118 | Approved
 //	 136956 | Do Not Honor
 //	 119640 | Insufficient Funds
diff --git a/api/src/main/java/com/ning/billing/overdue/OverdueApiException.java b/api/src/main/java/com/ning/billing/overdue/OverdueApiException.java
index 7629abf..df58f85 100644
--- a/api/src/main/java/com/ning/billing/overdue/OverdueApiException.java
+++ b/api/src/main/java/com/ning/billing/overdue/OverdueApiException.java
@@ -20,14 +20,14 @@ import com.ning.billing.BillingExceptionBase;
 import com.ning.billing.ErrorCode;
 
 public class OverdueApiException extends BillingExceptionBase {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
 
-	public OverdueApiException(Throwable cause, ErrorCode code, Object... args) {
-		super(cause, code, args);
-	}
+    public OverdueApiException(final Throwable cause, final ErrorCode code, final Object... args) {
+        super(cause, code, args);
+    }
 
-	public OverdueApiException(ErrorCode code, Object... args) {
-		super(code, args);
-	}
+    public OverdueApiException(final ErrorCode code, final Object... args) {
+        super(code, args);
+    }
 
 }
diff --git a/api/src/main/java/com/ning/billing/overdue/OverdueService.java b/api/src/main/java/com/ning/billing/overdue/OverdueService.java
index 06c1f15..8745653 100644
--- a/api/src/main/java/com/ning/billing/overdue/OverdueService.java
+++ b/api/src/main/java/com/ning/billing/overdue/OverdueService.java
@@ -24,5 +24,5 @@ public interface OverdueService extends KillbillService {
     public String getName();
 
     public OverdueUserApi getUserApi();
-    
+
 }
diff --git a/api/src/main/java/com/ning/billing/overdue/OverdueState.java b/api/src/main/java/com/ning/billing/overdue/OverdueState.java
index 231a434..39cf93d 100644
--- a/api/src/main/java/com/ning/billing/overdue/OverdueState.java
+++ b/api/src/main/java/com/ning/billing/overdue/OverdueState.java
@@ -21,22 +21,21 @@ import org.joda.time.Period;
 import com.ning.billing.junction.api.Blockable;
 
 
-
 public interface OverdueState<T extends Blockable> {
 
     public String getName();
 
     public String getExternalMessage();
-    
+
     public int getDaysBetweenPaymentRetries();
 
     public boolean disableEntitlementAndChangesBlocked();
 
     public boolean blockChanges();
-    
+
     public boolean isClearState();
 
     public Period getReevaluationInterval() throws OverdueApiException;
 
     public Condition<T> getCondition();
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/ning/billing/payment/api/Payment.java b/api/src/main/java/com/ning/billing/payment/api/Payment.java
index 33a7ab8..9171213 100644
--- a/api/src/main/java/com/ning/billing/payment/api/Payment.java
+++ b/api/src/main/java/com/ning/billing/payment/api/Payment.java
@@ -26,31 +26,31 @@ import com.ning.billing.catalog.api.Currency;
 public interface Payment {
 
     public UUID getId();
-    
+
     public UUID getAccountId();
-    
-    public UUID getInvoiceId();    
-    
+
+    public UUID getInvoiceId();
+
     public UUID getPaymentMethodId();
-    
+
     public Integer getPaymentNumber();
-    
+
     public BigDecimal getAmount();
-    
+
     public DateTime getEffectiveDate();
-    
+
     public Currency getCurrency();
-    
+
     public PaymentStatus getPaymentStatus();
-    
+
     public List<PaymentAttempt> getAttempts();
-    
+
     public interface PaymentAttempt {
-        
+
         public UUID getId();
-        
+
         public DateTime getEffectiveDate();
-        
+
         public String getErrorMsg();
 
         public PaymentStatus getPaymentStatus();
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
index 63fc93a..c8f9b2f 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
@@ -21,60 +21,58 @@ import java.util.Set;
 import java.util.UUID;
 
 import com.ning.billing.account.api.Account;
-
-import com.ning.billing.payment.plugin.api.PaymentProviderAccount;
 import com.ning.billing.util.callcontext.CallContext;
 
 public interface PaymentApi {
-  
+
     public Payment createPayment(final String accountKey, final UUID invoiceId, final BigDecimal amount, final CallContext context)
-    throws PaymentApiException;
+            throws PaymentApiException;
 
     public Payment createPayment(final Account account, final UUID invoiceId, final BigDecimal amount, final CallContext context)
-    throws PaymentApiException;
+            throws PaymentApiException;
 
     public Refund createRefund(final Account account, final UUID paymentId, final CallContext context)
-    throws PaymentApiException;
+            throws PaymentApiException;
 
     public List<Payment> getInvoicePayments(final UUID invoiceId)
-    throws PaymentApiException;
-
-   public List<Payment> getAccountPayments(final UUID accountId)
-    throws PaymentApiException;
-   
-   public Payment getPayment(final UUID paymentId)
-   throws PaymentApiException;
-   
-   /*
+            throws PaymentApiException;
+
+    public List<Payment> getAccountPayments(final UUID accountId)
+            throws PaymentApiException;
+
+    public Payment getPayment(final UUID paymentId)
+            throws PaymentApiException;
+
+    /*
     * Payment method Apis
     */
-   public Set<String> getAvailablePlugins();
-   
-   public String initializeAccountPlugin(final String pluginName, final Account account)
-   throws PaymentApiException;
-   
-   public UUID addPaymentMethod(final String pluginName, final Account account, boolean setDefault, final PaymentMethodPlugin paymentMethodInfo, final CallContext context)
-   throws PaymentApiException;
-   
-   public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final CallContext context)
-    throws PaymentApiException;
-   
-   public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginDetail)
-    throws PaymentApiException;
-
-   public PaymentMethod getPaymentMethodById(final UUID paymentMethodId)
-   throws PaymentApiException;
-
-   public PaymentMethod getPaymentMethod(final Account account, final UUID paymentMethodId, final boolean withPluginDetail)
-   throws PaymentApiException;
-   
-   public void updatePaymentMethod(final Account account, final UUID paymentMethodId, final PaymentMethodPlugin paymentMetghodInfo)
-   throws PaymentApiException;
-   
-   public void deletedPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
-   throws PaymentApiException;
-   
-   public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
-   throws PaymentApiException;
+    public Set<String> getAvailablePlugins();
+
+    public String initializeAccountPlugin(final String pluginName, final Account account)
+            throws PaymentApiException;
+
+    public UUID addPaymentMethod(final String pluginName, final Account account, boolean setDefault, final PaymentMethodPlugin paymentMethodInfo, final CallContext context)
+            throws PaymentApiException;
+
+    public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final CallContext context)
+            throws PaymentApiException;
+
+    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginDetail)
+            throws PaymentApiException;
+
+    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId)
+            throws PaymentApiException;
+
+    public PaymentMethod getPaymentMethod(final Account account, final UUID paymentMethodId, final boolean withPluginDetail)
+            throws PaymentApiException;
+
+    public void updatePaymentMethod(final Account account, final UUID paymentMethodId, final PaymentMethodPlugin paymentMetghodInfo)
+            throws PaymentApiException;
+
+    public void deletedPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
+            throws PaymentApiException;
+
+    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
+            throws PaymentApiException;
 
 }
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentApiException.java b/api/src/main/java/com/ning/billing/payment/api/PaymentApiException.java
index fd3445d..2ef846d 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentApiException.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentApiException.java
@@ -23,19 +23,19 @@ public class PaymentApiException extends BillingExceptionBase {
 
     private static final long serialVersionUID = 39445033L;
 
-    public PaymentApiException(AccountApiException e) {
+    public PaymentApiException(final AccountApiException e) {
         super(e, e.getCode(), e.getMessage());
     }
 
-    public PaymentApiException(Throwable e, ErrorCode code, Object...args) {
+    public PaymentApiException(final Throwable e, final ErrorCode code, final Object... args) {
         super(e, code, args);
     }
 
-    public PaymentApiException(Throwable e, int code, String message) {
+    public PaymentApiException(final Throwable e, final int code, final String message) {
         super(e, code, message);
     }
 
-    public PaymentApiException(ErrorCode code, Object...args) {
+    public PaymentApiException(final ErrorCode code, final Object... args) {
         super(code, args);
     }
 }
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentErrorEvent.java b/api/src/main/java/com/ning/billing/payment/api/PaymentErrorEvent.java
index 3217bdb..3dadf88 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentErrorEvent.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentErrorEvent.java
@@ -26,6 +26,6 @@ public interface PaymentErrorEvent extends BusEvent {
     public UUID getInvoiceId();
 
     public UUID getAccountId();
-    
+
     public UUID getPaymentId();
 }
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentInfoEvent.java b/api/src/main/java/com/ning/billing/payment/api/PaymentInfoEvent.java
index 040034b..8c5a1ef 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentInfoEvent.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentInfoEvent.java
@@ -17,16 +17,18 @@ package com.ning.billing.payment.api;
 
 import java.math.BigDecimal;
 import java.util.UUID;
-import com.ning.billing.util.entity.Entity;
+
 import org.joda.time.DateTime;
+
 import com.ning.billing.util.bus.BusEvent;
+import com.ning.billing.util.entity.Entity;
 
 public interface PaymentInfoEvent extends Entity, BusEvent {
 
     public UUID getPaymentId();
-    
+
     public UUID getAccountId();
-    
+
     public UUID getInvoiceId();
 
     public BigDecimal getAmount();
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentMethod.java b/api/src/main/java/com/ning/billing/payment/api/PaymentMethod.java
index 94299e7..dfe9668 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentMethod.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentMethod.java
@@ -19,14 +19,14 @@ import java.util.UUID;
 
 
 public interface PaymentMethod {
-    
+
     public UUID getId();
-    
+
     public UUID getAccountId();
-    
+
     public Boolean isActive();
-    
+
     public String getPluginName();
-    
+
     public PaymentMethodPlugin getPluginDetail();
 }
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentMethodPlugin.java b/api/src/main/java/com/ning/billing/payment/api/PaymentMethodPlugin.java
index f829232..cacdf3a 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentMethodPlugin.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentMethodPlugin.java
@@ -18,21 +18,21 @@ package com.ning.billing.payment.api;
 import java.util.List;
 
 public interface PaymentMethodPlugin {
-    
+
     public String getExternalPaymentMethodId();
-    
+
     public boolean isDefaultPaymentMethod();
-    
-    public List<PaymentMethodKVInfo> getProperties(); 
-    
+
+    public List<PaymentMethodKVInfo> getProperties();
+
     public String getValueString(String key);
-    
+
     public class PaymentMethodKVInfo {
         private final String key;
         private final Object value;
         private final Boolean isUpdatable;
-        
-        public PaymentMethodKVInfo(String key, Object value, Boolean isUpdatable) {
+
+        public PaymentMethodKVInfo(final String key, final Object value, final Boolean isUpdatable) {
             super();
             this.key = key;
             this.value = value;
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentStatus.java b/api/src/main/java/com/ning/billing/payment/api/PaymentStatus.java
index ad77bdc..151447c 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentStatus.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentStatus.java
@@ -23,16 +23,16 @@ public enum PaymentStatus {
     UNKNOWN,
     /* Status for Payment when AUTO_PAY_OFF is turned on */
     AUTO_PAY_OFF,
-    /* Status for Payment and PaymentAttempt when the plugin failed to make the Payment and we will schedule a FailedPaymentRetry */    
+    /* Status for Payment and PaymentAttempt when the plugin failed to make the Payment and we will schedule a FailedPaymentRetry */
     PAYMENT_FAILURE,
     /* Payment failure , we already retried a maximum of time */
     PAYMENT_FAILURE_ABORTED,
     /* Exception from plugin, state is unknown and needs to be retried */
     PLUGIN_FAILURE,
     /* Exception from plugin, we already retried a maximum of time */
-    PLUGIN_FAILURE_ABORTED,    
-    /* PaymentAttenmpt timedout; When TimedoutPaymentRetry kicks in, it check moves the state to TIMEDOUT if this is still in UNKNWON state */    
+    PLUGIN_FAILURE_ABORTED,
+    /* PaymentAttenmpt timedout; When TimedoutPaymentRetry kicks in, it check moves the state to TIMEDOUT if this is still in UNKNWON state */
     TIMEDOUT,
     /* Status for Payment and PaymentAttempt all TimedoutPaymentRetry failed */
-    TIMEDOUT_ABORTED,    
+    TIMEDOUT_ABORTED,
 }
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/NoOpPaymentPluginApi.java b/api/src/main/java/com/ning/billing/payment/plugin/api/NoOpPaymentPluginApi.java
index 2b3620a..21ef934 100644
--- a/api/src/main/java/com/ning/billing/payment/plugin/api/NoOpPaymentPluginApi.java
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/NoOpPaymentPluginApi.java
@@ -18,9 +18,9 @@ package com.ning.billing.payment.plugin.api;
 public interface NoOpPaymentPluginApi extends PaymentPluginApi {
 
     public void clear();
-    
+
     public void makeNextPaymentFailWithError();
-    
+
     public void makeNextPaymentFailWithException();
 
     public void makeAllInvoicesFailWithError(boolean failure);
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java
index 18e4d5e..3e8b563 100644
--- a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java
@@ -20,13 +20,13 @@ import java.math.BigDecimal;
 import org.joda.time.DateTime;
 
 public interface PaymentInfoPlugin {
-    
+
     public enum PaymentPluginStatus {
         UNDEFINED,
         PROCESSED,
         ERROR
-    };
-    
+    }
+
     public BigDecimal getAmount();
 
     public DateTime getCreatedDate();
@@ -34,8 +34,8 @@ public interface PaymentInfoPlugin {
     public DateTime getEffectiveDate();
 
     public PaymentPluginStatus getStatus();
-    
+
     public String getGatewayError();
-    
+
     public String getGatewayErrorCode();
 }
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApi.java b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApi.java
index aa965a6..10b329e 100644
--- a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApi.java
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApi.java
@@ -24,36 +24,36 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.payment.api.PaymentMethodPlugin;
 
 public interface PaymentPluginApi {
-    
+
     public String getName();
-    
+
     public PaymentInfoPlugin processPayment(String externalAccountKey, UUID paymentId, BigDecimal amount)
-    throws PaymentPluginApiException;
+            throws PaymentPluginApiException;
 
     public PaymentInfoPlugin getPaymentInfo(UUID paymentId)
-    throws PaymentPluginApiException;
+            throws PaymentPluginApiException;
 
     public List<PaymentInfoPlugin> processRefund(Account account)
-    throws PaymentPluginApiException;
-    
+            throws PaymentPluginApiException;
+
     public String createPaymentProviderAccount(Account account)
-    throws PaymentPluginApiException;
+            throws PaymentPluginApiException;
 
-    public List<PaymentMethodPlugin> getPaymentMethodDetails(String accountKey) 
-    throws PaymentPluginApiException;
+    public List<PaymentMethodPlugin> getPaymentMethodDetails(String accountKey)
+            throws PaymentPluginApiException;
 
-    public PaymentMethodPlugin getPaymentMethodDetail(String accountKey, String externalPaymentMethodId) 
-    throws PaymentPluginApiException;
+    public PaymentMethodPlugin getPaymentMethodDetail(String accountKey, String externalPaymentMethodId)
+            throws PaymentPluginApiException;
 
     public String addPaymentMethod(String accountKey, PaymentMethodPlugin paymentMethodProps, boolean setDefault)
-    throws PaymentPluginApiException;
+            throws PaymentPluginApiException;
 
     public void updatePaymentMethod(String accountKey, PaymentMethodPlugin paymentMethodProps)
-    throws PaymentPluginApiException;
+            throws PaymentPluginApiException;
 
     public void deletePaymentMethod(String accountKey, String externalPaymentMethodId)
-    throws PaymentPluginApiException;    
+            throws PaymentPluginApiException;
 
     public void setDefaultPaymentMethod(String accountKey, String externalPaymentId)
-    throws PaymentPluginApiException;    
+            throws PaymentPluginApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApiException.java b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApiException.java
index 5df657e..d201a27 100644
--- a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApiException.java
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApiException.java
@@ -18,10 +18,10 @@ package com.ning.billing.payment.plugin.api;
 public class PaymentPluginApiException extends Exception {
 
     private static final long serialVersionUID = 15642965L;
-    
+
     private final String errorType;
     private final String errorMessage;
-    
+
     public PaymentPluginApiException(final String errorType, final String errorMessage) {
         this.errorMessage = errorMessage;
         this.errorType = errorType;
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderAccount.java b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderAccount.java
index 0244dbf..cfeb7df 100644
--- a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderAccount.java
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderAccount.java
@@ -25,11 +25,11 @@ public class PaymentProviderAccount {
     private final String phoneNumber;
     private final String defaultPaymentMethodId;
 
-    public PaymentProviderAccount(String id,
-                                  String accountKey,
-                                  String accountName,
-                                  String phoneNumber,
-                                  String defaultPaymentMethodId) {
+    public PaymentProviderAccount(final String id,
+                                  final String accountKey,
+                                  final String accountName,
+                                  final String phoneNumber,
+                                  final String defaultPaymentMethodId) {
         this.id = id;
         this.accountKey = accountKey;
         this.accountName = accountName;
@@ -64,7 +64,7 @@ public class PaymentProviderAccount {
         private String phoneNumber;
         private String defaultPaymentMethodId;
 
-        public Builder copyFrom(PaymentProviderAccount src) {
+        public Builder copyFrom(final PaymentProviderAccount src) {
             this.id = src.getId();
             this.accountKey = src.getAccountKey();
             this.accountName = src.getAccountName();
@@ -73,27 +73,27 @@ public class PaymentProviderAccount {
             return this;
         }
 
-        public Builder setId(String id) {
+        public Builder setId(final String id) {
             this.id = id;
             return this;
         }
 
-        public Builder setAccountKey(String accountKey) {
+        public Builder setAccountKey(final String accountKey) {
             this.accountKey = accountKey;
             return this;
         }
 
-        public Builder setAccountName(String accountName) {
+        public Builder setAccountName(final String accountName) {
             this.accountName = accountName;
             return this;
         }
 
-        public Builder setPhoneNumber(String phoneNumber) {
+        public Builder setPhoneNumber(final String phoneNumber) {
             this.phoneNumber = phoneNumber;
             return this;
         }
 
-        public Builder setDefaultPaymentMethod(String defaultPaymentMethod) {
+        public Builder setDefaultPaymentMethod(final String defaultPaymentMethod) {
             this.defaultPaymentMethodId = defaultPaymentMethod;
             return this;
         }
@@ -114,18 +114,17 @@ public class PaymentProviderAccount {
     }
 
     @Override
-    public boolean equals(Object obj) {
+    public boolean equals(final Object obj) {
         if (getClass() == obj.getClass()) {
-            PaymentProviderAccount other = (PaymentProviderAccount)obj;
+            final PaymentProviderAccount other = (PaymentProviderAccount) obj;
             if (obj == other) {
                 return true;
-            }
-            else {
+            } else {
                 return Objects.equal(id, other.id) &&
-                       Objects.equal(accountKey, other.accountKey) &&
-                       Objects.equal(accountName, other.accountName) &&
-                       Objects.equal(phoneNumber, other.phoneNumber) &&
-                       Objects.equal(defaultPaymentMethodId, other.defaultPaymentMethodId);
+                        Objects.equal(accountKey, other.accountKey) &&
+                        Objects.equal(accountName, other.accountName) &&
+                        Objects.equal(phoneNumber, other.phoneNumber) &&
+                        Objects.equal(defaultPaymentMethodId, other.defaultPaymentMethodId);
             }
         }
         return false;
diff --git a/api/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java b/api/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java
index 321a421..d05f762 100644
--- a/api/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java
+++ b/api/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java
@@ -24,6 +24,6 @@ public interface PaymentProviderPluginRegistry {
     public void register(final PaymentPluginApi plugin, final String name);
 
     public PaymentPluginApi getPlugin(final String name);
-    
+
     public Set<String> getRegisteredPluginNames();
 }
diff --git a/api/src/main/java/com/ning/billing/util/api/CustomFieldUserApi.java b/api/src/main/java/com/ning/billing/util/api/CustomFieldUserApi.java
index 649c034..828d030 100644
--- a/api/src/main/java/com/ning/billing/util/api/CustomFieldUserApi.java
+++ b/api/src/main/java/com/ning/billing/util/api/CustomFieldUserApi.java
@@ -16,14 +16,14 @@
 
 package com.ning.billing.util.api;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.customfield.CustomField;
-import com.ning.billing.util.dao.ObjectType;
-
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.dao.ObjectType;
+
 public interface CustomFieldUserApi {
     Map<String, CustomField> getCustomFields(UUID objectId, ObjectType objectType);
 
diff --git a/api/src/main/java/com/ning/billing/util/bus/Bus.java b/api/src/main/java/com/ning/billing/util/bus/Bus.java
index 3410e83..0368f27 100644
--- a/api/src/main/java/com/ning/billing/util/bus/Bus.java
+++ b/api/src/main/java/com/ning/billing/util/bus/Bus.java
@@ -16,19 +16,18 @@
 
 package com.ning.billing.util.bus;
 
-import com.google.common.eventbus.Subscribe;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
+import com.google.common.eventbus.Subscribe;
+
 
 /**
- *
  * Bus API based on the guava EventBus API
- *
+ * <p/>
  * The API also provides an API to send events from within a transaction
  * with the guarantee that the event will be delivered if and only if
  * the transaction completes. If the implementation is not based on a
  * DB, this API is behaves the same as the regular post() call.
- *
  */
 public interface Bus {
 
@@ -40,35 +39,32 @@ public interface Bus {
         public EventBusException() {
             super();
         }
-        public EventBusException(String message, Throwable cause) {
+
+        public EventBusException(final String message, final Throwable cause) {
             super(message, cause);
         }
 
-        public EventBusException(String message) {
+        public EventBusException(final String message) {
             super(message);
         }
     }
 
     /**
      * Start accepting events and dispatching them
-     *
      */
     public void start();
 
     /**
      * Stop accepting events and flush event queue before it returns.
-     *
      */
     public void stop();
 
     /**
-     *
      * Registers all handler methods on {@code object} to receive events.
      * Handler methods need to be Annotated with {@link Subscribe}
      *
      * @param handlerInstance
-     *
-     *  @throws EventBusException if bus not been started yet
+     * @throws EventBusException if bus not been started yet
      */
     public void register(Object handlerInstance) throws EventBusException;
 
@@ -86,21 +82,17 @@ public interface Bus {
      * Post an event asynchronously
      *
      * @param event to be posted
-     *
-     *  @throws EventBusException if bus not been started yet
+     * @throws EventBusException if bus not been started yet
      */
     public void post(BusEvent event) throws EventBusException;
 
     /**
-     *
      * Post an event from within a transaction.
      * Guarantees that the event is persisted on disk from within the same transaction
      *
-     *
      * @param event to be posted
-     * @param dao a valid DAO object obtained through the DBI.onDemand() API.
-     *
-     *  @throws EventBusException if bus not been started yet
+     * @param dao   a valid DAO object obtained through the DBI.onDemand() API.
+     * @throws EventBusException if bus not been started yet
      */
     public void postFromTransaction(BusEvent event, Transmogrifier dao) throws EventBusException;
 
diff --git a/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java b/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java
index fd364bf..2887f51 100644
--- a/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java
+++ b/api/src/main/java/com/ning/billing/util/callcontext/CallContext.java
@@ -21,12 +21,19 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 
 public interface CallContext {
-	public UUID getUserToken();
+    public UUID getUserToken();
+
     public String getUserName();
+
     public CallOrigin getCallOrigin();
+
     public UserType getUserType();
+
     public String getReasonCode();
+
     public String getComment();
+
     public DateTime getCreatedDate();
+
     public DateTime getUpdatedDate();
 }
diff --git a/api/src/main/java/com/ning/billing/util/dao/ObjectType.java b/api/src/main/java/com/ning/billing/util/dao/ObjectType.java
index b961b39..a158e77 100644
--- a/api/src/main/java/com/ning/billing/util/dao/ObjectType.java
+++ b/api/src/main/java/com/ning/billing/util/dao/ObjectType.java
@@ -27,7 +27,8 @@ public enum ObjectType {
     PAYMENT_METHOD("payment method");
 
     private final String objectName;
-    ObjectType(String objectName) {
+
+    ObjectType(final String objectName) {
         this.objectName = objectName;
     }
 
diff --git a/api/src/main/java/com/ning/billing/util/email/EmailApiException.java b/api/src/main/java/com/ning/billing/util/email/EmailApiException.java
index 9b5d6ba..6842e74 100644
--- a/api/src/main/java/com/ning/billing/util/email/EmailApiException.java
+++ b/api/src/main/java/com/ning/billing/util/email/EmailApiException.java
@@ -22,15 +22,15 @@ import com.ning.billing.ErrorCode;
 public class EmailApiException extends BillingExceptionBase {
     private static final long serialVersionUID = 1L;
 
-    public EmailApiException(Throwable cause, int code, final String msg) {
+    public EmailApiException(final Throwable cause, final int code, final String msg) {
         super(cause, code, msg);
     }
 
-    public EmailApiException(Throwable cause, ErrorCode code, final Object... args) {
+    public EmailApiException(final Throwable cause, final ErrorCode code, final Object... args) {
         super(cause, code, args);
     }
 
-    public EmailApiException(ErrorCode code, final Object... args) {
+    public EmailApiException(final ErrorCode code, final Object... args) {
         super(code, args);
     }
 }
diff --git a/api/src/main/java/com/ning/billing/util/entity/EntityPersistenceException.java b/api/src/main/java/com/ning/billing/util/entity/EntityPersistenceException.java
index 0b593ca..33dd3a8 100644
--- a/api/src/main/java/com/ning/billing/util/entity/EntityPersistenceException.java
+++ b/api/src/main/java/com/ning/billing/util/entity/EntityPersistenceException.java
@@ -22,15 +22,15 @@ import com.ning.billing.ErrorCode;
 public class EntityPersistenceException extends BillingExceptionBase {
     private static final long serialVersionUID = 1L;
 
-    public EntityPersistenceException(Throwable cause, int code, final String msg) {
+    public EntityPersistenceException(final Throwable cause, final int code, final String msg) {
         super(cause, code, msg);
     }
 
-    public EntityPersistenceException(Throwable cause, ErrorCode code, final Object... args) {
+    public EntityPersistenceException(final Throwable cause, final ErrorCode code, final Object... args) {
         super(cause, code, args);
     }
 
-    public EntityPersistenceException(ErrorCode code, final Object... args) {
+    public EntityPersistenceException(final ErrorCode code, final Object... args) {
         super(code, args);
     }
 }
diff --git a/api/src/main/java/com/ning/billing/util/queue/QueueLifecycle.java b/api/src/main/java/com/ning/billing/util/queue/QueueLifecycle.java
index 8db4ec7..b839468 100644
--- a/api/src/main/java/com/ning/billing/util/queue/QueueLifecycle.java
+++ b/api/src/main/java/com/ning/billing/util/queue/QueueLifecycle.java
@@ -23,12 +23,11 @@ public interface QueueLifecycle {
 
     /**
      * Stop the queue
-     *
      */
     public void stopQueue();
-    
+
     /**
-     *  Processes event from queue
+     * Processes event from queue
      */
     public int doProcessEvents();
 }
diff --git a/api/src/main/java/com/ning/billing/util/tag/ControlTagType.java b/api/src/main/java/com/ning/billing/util/tag/ControlTagType.java
index 65d32c7..f7bf292 100644
--- a/api/src/main/java/com/ning/billing/util/tag/ControlTagType.java
+++ b/api/src/main/java/com/ning/billing/util/tag/ControlTagType.java
@@ -20,7 +20,7 @@ import java.util.UUID;
 
 public enum ControlTagType {
     AUTO_PAY_OFF("Suspends payments until removed.", true, false),
-    AUTO_INVOICING_OFF("Suspends invoicing until removed.", false, true), 
+    AUTO_INVOICING_OFF("Suspends invoicing until removed.", false, true),
     OVERDUE_ENFORCEMENT_OFF("Suspends overdue enforcement behaviour until removed.", false, false),
     WRITTEN_OFF("Indicated that an invoice is written off. No billing or payment effect.", false, false);
 
@@ -48,15 +48,25 @@ public enum ControlTagType {
 
     public TagDefinition toTagDefinition() {
         return new TagDefinition() {
-            @Override public String getName() {
+            @Override
+            public String getName() {
                 return name();
             }
 
-            @Override public String getDescription() {return description;}
+            @Override
+            public String getDescription() {
+                return description;
+            }
 
-            @Override public Boolean isControlTag() {return true;}
+            @Override
+            public Boolean isControlTag() {
+                return true;
+            }
 
-            @Override public UUID getId() {return null;}
+            @Override
+            public UUID getId() {
+                return null;
+            }
         };
     }
 }
diff --git a/api/src/main/java/com/ning/billing/util/template/translation/TranslatorConfig.java b/api/src/main/java/com/ning/billing/util/template/translation/TranslatorConfig.java
index 506c8bc..14dacf5 100644
--- a/api/src/main/java/com/ning/billing/util/template/translation/TranslatorConfig.java
+++ b/api/src/main/java/com/ning/billing/util/template/translation/TranslatorConfig.java
@@ -19,8 +19,22 @@ package com.ning.billing.util.template.translation;
 import org.skife.config.Config;
 import org.skife.config.Default;
 
+import com.ning.billing.invoice.api.formatters.InvoiceFormatterFactory;
+
 public interface TranslatorConfig {
-    @Config("email.default.locale")
+    @Config("killbill.template.default.locale")
     @Default("en_US")
     public String getDefaultLocale();
+
+    @Config("killbill.template.bundlePath")
+    @Default("com/ning/billing/util/template/translation/InvoiceTranslation")
+    public String getBundlePath();
+
+    @Config("killbill.template.name")
+    @Default("com/ning/billing/util/email/templates/HtmlInvoiceTemplate.mustache")
+    String getTemplateName();
+
+    @Config("killbill.template.invoiceFormatterFactoryClass")
+    @Default("com.ning.billing.invoice.template.formatters.DefaultInvoiceFormatterFactory")
+    Class<? extends InvoiceFormatterFactory> getInvoiceFormatterFactoryClass();
 }
diff --git a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequest.java b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequest.java
index bf67736..f240a02 100644
--- a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequest.java
+++ b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequest.java
@@ -15,5 +15,5 @@
  */
 package com.ning.billing.util.userrequest;
 
-public interface CompletionUserRequest extends CompletionUserRequestNotifier, CompletionUserRequestWaiter{
+public interface CompletionUserRequest extends CompletionUserRequestNotifier, CompletionUserRequestWaiter {
 }
diff --git a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestNotifier.java b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestNotifier.java
index 62b9256..befa2d7 100644
--- a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestNotifier.java
+++ b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestNotifier.java
@@ -20,6 +20,6 @@ import com.ning.billing.util.bus.BusEvent;
 public interface CompletionUserRequestNotifier {
 
     public void notifyForCompletion();
-    
+
     public void onBusEvent(BusEvent curEvent);
 }
diff --git a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java
index d1258c8..f491beb 100644
--- a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java
+++ b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java
@@ -16,7 +16,6 @@
 package com.ning.billing.util.userrequest;
 
 import java.util.List;
-import java.util.UUID;
 import java.util.concurrent.TimeoutException;
 
 import com.ning.billing.account.api.AccountChangeEvent;
@@ -31,18 +30,18 @@ import com.ning.billing.util.bus.BusEvent;
 public interface CompletionUserRequestWaiter {
 
     public List<BusEvent> waitForCompletion(final long timeoutMilliSec) throws InterruptedException, TimeoutException;
-    
+
     public void onAccountCreation(final AccountCreationEvent curEvent);
 
     public void onAccountChange(final AccountChangeEvent curEvent);
 
-    public void onSubscriptionTransition(final SubscriptionEvent curEvent);    
+    public void onSubscriptionTransition(final SubscriptionEvent curEvent);
+
+    public void onInvoiceCreation(final InvoiceCreationEvent curEvent);
 
-    public void onInvoiceCreation(final InvoiceCreationEvent curEvent);    
-    
-    public void onEmptyInvoice(final EmptyInvoiceEvent curEvent);        
+    public void onEmptyInvoice(final EmptyInvoiceEvent curEvent);
 
-    public void onPaymentInfo(final PaymentInfoEvent curEvent);    
+    public void onPaymentInfo(final PaymentInfoEvent curEvent);
 
-    public void onPaymentError(final PaymentErrorEvent curEvent);    
+    public void onPaymentError(final PaymentErrorEvent curEvent);
 }

beatrix/pom.xml 25(+15 -10)

diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index 547db04..406b097 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-beatrix</artifactId>
@@ -67,15 +67,20 @@
         </dependency>
 
         <!-- TEST SCOPE -->
-        <dependency> 
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>com.jayway.awaitility</groupId>
             <artifactId>awaitility</artifactId>
             <scope>test</scope>
-        </dependency>      
-         <dependency>
+        </dependency>
+        <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-junction</artifactId>
-             <type>test-jar</type>
+            <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -103,6 +108,11 @@
         </dependency>
         <dependency>
             <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-analytics</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
             <artifactId>killbill-overdue</artifactId>
             <scope>test</scope>
         </dependency>
@@ -118,11 +128,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-util</artifactId>
             <type>test-jar</type>
diff --git a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java
index 8a07355..c5cfd73 100644
--- a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/DefaultLifecycle.java
@@ -16,6 +16,18 @@
 
 package com.ning.billing.beatrix.lifecycle;
 
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import com.google.common.base.Supplier;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
@@ -27,22 +39,11 @@ import com.ning.billing.lifecycle.KillbillService;
 import com.ning.billing.lifecycle.LifecycleHandlerType;
 import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
 import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel.Sequence;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
 
 
 public class DefaultLifecycle implements Lifecycle {
 
-    private final static Logger log = LoggerFactory.getLogger(DefaultLifecycle.class);
+    private static final Logger log = LoggerFactory.getLogger(DefaultLifecycle.class);
     private final SetMultimap<LifecycleLevel, LifecycleHandler<? extends KillbillService>> handlersByLevel;
 
     private final ServiceFinder serviceFinder;
@@ -50,17 +51,17 @@ public class DefaultLifecycle implements Lifecycle {
     protected final Injector injector;
 
     @Inject
-    public DefaultLifecycle(Injector injector) {
+    public DefaultLifecycle(final Injector injector) {
 
         this.serviceFinder = new ServiceFinder(DefaultLifecycle.class.getClassLoader());
         this.handlersByLevel = Multimaps.newSetMultimap(new ConcurrentHashMap<LifecycleLevel, Collection<LifecycleHandler<? extends KillbillService>>>(),
 
-                new Supplier<Set<LifecycleHandler<? extends KillbillService>>>() {
-            @Override
-            public Set<LifecycleHandler<? extends KillbillService>> get() {
-                return new CopyOnWriteArraySet<LifecycleHandler<? extends KillbillService>>();
-            }
-        });
+                                                        new Supplier<Set<LifecycleHandler<? extends KillbillService>>>() {
+                                                            @Override
+                                                            public Set<LifecycleHandler<? extends KillbillService>> get() {
+                                                                return new CopyOnWriteArraySet<LifecycleHandler<? extends KillbillService>>();
+                                                            }
+                                                        });
         this.injector = injector;
 
         init();
@@ -89,12 +90,12 @@ public class DefaultLifecycle implements Lifecycle {
 
     protected Set<? extends KillbillService> findServices() {
 
-        Set<KillbillService> result = new HashSet<KillbillService>();
-        Set<Class<? extends KillbillService>> services =  serviceFinder.getServices();
-        for (Class<? extends KillbillService> cur : services) {
+        final Set<KillbillService> result = new HashSet<KillbillService>();
+        final Set<Class<? extends KillbillService>> services = serviceFinder.getServices();
+        for (final Class<? extends KillbillService> cur : services) {
             log.debug("Found service {}", cur.getName());
             try {
-                KillbillService instance = injector.getInstance(cur);
+                final KillbillService instance = injector.getInstance(cur);
                 log.debug("got instance {}", instance.getName());
                 result.add(instance);
             } catch (Exception e) {
@@ -106,28 +107,28 @@ public class DefaultLifecycle implements Lifecycle {
     }
 
     private void init() {
-        Set<? extends KillbillService> services = findServices();
-        Iterator<? extends KillbillService> it = services.iterator();
+        final Set<? extends KillbillService> services = findServices();
+        final Iterator<? extends KillbillService> it = services.iterator();
         while (it.hasNext()) {
             handlersByLevel.putAll(findAllHandlers(it.next()));
         }
     }
 
-    private void fireSequence(Sequence seq) {
-        List<LifecycleLevel> levels = LifecycleLevel.getLevelsForSequence(seq);
-        for (LifecycleLevel cur : levels) {
+    private void fireSequence(final Sequence seq) {
+        final List<LifecycleLevel> levels = LifecycleLevel.getLevelsForSequence(seq);
+        for (final LifecycleLevel cur : levels) {
             doFireStage(cur);
         }
     }
 
-    private void doFireStage(LifecycleLevel level) {
+    private void doFireStage(final LifecycleLevel level) {
         log.info("Killbill lifecycle firing stage {}", level);
-        Set<LifecycleHandler<? extends KillbillService>> handlers = handlersByLevel.get(level);
-        for (LifecycleHandler<? extends KillbillService> cur : handlers) {
+        final Set<LifecycleHandler<? extends KillbillService>> handlers = handlersByLevel.get(level);
+        for (final LifecycleHandler<? extends KillbillService> cur : handlers) {
 
             try {
-                Method method = cur.getMethod();
-                KillbillService target = cur.getTarget();
+                final Method method = cur.getMethod();
+                final KillbillService target = cur.getTarget();
                 log.info("Killbill lifecycle calling handler {} for service {}", cur.getMethod().getName(), target.getName());
                 method.invoke(target);
             } catch (Exception e) {
@@ -139,18 +140,18 @@ public class DefaultLifecycle implements Lifecycle {
 
 
     // Used to disable valid injection failure from unit tests
-    protected void logWarn(String msg, Exception e) {
+    protected void logWarn(final String msg, final Exception e) {
         log.warn(msg, e);
     }
 
-    private Multimap<LifecycleLevel, LifecycleHandler<? extends KillbillService>> findAllHandlers(KillbillService service) {
-        Multimap<LifecycleLevel, LifecycleHandler<? extends KillbillService>> methodsInService = HashMultimap.create();
-        Class<? extends KillbillService> clazz = service.getClass();
-        for (Method method : clazz.getMethods()) {
-            LifecycleHandlerType annotation = method.getAnnotation(LifecycleHandlerType.class);
+    private Multimap<LifecycleLevel, LifecycleHandler<? extends KillbillService>> findAllHandlers(final KillbillService service) {
+        final Multimap<LifecycleLevel, LifecycleHandler<? extends KillbillService>> methodsInService = HashMultimap.create();
+        final Class<? extends KillbillService> clazz = service.getClass();
+        for (final Method method : clazz.getMethods()) {
+            final LifecycleHandlerType annotation = method.getAnnotation(LifecycleHandlerType.class);
             if (annotation != null) {
-                LifecycleLevel level = annotation.value();
-                LifecycleHandler<? extends KillbillService> handler = new  LifecycleHandler<KillbillService>(service, method);
+                final LifecycleLevel level = annotation.value();
+                final LifecycleHandler<? extends KillbillService> handler = new LifecycleHandler<KillbillService>(service, method);
                 methodsInService.put(level, handler);
             }
         }
@@ -161,7 +162,7 @@ public class DefaultLifecycle implements Lifecycle {
         private final T target;
         private final Method method;
 
-        public LifecycleHandler(T target, Method method) {
+        public LifecycleHandler(final T target, final Method method) {
             this.target = target;
             this.method = method;
         }
diff --git a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java
index e27dff9..52c7716 100644
--- a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.beatrix.lifecycle;
 
-import com.ning.billing.lifecycle.KillbillService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.io.File;
 import java.io.IOException;
 import java.net.MalformedURLException;
@@ -33,178 +29,183 @@ import java.util.List;
 import java.util.Set;
 import java.util.jar.JarFile;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ning.billing.lifecycle.KillbillService;
+
 public class ServiceFinder {
 
     private static final Logger log = LoggerFactory.getLogger(ServiceFinder.class);
 
-	private final ClassLoader loader;
-	private final Set<Class<? extends KillbillService>> servicesTypes;
-
-	public ServiceFinder(ClassLoader loader) {
-		this.loader = loader;
-		this.servicesTypes = initialize();
-		Iterator<Class<? extends KillbillService>> it = servicesTypes.iterator();
-		while (it.hasNext()) {
-		    Class<? extends KillbillService> svc = it.next();
-			log.debug("Found IService classes {}", svc.getName());
-		}
-	}
-
-	public Set<Class<? extends KillbillService>> getServices() {
-	    return servicesTypes;
-	}
-
-	private Set<Class<? extends KillbillService>> initialize() {
-		try {
-
-		    final Set<String> packageFilter = new HashSet<String>();
-		    packageFilter.add("com.ning.billing");
-		    final String jarFilter = "killbill";
-			return findClasses(loader, KillbillService.class.getName(), jarFilter, packageFilter);
-		} catch (ClassNotFoundException nfe) {
-			throw new RuntimeException("Failed to initialize ClassFinder", nfe);
-		}
-	}
+    private final ClassLoader loader;
+    private final Set<Class<? extends KillbillService>> servicesTypes;
+
+    public ServiceFinder(final ClassLoader loader) {
+        this.loader = loader;
+        this.servicesTypes = initialize();
+        final Iterator<Class<? extends KillbillService>> it = servicesTypes.iterator();
+        while (it.hasNext()) {
+            final Class<? extends KillbillService> svc = it.next();
+            log.debug("Found IService classes {}", svc.getName());
+        }
+    }
+
+    public Set<Class<? extends KillbillService>> getServices() {
+        return servicesTypes;
+    }
+
+    private Set<Class<? extends KillbillService>> initialize() {
+        try {
+
+            final Set<String> packageFilter = new HashSet<String>();
+            packageFilter.add("com.ning.billing");
+            final String jarFilter = "killbill";
+            return findClasses(loader, KillbillService.class.getName(), jarFilter, packageFilter);
+        } catch (ClassNotFoundException nfe) {
+            throw new RuntimeException("Failed to initialize ClassFinder", nfe);
+        }
+    }
 
     /*
      *  Code originally from Kris Dover <krisdover@hotmail.com> and adapted for my purpose.
      *
      */
-	private static Set<Class<? extends KillbillService>> findClasses(ClassLoader classLoader,
-	        String interfaceFilter,
-	        String jarFilter,
-	        Set<String> packageFilter)
-	        throws ClassNotFoundException {
-
-	    final Set<Class<? extends KillbillService>> result = new HashSet<Class<? extends KillbillService>>();
-
-	    Object[] classPaths;
-	    try {
-	        classPaths = ((java.net.URLClassLoader) classLoader).getURLs();
-	    } catch(ClassCastException cce){
-	        classPaths = System.getProperty("java.class.path", "").split(File.pathSeparator);
-	    }
-
-	    for (int h = 0; h < classPaths.length; h++) {
-	        Enumeration<?> files = null;
-	        JarFile module = null;
-	        File classPath = new File( (URL.class).isInstance(classPaths[h]) ?
-	                ((URL)classPaths[h]).getFile() : classPaths[h].toString());
-	        if (classPath.isDirectory()) {
+    private static Set<Class<? extends KillbillService>> findClasses(final ClassLoader classLoader,
+                                                                     final String interfaceFilter,
+                                                                     final String jarFilter,
+                                                                     final Set<String> packageFilter)
+            throws ClassNotFoundException {
+
+        final Set<Class<? extends KillbillService>> result = new HashSet<Class<? extends KillbillService>>();
+
+        Object[] classPaths;
+        try {
+            classPaths = ((java.net.URLClassLoader) classLoader).getURLs();
+        } catch (ClassCastException cce) {
+            classPaths = System.getProperty("java.class.path", "").split(File.pathSeparator);
+        }
+
+        for (int h = 0; h < classPaths.length; h++) {
+            Enumeration<?> files = null;
+            JarFile module = null;
+            final File classPath = new File((URL.class).isInstance(classPaths[h]) ?
+                                              ((URL) classPaths[h]).getFile() : classPaths[h].toString());
+            if (classPath.isDirectory()) {
 
                 log.debug("DIR : " + classPath);
 
-	            List<String> dirListing = new ArrayList<String>();
-	            recursivelyListDir(dirListing, classPath, new StringBuffer() );
-	            files = Collections.enumeration(dirListing);
-	        } else if (classPath.getName().endsWith(".jar")) {
-
-	            log.debug("JAR : " + classPath);
-
-	            String [] jarParts = classPath.getName().split("/");
-	            String jarName = jarParts[jarParts.length - 1];
-	            if (jarFilter != null && jarName != null && ! jarName.startsWith(jarFilter)) {
-	                continue;
-	            }
-	            boolean failed = true;
-	            try {
-	                module = new JarFile(classPath);
-	                failed = false;
-	            } catch (MalformedURLException mue){
-	                throw new ClassNotFoundException("Bad classpath. Error: " + mue.getMessage());
-	            } catch (IOException io){
-	                throw new ClassNotFoundException("jar file '" + classPath.getName() +
-	                        "' could not be instantiate from file path. Error: " + io.getMessage());
-	            }
-	            if (! failed) {
-	                files = module.entries();
-	            }
-	        }
-
-	        while( files != null && files.hasMoreElements() ){
-	            String fileName = files.nextElement().toString();
-
-	            if( fileName.endsWith(".class") ){
-	                String className = fileName.replaceAll("/", ".").substring(0, fileName.length() - 6);
-	                if (packageFilter != null) {
-	                    boolean skip = true;
-	                    Iterator<String> it = packageFilter.iterator();
-	                    while (it.hasNext()) {
-	                        String filter = it.next() + ".";
-	                        if (className.startsWith(filter)) {
-	                            skip = false;
-	                            break;
-	                        }
-	                    }
-	                    if (skip) {
-	                        continue;
-	                    }
-	                }
-	                Class<?> theClass = null;
-	                try {
-	                    theClass = Class.forName(className, false, classLoader);
-	                } catch(NoClassDefFoundError e) {
-	                    continue;
-	                }
-	                if ( theClass.isInterface() ) {
-	                    continue;
-	                }
-	                Class<?> [] classInterfaces = getAllInterfaces(theClass);
-	                String interfaceName = null;
-	                for (int i = 0; i < classInterfaces.length; i++) {
-
-	                    interfaceName = classInterfaces[i].getName();
-	                    if (!interfaceFilter.equals(interfaceName) ) {
-	                        continue;
-	                    }
-	                    result.add((Class<? extends KillbillService>) theClass);
-	                    break;
-	                }
-
-	            }
-	        }
-	        if (module != null) {
-	            try {
-	                module.close();
-	            } catch(IOException ioe) {
-	                throw new ClassNotFoundException("The module jar file '" + classPath.getName() +
-	                        "' could not be closed. Error: " + ioe.getMessage());
-	            }
-	        }
-	    }
-	    return result;
-	}
-
-	private static Class<?> [] getAllInterfaces(Class<?> theClass) {
-	    Set<Class<?>> superInterfaces = new HashSet<Class<?>>();
-	    Class<?> [] classInterfaces = theClass.getInterfaces();
-	    for (Class<?> cur : classInterfaces) {
-	        getSuperInterfaces(superInterfaces, cur);
-	    }
-	    return superInterfaces.toArray(new Class<?>[superInterfaces.size()]);
-	}
-
-	private static void getSuperInterfaces(Set<Class<?>> superInterfaces, Class<?> theInterface) {
-
-	    superInterfaces.add(theInterface);
-	    Class<?> [] classInterfaces = theInterface.getInterfaces();
-	    for (Class<?> cur : classInterfaces) {
-	        getSuperInterfaces(superInterfaces, cur);
-	    }
-	}
-
-	private static void recursivelyListDir(List<String> dirListing, File dir, StringBuffer relativePath){
-	    int prevLen;
-	    if (dir.isDirectory()) {
-	        File[] files = dir.listFiles();
-	        for(int i = 0; i < files.length; i++){
-	            prevLen = relativePath.length();
-	            recursivelyListDir(dirListing, files[i],
-	                    relativePath.append(prevLen == 0 ? "" : "/" ).append( files[i].getName()));
-	            relativePath.delete(prevLen, relativePath.length());
-	        }
-	    } else {
-	        dirListing.add(relativePath.toString());
-	    }
-	}
+                final List<String> dirListing = new ArrayList<String>();
+                recursivelyListDir(dirListing, classPath, new StringBuffer());
+                files = Collections.enumeration(dirListing);
+            } else if (classPath.getName().endsWith(".jar")) {
+
+                log.debug("JAR : " + classPath);
+
+                final String[] jarParts = classPath.getName().split("/");
+                final String jarName = jarParts[jarParts.length - 1];
+                if (jarFilter != null && jarName != null && !jarName.startsWith(jarFilter)) {
+                    continue;
+                }
+                boolean failed = true;
+                try {
+                    module = new JarFile(classPath);
+                    failed = false;
+                } catch (MalformedURLException mue) {
+                    throw new ClassNotFoundException("Bad classpath. Error: " + mue.getMessage());
+                } catch (IOException io) {
+                    throw new ClassNotFoundException("jar file '" + classPath.getName() +
+                                                             "' could not be instantiate from file path. Error: " + io.getMessage());
+                }
+                if (!failed) {
+                    files = module.entries();
+                }
+            }
+
+            while (files != null && files.hasMoreElements()) {
+                final String fileName = files.nextElement().toString();
+
+                if (fileName.endsWith(".class")) {
+                    final String className = fileName.replaceAll("/", ".").substring(0, fileName.length() - 6);
+                    if (packageFilter != null) {
+                        boolean skip = true;
+                        final Iterator<String> it = packageFilter.iterator();
+                        while (it.hasNext()) {
+                            final String filter = it.next() + ".";
+                            if (className.startsWith(filter)) {
+                                skip = false;
+                                break;
+                            }
+                        }
+                        if (skip) {
+                            continue;
+                        }
+                    }
+                    Class<?> theClass = null;
+                    try {
+                        theClass = Class.forName(className, false, classLoader);
+                    } catch (NoClassDefFoundError e) {
+                        continue;
+                    }
+                    if (theClass.isInterface()) {
+                        continue;
+                    }
+                    final Class<?>[] classInterfaces = getAllInterfaces(theClass);
+                    String interfaceName = null;
+                    for (int i = 0; i < classInterfaces.length; i++) {
+
+                        interfaceName = classInterfaces[i].getName();
+                        if (!interfaceFilter.equals(interfaceName)) {
+                            continue;
+                        }
+                        result.add((Class<? extends KillbillService>) theClass);
+                        break;
+                    }
+
+                }
+            }
+            if (module != null) {
+                try {
+                    module.close();
+                } catch (IOException ioe) {
+                    throw new ClassNotFoundException("The module jar file '" + classPath.getName() +
+                                                             "' could not be closed. Error: " + ioe.getMessage());
+                }
+            }
+        }
+        return result;
+    }
+
+    private static Class<?>[] getAllInterfaces(final Class<?> theClass) {
+        final Set<Class<?>> superInterfaces = new HashSet<Class<?>>();
+        final Class<?>[] classInterfaces = theClass.getInterfaces();
+        for (final Class<?> cur : classInterfaces) {
+            getSuperInterfaces(superInterfaces, cur);
+        }
+        return superInterfaces.toArray(new Class<?>[superInterfaces.size()]);
+    }
+
+    private static void getSuperInterfaces(final Set<Class<?>> superInterfaces, final Class<?> theInterface) {
+
+        superInterfaces.add(theInterface);
+        final Class<?>[] classInterfaces = theInterface.getInterfaces();
+        for (final Class<?> cur : classInterfaces) {
+            getSuperInterfaces(superInterfaces, cur);
+        }
+    }
+
+    private static void recursivelyListDir(final List<String> dirListing, final File dir, final StringBuffer relativePath) {
+        int prevLen;
+        if (dir.isDirectory()) {
+            final File[] files = dir.listFiles();
+            for (int i = 0; i < files.length; i++) {
+                prevLen = relativePath.length();
+                recursivelyListDir(dirListing, files[i],
+                                   relativePath.append(prevLen == 0 ? "" : "/").append(files[i].getName()));
+                relativePath.delete(prevLen, relativePath.length());
+            }
+        } else {
+            dirListing.add(relativePath.toString());
+        }
+    }
 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixModule.java
index 58a9c63..c26fac5 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixModule.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixModule.java
@@ -16,8 +16,6 @@
 
 package com.ning.billing.beatrix.integration;
 
-import static org.testng.Assert.assertNotNull;
-
 import java.io.IOException;
 import java.net.URL;
 import java.util.Set;
@@ -31,7 +29,7 @@ import com.google.inject.Inject;
 import com.google.inject.Injector;
 import com.ning.billing.account.api.AccountService;
 import com.ning.billing.account.glue.AccountModule;
-import com.ning.billing.account.glue.AccountModuleWithMocks;
+import com.ning.billing.analytics.setup.AnalyticsModule;
 import com.ning.billing.beatrix.integration.overdue.IntegrationTestOverdueModule;
 import com.ning.billing.beatrix.lifecycle.DefaultLifecycle;
 import com.ning.billing.beatrix.lifecycle.Lifecycle;
@@ -63,9 +61,11 @@ import com.ning.billing.util.glue.GlobalLockerModule;
 import com.ning.billing.util.glue.NotificationQueueModule;
 import com.ning.billing.util.glue.TagStoreModule;
 
+import static org.testng.Assert.assertNotNull;
+
 
 public class BeatrixModule extends AbstractModule {
-    
+
     public static final String PLUGIN_NAME = "yoyo";
 
     @Override
@@ -82,7 +82,7 @@ public class BeatrixModule extends AbstractModule {
         final IDBI dbi;
         if (helper.isUsingLocalInstance()) {
             final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
-            DBIProvider provider = new DBIProvider(config);
+            final DBIProvider provider = new DBIProvider(config);
             dbi = provider.get();
         } else {
             dbi = helper.getDBI();
@@ -97,6 +97,7 @@ public class BeatrixModule extends AbstractModule {
         install(new TagStoreModule());
         install(new CustomFieldModule());
         install(new AccountModule());
+        install(new AnalyticsModule());
         install(new CatalogModule());
         install(new DefaultEntitlementModule());
         install(new DefaultInvoiceModule());
@@ -108,7 +109,7 @@ public class BeatrixModule extends AbstractModule {
 
     private static final class PaymentPluginMockModule extends PaymentModule {
         @Override
-        protected void installPaymentProviderPlugins(PaymentConfig config) {
+        protected void installPaymentProviderPlugins(final PaymentConfig config) {
             install(new MockPaymentProviderPluginModule(PLUGIN_NAME));
         }
     }
@@ -117,30 +118,30 @@ public class BeatrixModule extends AbstractModule {
         final URL url = TestIntegration.class.getResource(resource);
         assertNotNull(url);
         try {
-            System.getProperties().load( url.openStream() );
+            System.getProperties().load(url.openStream());
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
     }
 
-    private final static class SubsetDefaultLifecycle extends DefaultLifecycle {
+    private static final class SubsetDefaultLifecycle extends DefaultLifecycle {
 
         @Inject
-        public SubsetDefaultLifecycle(Injector injector) {
+        public SubsetDefaultLifecycle(final Injector injector) {
             super(injector);
         }
 
         @Override
         protected Set<? extends KillbillService> findServices() {
-            ImmutableSet<? extends KillbillService> services = new ImmutableSet.Builder<KillbillService>()
-                            .add(injector.getInstance(AccountService.class))
-                            .add(injector.getInstance(BusService.class))
-                            .add(injector.getInstance(CatalogService.class))
-                            .add(injector.getInstance(EntitlementService.class))
-                            .add(injector.getInstance(InvoiceService.class))
-                            .add(injector.getInstance(PaymentService.class))
-                            .add(injector.getInstance(OverdueService.class))
-                            .build();
+            final ImmutableSet<? extends KillbillService> services = new ImmutableSet.Builder<KillbillService>()
+                    .add(injector.getInstance(AccountService.class))
+                    .add(injector.getInstance(BusService.class))
+                    .add(injector.getInstance(CatalogService.class))
+                    .add(injector.getInstance(EntitlementService.class))
+                    .add(injector.getInstance(InvoiceService.class))
+                    .add(injector.getInstance(PaymentService.class))
+                    .add(injector.getInstance(OverdueService.class))
+                    .build();
             return services;
         }
     }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/IntegrationTestOverdueModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/IntegrationTestOverdueModule.java
index 2e120dc..45c948a 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/IntegrationTestOverdueModule.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/IntegrationTestOverdueModule.java
@@ -20,11 +20,11 @@ import com.ning.billing.overdue.OverdueService;
 import com.ning.billing.overdue.glue.DefaultOverdueModule;
 
 public class IntegrationTestOverdueModule extends DefaultOverdueModule {
-   
-    
+
+
     protected void installOverdueService() {
-        bind(OverdueService.class).to(MockOverdueService.class);    
+        bind(OverdueService.class).to(MockOverdueService.class);
     }
 
-     
+
 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/MockOverdueService.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/MockOverdueService.java
index cdb323b..7dc1ddb 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/MockOverdueService.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/MockOverdueService.java
@@ -27,13 +27,13 @@ import com.ning.billing.util.bus.BusService;
 
 public class MockOverdueService extends DefaultOverdueService {
     @Inject
-    public MockOverdueService(OverdueUserApi userApi, OverdueProperties properties, OverdueCheckNotifier notifier,
-            BusService busService, OverdueListener listener, OverdueWrapperFactory factory) {
+    public MockOverdueService(final OverdueUserApi userApi, final OverdueProperties properties, final OverdueCheckNotifier notifier,
+                              final BusService busService, final OverdueListener listener, final OverdueWrapperFactory factory) {
         super(userApi, properties, notifier, busService, listener, factory);
     }
 
     public synchronized void loadConfig() throws ServiceException {
-       
+
     }
- 
-}
\ No newline at end of file
+
+}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index 8b205f8..c6b1d85 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.beatrix.integration.overdue;
 
-import static com.jayway.awaitility.Awaitility.await;
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.math.BigDecimal;
@@ -62,73 +57,35 @@ import com.ning.billing.util.callcontext.DefaultCallContext;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.config.XMLLoader;
 
+import static com.jayway.awaitility.Awaitility.await;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 @Test(groups = "slow")
 @Guice(modules = {BeatrixModule.class})
 public class TestOverdueIntegration extends TestIntegrationBase {
-    private final String configXml =  
-            "<overdueConfig>" +
-                    "   <bundleOverdueStates>" +
-                    "       <state name=\"OD3\">" +
-                    "           <condition>" +
-                    "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                    "                   <unit>DAYS</unit><number>50</number>" +
-                    "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                    "           </condition>" +
-                    "           <externalMessage>Reached OD3</externalMessage>" +
-                    "           <blockChanges>true</blockChanges>" +
-                    "           <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
-                    "           <autoReevaluationInterval>" +
-                    "               <unit>DAYS</unit><number>5</number>" +
-                    "           </autoReevaluationInterval>" +
-                    "       </state>" +
-                    "       <state name=\"OD2\">" +
-                    "           <condition>" +
-                    "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                    "                   <unit>DAYS</unit><number>40</number>" +
-                    "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                    "           </condition>" +
-                    "           <externalMessage>Reached OD2</externalMessage>" +
-                    "           <blockChanges>true</blockChanges>" +
-                    "           <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
-                    "           <autoReevaluationInterval>" +
-                    "               <unit>DAYS</unit><number>5</number>" +
-                    "           </autoReevaluationInterval>" +
-                    "       </state>" +
-                    "       <state name=\"OD1\">" +
-                    "           <condition>" +
-                    "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                    "                   <unit>DAYS</unit><number>30</number>" +
-                    "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                    "           </condition>" +
-                    "           <externalMessage>Reached OD1</externalMessage>" +
-                    "           <blockChanges>true</blockChanges>" +
-                    "           <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
-                    "           <autoReevaluationInterval>" +
-                    "               <unit>DAYS</unit><number>100</number>" + // this number is intentionally too high
-                    "           </autoReevaluationInterval>" +
-                    "       </state>" +
-                    "   </bundleOverdueStates>" +
-                    "</overdueConfig>";
-    private OverdueConfig config; 
 
     @Inject
     private ClockMock clock;
 
+    @Named("yoyo")
     @Inject
-    private @Named("yoyo") MockPaymentProviderPlugin paymentPlugin;
+    private
+    MockPaymentProviderPlugin paymentPlugin;
 
     @Inject
     private BlockingApi blockingApi;
-    
+
     @Inject
     private OverdueWrapperFactory overdueWrapperFactory;
-    
+
     @Inject
     private OverdueUserApi overdueApi;
-    
+
     @Inject
     private PaymentApi paymentApi;
-    
+
     @Inject
     private InvoiceUserApi invoiceApi;
 
@@ -140,26 +97,72 @@ public class TestOverdueIntegration extends TestIntegrationBase {
 
     @BeforeMethod(groups = {"slow"})
     public void setupOverdue() throws Exception {
-        InputStream is = new ByteArrayInputStream(configXml.getBytes());
-        config = XMLLoader.getObjectFromStreamNoValidation(is,  OverdueConfig.class);
+        final String configXml = "<overdueConfig>" +
+                "   <bundleOverdueStates>" +
+                "       <state name=\"OD3\">" +
+                "           <condition>" +
+                "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                "                   <unit>DAYS</unit><number>50</number>" +
+                "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                "           </condition>" +
+                "           <externalMessage>Reached OD3</externalMessage>" +
+                "           <blockChanges>true</blockChanges>" +
+                "           <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
+                "           <autoReevaluationInterval>" +
+                "               <unit>DAYS</unit><number>5</number>" +
+                "           </autoReevaluationInterval>" +
+                "       </state>" +
+                "       <state name=\"OD2\">" +
+                "           <condition>" +
+                "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                "                   <unit>DAYS</unit><number>40</number>" +
+                "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                "           </condition>" +
+                "           <externalMessage>Reached OD2</externalMessage>" +
+                "           <blockChanges>true</blockChanges>" +
+                "           <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
+                "           <autoReevaluationInterval>" +
+                "               <unit>DAYS</unit><number>5</number>" +
+                "           </autoReevaluationInterval>" +
+                "       </state>" +
+                "       <state name=\"OD1\">" +
+                "           <condition>" +
+                "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                "                   <unit>DAYS</unit><number>30</number>" +
+                "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                "           </condition>" +
+                "           <externalMessage>Reached OD1</externalMessage>" +
+                "           <blockChanges>true</blockChanges>" +
+                "           <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
+                "           <autoReevaluationInterval>" +
+                "               <unit>DAYS</unit><number>100</number>" + // this number is intentionally too high
+                "           </autoReevaluationInterval>" +
+                "       </state>" +
+                "   </bundleOverdueStates>" +
+                "</overdueConfig>";
+        final InputStream is = new ByteArrayInputStream(configXml.getBytes());
+        final OverdueConfig config = XMLLoader.getObjectFromStreamNoValidation(is, OverdueConfig.class);
         overdueWrapperFactory.setOverdueConfig(config);
-        
+
         account = createAccountWithPaymentMethod(getAccountData(25));
         assertNotNull(account);
-        
-        PaymentMethodPlugin info = new PaymentMethodPlugin() {
+
+        final PaymentMethodPlugin info = new PaymentMethodPlugin() {
             @Override
             public boolean isDefaultPaymentMethod() {
                 return false;
             }
+
             @Override
-            public String getValueString(String key) {
+            public String getValueString(final String key) {
                 return null;
             }
+
             @Override
             public List<PaymentMethodKVInfo> getProperties() {
                 return null;
             }
+
             @Override
             public String getExternalPaymentMethodId() {
                 return UUID.randomUUID().toString();
@@ -180,30 +183,30 @@ public class TestOverdueIntegration extends TestIntegrationBase {
     }
 
     @AfterMethod
-    public void cleanup(){
+    public void cleanup() {
         // Clear databases
     }
 
-    @Test(groups={"slow"}, enabled = true)
+    @Test(groups = {"slow"}, enabled = true)
     public void testBasicOverdueState() throws Exception {
         clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
         paymentPlugin.makeAllInvoicesFailWithError(true);
-        
+
         // set next invoice to fail and create subscription 
         busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE);
-        SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+        final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
         busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
         clock.addDays(30); // DAY 30 have to get out of trial before first payment
-        
+
         assertTrue(busHandler.isCompleted(DELAY));
-        
+
         // should still be in clear state
         checkODState(BlockingApi.CLEAR_STATE_NAME);
-    
+
         clock.addDays(15); // DAY 45 - 15 days after invoice
         assertTrue(busHandler.isCompleted(DELAY));
         //should still be in clear state
@@ -212,10 +215,10 @@ public class TestOverdueIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
         clock.addDays(20); // DAY 65 - 35 days after invoice
         assertTrue(busHandler.isCompleted(DELAY));
-        
+
         //Now we should be in OD1
         checkODState("OD1");
-          
+
         clock.addDays(2); //DAY 67 - 37 days after invoice
         assertTrue(busHandler.isCompleted(DELAY));
         // should still be in OD1
@@ -226,41 +229,41 @@ public class TestOverdueIntegration extends TestIntegrationBase {
         assertTrue(busHandler.isCompleted(DELAY));
         // should still be in OD1
         checkODState("OD2");
-        
+
         busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
         clock.addDays(10); //DAY 85 - 55 days after invoice
         assertTrue(busHandler.isCompleted(DELAY));
         // should now be in OD2 state once the update is processed
         checkODState("OD3");
-        
+
         paymentPlugin.makeAllInvoicesFailWithError(false);
-        Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCNow());
-        List<String> invoiceIds = new ArrayList<String>();
-        for (Invoice invoice : invoices) {
-            invoiceIds.add(invoice.getId().toString()); 
+        final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCNow());
+        final List<String> invoiceIds = new ArrayList<String>();
+        for (final Invoice invoice : invoices) {
+            invoiceIds.add(invoice.getId().toString());
             if (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) {
                 busHandler.pushExpectedEvent(NextEvent.PAYMENT);
                 paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), new DefaultCallContext("test", null, null, clock));
                 assertTrue(busHandler.isCompleted(DELAY));
             }
         }
-        
+
         checkODState(BlockingApi.CLEAR_STATE_NAME);
 
     }
 
     private void checkODState(final String expected) {
-        
+
         try {
             await().atMost(10, SECONDS).until(new Callable<Boolean>() {
                 @Override
                 public Boolean call() throws Exception {
-                    overdueApi.refreshOverdueStateFor(bundle); 
-                    return expected.equals(blockingApi.getBlockingStateFor(bundle).getStateName()) ;
+                    overdueApi.refreshOverdueStateFor(bundle);
+                    return expected.equals(blockingApi.getBlockingStateFor(bundle).getStateName());
                 }
             });
         } catch (Exception e) {
-           Assert.assertEquals(blockingApi.getBlockingStateFor(bundle).getStateName(), expected);
+            Assert.assertEquals(blockingApi.getBlockingStateFor(bundle).getStateName(), expected);
         }
     }
 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java
new file mode 100644
index 0000000..9dadb9e
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestAnalytics.java
@@ -0,0 +1,322 @@
+/*
+ * 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.beatrix.integration;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.AccountData;
+import com.ning.billing.account.api.MutableAccountData;
+import com.ning.billing.analytics.model.BusinessAccount;
+import com.ning.billing.analytics.model.BusinessAccountTag;
+import com.ning.billing.analytics.model.BusinessInvoice;
+import com.ning.billing.analytics.model.BusinessInvoiceItem;
+import com.ning.billing.analytics.model.BusinessSubscriptionEvent;
+import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
+import com.ning.billing.analytics.utils.Rounder;
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.catalog.api.PlanPhaseSpecifier;
+import com.ning.billing.catalog.api.PriceListSet;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.util.api.TagApiException;
+import com.ning.billing.util.api.TagDefinitionApiException;
+import com.ning.billing.util.dao.ObjectType;
+import com.ning.billing.util.tag.TagDefinition;
+
+@Guice(modules = BeatrixModule.class)
+public class TestAnalytics extends TestIntegrationBase {
+    @BeforeMethod(groups = "slow")
+    public void setUpAnalyticsHandler() throws Exception {
+        busService.getBus().register(analyticsListener);
+    }
+
+    @AfterMethod(groups = "slow")
+    public void tearDownAnalyticsHandler() throws Exception {
+        busService.getBus().unregister(analyticsListener);
+    }
+
+    @Test(groups = "slow")
+    public void testAnalyticsEvents() throws Exception {
+        // Create an account
+        final Account account = verifyAccountCreation();
+
+        // Update some fields
+        verifyAccountUpdate(account);
+
+        // Add a tag
+        verifyAddTagToAccount(account);
+
+        // Create a bundle
+        final SubscriptionBundle bundle = verifyFirstBundle(account);
+
+        // Add a subscription
+        final Subscription subscription = verifyFirstSubscription(account, bundle);
+
+        // Upgrade the subscription
+        verifyChangePlan(account, bundle, subscription);
+    }
+
+    private Account verifyAccountCreation() throws Exception {
+        final AccountData accountData = getAccountData(1);
+
+        // Verify BAC is empty
+        Assert.assertNull(analyticsUserApi.getAccountByKey(accountData.getExternalKey()));
+
+        // Create an account
+        final Account account = createAccountWithPaymentMethod(accountData);
+        Assert.assertNotNull(account);
+
+        waitALittle();
+
+        // Verify Analytics got the account creation event
+        final BusinessAccount businessAccount = analyticsUserApi.getAccountByKey(account.getExternalKey());
+        Assert.assertNotNull(businessAccount);
+        // No balance yet
+        Assert.assertEquals(businessAccount.getBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
+        Assert.assertEquals(businessAccount.getKey(), account.getExternalKey());
+        // No invoice yet
+        Assert.assertNull(businessAccount.getLastInvoiceDate());
+        // No payment yet
+        Assert.assertNull(businessAccount.getLastPaymentStatus());
+        Assert.assertEquals(businessAccount.getName(), account.getName());
+        // No invoice balance yet
+        Assert.assertEquals(businessAccount.getTotalInvoiceBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
+        // TODO - payment fields
+        //Assert.assertNotNull(businessAccount.getBillingAddressCountry());
+        //Assert.assertNotNull(businessAccount.getCreditCardType());
+        //Assert.assertNotNull(businessAccount.getPaymentMethod());
+
+        // The account shouldn't have any invoice yet
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).size(), 0);
+
+        return account;
+    }
+
+    private void verifyAccountUpdate(final Account account) throws InterruptedException {
+        final MutableAccountData mutableAccountData = account.toMutableAccountData();
+
+        mutableAccountData.setName(UUID.randomUUID().toString().substring(0, 20));
+
+        try {
+            accountUserApi.updateAccount(account.getId(), mutableAccountData, context);
+        } catch (AccountApiException e) {
+            Assert.fail("Unable to update account", e);
+        }
+
+        waitALittle();
+
+        // Verify Analytics got the account update event
+        final BusinessAccount businessAccount = analyticsUserApi.getAccountByKey(mutableAccountData.getExternalKey());
+        Assert.assertNotNull(businessAccount);
+        // No balance yet
+        Assert.assertEquals(businessAccount.getBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
+        Assert.assertEquals(businessAccount.getKey(), mutableAccountData.getExternalKey());
+        // No invoice yet
+        Assert.assertNull(businessAccount.getLastInvoiceDate());
+        // No payment yet
+        Assert.assertNull(businessAccount.getLastPaymentStatus());
+        Assert.assertEquals(businessAccount.getName(), mutableAccountData.getName());
+        // No invoice balance yet
+        Assert.assertEquals(businessAccount.getTotalInvoiceBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
+        // TODO - payment fields
+        //Assert.assertNotNull(businessAccount.getBillingAddressCountry());
+        //Assert.assertNotNull(businessAccount.getCreditCardType());
+        //Assert.assertNotNull(businessAccount.getPaymentMethod());
+
+        // The account should still not have any invoice
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).size(), 0);
+    }
+
+    private void verifyAddTagToAccount(final Account account) throws TagDefinitionApiException, TagApiException, InterruptedException {
+        Assert.assertEquals(analyticsUserApi.getTagsForAccount(account.getExternalKey()).size(), 0);
+
+        final TagDefinition tagDefinition = tagUserApi.create(UUID.randomUUID().toString().substring(0, 10), UUID.randomUUID().toString(), context);
+        tagUserApi.addTag(account.getId(), ObjectType.ACCOUNT, tagDefinition, context);
+
+        waitALittle();
+
+        final List<BusinessAccountTag> tagsForAccount = analyticsUserApi.getTagsForAccount(account.getExternalKey());
+        Assert.assertEquals(tagsForAccount.size(), 1);
+        Assert.assertEquals(tagsForAccount.get(0).getName(), tagDefinition.getName());
+    }
+
+    private SubscriptionBundle verifyFirstBundle(final Account account) throws EntitlementUserApiException, InterruptedException {
+        // Add a bundle
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), UUID.randomUUID().toString(), context);
+        Assert.assertNotNull(bundle);
+
+        waitALittle();
+
+        // Verify BST is still empty since no subscription has been added yet
+        Assert.assertEquals(analyticsUserApi.getTransitionsForBundle(bundle.getKey()).size(), 0);
+
+        // The account should still not have any invoice
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).size(), 0);
+
+        return bundle;
+    }
+
+    private Subscription verifyFirstSubscription(final Account account, final SubscriptionBundle bundle) throws EntitlementUserApiException, InterruptedException, CatalogApiException {
+        // Add a subscription
+        final String productName = "Shotgun";
+        final BillingPeriod term = BillingPeriod.MONTHLY;
+        final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+        final PlanPhaseSpecifier phaseSpecifier = new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null);
+        final Subscription subscription = entitlementUserApi.createSubscription(bundle.getId(), phaseSpecifier, null, context);
+
+        waitALittle();
+
+        // BST should have one transition
+        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey());
+        Assert.assertEquals(transitions.size(), 1);
+        final BusinessSubscriptionTransition transition = transitions.get(0);
+        Assert.assertEquals(transition.getExternalKey(), bundle.getKey());
+        Assert.assertEquals(transition.getAccountKey(), account.getExternalKey());
+        Assert.assertEquals(transition.getEvent().getCategory(), phaseSpecifier.getProductCategory());
+        Assert.assertEquals(transition.getEvent().getEventType(), BusinessSubscriptionEvent.EventType.ADD);
+
+        // This is the first transition
+        Assert.assertNull(transition.getPreviousSubscription());
+
+        Assert.assertEquals(transition.getNextSubscription().getBillingPeriod(), subscription.getCurrentPhase().getBillingPeriod().toString());
+        Assert.assertEquals(transition.getNextSubscription().getBundleId(), subscription.getBundleId());
+        Assert.assertEquals(transition.getNextSubscription().getCurrency(), account.getCurrency().toString());
+        Assert.assertEquals(transition.getNextSubscription().getPhase(), subscription.getCurrentPhase().getPhaseType().toString());
+        // Trial: fixed price of zero
+        Assert.assertEquals(transition.getNextSubscription().getPrice().doubleValue(), subscription.getCurrentPhase().getFixedPrice().getPrice(account.getCurrency()).doubleValue());
+        Assert.assertEquals(transition.getNextSubscription().getPriceList(), subscription.getCurrentPriceList().getName());
+        Assert.assertEquals(transition.getNextSubscription().getProductCategory(), subscription.getCurrentPlan().getProduct().getCategory());
+        Assert.assertEquals(transition.getNextSubscription().getProductName(), subscription.getCurrentPlan().getProduct().getName());
+        Assert.assertEquals(transition.getNextSubscription().getProductType(), subscription.getCurrentPlan().getProduct().getCatalogName());
+        Assert.assertEquals(transition.getNextSubscription().getSlug(), subscription.getCurrentPhase().getName());
+        Assert.assertEquals(transition.getNextSubscription().getStartDate(), subscription.getStartDate());
+        Assert.assertEquals(transition.getNextSubscription().getState(), subscription.getState());
+        Assert.assertEquals(transition.getNextSubscription().getSubscriptionId(), subscription.getId());
+
+        // Make sure the account balance is still zero
+        final BusinessAccount businessAccount = analyticsUserApi.getAccountByKey(account.getExternalKey());
+        Assert.assertEquals(businessAccount.getBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
+        Assert.assertEquals(businessAccount.getTotalInvoiceBalance().doubleValue(), Rounder.round(BigDecimal.ZERO));
+
+        // The account should have one invoice for the trial phase
+        final List<BusinessInvoice> invoices = analyticsUserApi.getInvoicesForAccount(account.getExternalKey());
+        Assert.assertEquals(invoices.size(), 1);
+        final BusinessInvoice invoice = invoices.get(0);
+        Assert.assertEquals(invoice.getBalance().doubleValue(), 0.0);
+        Assert.assertEquals(invoice.getAmountCharged().doubleValue(), 0.0);
+        Assert.assertEquals(invoice.getAmountCredited().doubleValue(), 0.0);
+        Assert.assertEquals(invoice.getAmountPaid().doubleValue(), 0.0);
+        Assert.assertEquals(invoice.getCurrency(), account.getCurrency());
+
+        // The invoice should have a single item associated to it
+        final List<BusinessInvoiceItem> invoiceItems = analyticsUserApi.getInvoiceItemsForInvoice(invoice.getInvoiceId());
+        Assert.assertEquals(invoiceItems.size(), 1);
+        final BusinessInvoiceItem invoiceItem = invoiceItems.get(0);
+        Assert.assertEquals(invoiceItem.getAmount().doubleValue(), 0.0);
+        // No billing period for the trial item
+        Assert.assertEquals(invoiceItem.getBillingPeriod(), subscription.getCurrentPhase().getBillingPeriod().toString());
+        Assert.assertEquals(invoiceItem.getCurrency(), account.getCurrency());
+        // The subscription end date is null (evergreen)
+        Assert.assertEquals(invoiceItem.getEndDate(), subscription.getStartDate().plus(subscription.getCurrentPhase().getDuration().toJodaPeriod()));
+        Assert.assertEquals(invoiceItem.getExternalKey(), bundle.getKey());
+        Assert.assertEquals(invoiceItem.getInvoiceId(), invoice.getInvoiceId());
+        Assert.assertEquals(invoiceItem.getItemType(), "FIXED");
+        Assert.assertEquals(invoiceItem.getPhase(), subscription.getCurrentPhase().getPhaseType().toString());
+        Assert.assertEquals(invoiceItem.getProductCategory(), subscription.getCurrentPlan().getProduct().getCategory().toString());
+        Assert.assertEquals(invoiceItem.getProductName(), subscription.getCurrentPlan().getProduct().getName());
+        Assert.assertEquals(invoiceItem.getProductType(), subscription.getCurrentPlan().getProduct().getCatalogName());
+        Assert.assertEquals(invoiceItem.getSlug(), subscription.getCurrentPhase().getName());
+        Assert.assertEquals(invoiceItem.getStartDate(), subscription.getStartDate());
+
+        return subscription;
+    }
+
+    private void verifyChangePlan(final Account account, final SubscriptionBundle bundle, final Subscription subscription) throws EntitlementUserApiException, InterruptedException {
+        final String newProductName = "Assault-Rifle";
+        final BillingPeriod newTerm = BillingPeriod.MONTHLY;
+        final String newPlanSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+        final DateTime requestedDate = clock.getUTCNow();
+        Assert.assertTrue(subscription.changePlan(newProductName, newTerm, newPlanSetName, requestedDate, context));
+
+        waitALittle();
+
+        // BST should have two transitions
+        final List<BusinessSubscriptionTransition> transitions = analyticsUserApi.getTransitionsForBundle(bundle.getKey());
+        Assert.assertEquals(transitions.size(), 2);
+        final BusinessSubscriptionTransition previousTransition = transitions.get(0);
+        final BusinessSubscriptionTransition transition = transitions.get(1);
+        Assert.assertEquals(transition.getExternalKey(), bundle.getKey());
+        Assert.assertEquals(transition.getAccountKey(), account.getExternalKey());
+        Assert.assertEquals(transition.getEvent().getCategory(), ProductCategory.BASE);
+        Assert.assertEquals(transition.getEvent().getEventType(), BusinessSubscriptionEvent.EventType.CHANGE);
+
+        // Verify the previous subscription matches
+        Assert.assertNull(previousTransition.getPreviousSubscription());
+        Assert.assertEquals(previousTransition.getNextSubscription(), transition.getPreviousSubscription());
+
+        // Verify the next subscription
+        // No billing period for the trial phase
+        Assert.assertEquals(transition.getNextSubscription().getBillingPeriod(), BillingPeriod.NO_BILLING_PERIOD.toString());
+        Assert.assertEquals(transition.getNextSubscription().getBundleId(), subscription.getBundleId());
+        Assert.assertEquals(transition.getNextSubscription().getCurrency(), account.getCurrency().toString());
+        Assert.assertEquals(transition.getNextSubscription().getPhase(), PhaseType.TRIAL.toString());
+        // We're still in trial
+        Assert.assertEquals(transition.getNextSubscription().getPrice().doubleValue(), 0.0);
+        Assert.assertEquals(transition.getNextSubscription().getPriceList(), newPlanSetName);
+        Assert.assertEquals(transition.getNextSubscription().getProductCategory(), ProductCategory.BASE);
+        Assert.assertEquals(transition.getNextSubscription().getProductName(), newProductName);
+        Assert.assertEquals(transition.getNextSubscription().getProductType(), subscription.getCurrentPlan().getProduct().getCatalogName());
+        Assert.assertEquals(transition.getNextSubscription().getSlug(), subscription.getCurrentPhase().getName());
+        Assert.assertEquals(transition.getNextSubscription().getStartDate(), requestedDate);
+        Assert.assertEquals(transition.getNextSubscription().getState(), Subscription.SubscriptionState.ACTIVE);
+        // It's still the same subscription
+        Assert.assertEquals(transition.getNextSubscription().getSubscriptionId(), subscription.getId());
+
+        // The account should have two invoices for the trial phase of both subscriptions
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).size(), 2);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(0).getBalance().doubleValue(), 0.0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(0).getAmountCharged().doubleValue(), 0.0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(0).getAmountCredited().doubleValue(), 0.0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(0).getAmountPaid().doubleValue(), 0.0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(0).getCurrency(), account.getCurrency());
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getBalance().doubleValue(), 0.0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getAmountCharged().doubleValue(), 0.0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getAmountCredited().doubleValue(), 0.0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getAmountPaid().doubleValue(), 0.0);
+        Assert.assertEquals(analyticsUserApi.getInvoicesForAccount(account.getExternalKey()).get(1).getCurrency(), account.getCurrency());
+    }
+
+    private void waitALittle() throws InterruptedException {
+        // We especially need to wait for entitlement events
+        Thread.sleep(2000);
+    }
+}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
index 060ea97..15910a3 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.beatrix.integration;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
@@ -41,34 +37,38 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.invoice.api.Invoice;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 @Test(groups = "slow")
 @Guice(modules = {BeatrixModule.class})
 public class TestIntegration extends TestIntegrationBase {
     @Test(groups = "slow", enabled = true)
     public void testBasePlanCompleteWithBillingDayInPast() throws Exception {
         log.info("Starting testBasePlanCompleteWithBillingDayInPast");
-        DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
+        final DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
         testBasePlanComplete(startDate, 31, false);
     }
 
     @Test(groups = "slow", enabled = true)
     public void testBasePlanCompleteWithBillingDayPresent() throws Exception {
         log.info("Starting testBasePlanCompleteWithBillingDayPresent");
-        DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
+        final DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
         testBasePlanComplete(startDate, 1, false);
     }
 
     @Test(groups = "slow", enabled = true)
     public void testBasePlanCompleteWithBillingDayAlignedWithTrial() throws Exception {
         log.info("Starting testBasePlanCompleteWithBillingDayAlignedWithTrial");
-        DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
+        final DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
         testBasePlanComplete(startDate, 2, false);
     }
 
     @Test(groups = "slow", enabled = true)
     public void testBasePlanCompleteWithBillingDayInFuture() throws Exception {
         log.info("Starting testBasePlanCompleteWithBillingDayInFuture");
-        DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
+        final DateTime startDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
         testBasePlanComplete(startDate, 3, true);
     }
 
@@ -91,7 +91,7 @@ public class TestIntegration extends TestIntegrationBase {
             testBasePlanCompleteWithBillingDayInFuture();
         }
     }
-    
+
 
 //    // STEPH set to disabled until test written properly and fixed
 //    @Test(groups = "slow", enabled = true)
@@ -150,35 +150,35 @@ public class TestIntegration extends TestIntegrationBase {
 //        
 //        assertListenerStatus();
 //    }
-   
+
     // STEPH set to disabled until test written properly and fixed
     @Test(groups = "slow", enabled = false)
     public void testRepairChangeBPWithAddonIncluded() throws Exception {
-        
+
         log.info("Starting testRepairChangeBPWithAddonIncluded");
-        
-        DateTime initialDate = new DateTime(2012, 4, 25, 0, 13, 42, 0);
+
+        final DateTime initialDate = new DateTime(2012, 4, 25, 0, 13, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
-        
-        Account account = createAccountWithPaymentMethod(getAccountData(25));
+
+        final Account account = createAccountWithPaymentMethod(getAccountData(25));
         assertNotNull(account);
 
-        SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
 
-        String productName = "Shotgun";
-        BillingPeriod term = BillingPeriod.MONTHLY;
-        String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+        final String productName = "Shotgun";
+        final BillingPeriod term = BillingPeriod.MONTHLY;
+        final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
-        SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+        final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-   
+
         // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
-        Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
+        final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
         log.info("Moving clock from" + clock.getUTCNow() + " to " + clock.getUTCNow().plusDays(3));
         clock.addDays(3);
 
@@ -186,22 +186,22 @@ public class TestIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context));
+                                                                               new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context));
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
-        
+
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-        SubscriptionData aoSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context)); 
+        final SubscriptionData aoSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+                                                                                                                  new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context));
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
         // MOVE CLOCK A LITTLE BIT MORE -- EITHER STAY IN TRIAL OR GET OUT   
         busHandler.pushExpectedEvent(NextEvent.PHASE);
-        busHandler.pushExpectedEvent(NextEvent.PHASE);          
+        busHandler.pushExpectedEvent(NextEvent.PHASE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
@@ -210,67 +210,66 @@ public class TestIntegration extends TestIntegrationBase {
         clock.addDays(28);// 26 / 5
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-        
-        
-        busHandler.pushExpectedEvent(NextEvent.PHASE);       
+
+
+        busHandler.pushExpectedEvent(NextEvent.PHASE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         log.info("Moving clock from" + clock.getUTCNow() + " to " + clock.getUTCNow().plusDays(3));
         clock.addDays(3);// 29 / 5
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-       
-        
+
+
         log.info("Moving clock from" + clock.getUTCNow() + " to " + clock.getUTCNow().plusDays(10));
         clock.addDays(10);// 8 / 6
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-       
-        
-       
+
+
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         log.info("Moving clock from" + clock.getUTCNow() + " to " + clock.getUTCNow().plusDays(18));
         clock.addDays(18);// 26 / 6
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-        
+
         log.info("Moving clock from" + clock.getUTCNow() + " to " + clock.getUTCNow().plusDays(3));
         clock.addDays(3);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
-        
+
 
     }
-    
-    
+
+
     @Test(groups = {"slow"})
     public void testRepairForInvoicing() throws Exception {
 
         log.info("Starting testRepairForInvoicing");
 
-        Account account = createAccountWithPaymentMethod(getAccountData(1));
-        UUID accountId = account.getId();
+        final Account account = createAccountWithPaymentMethod(getAccountData(1));
+        final UUID accountId = account.getId();
         assertNotNull(account);
 
-        DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
+        final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
 
-        SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "someBundle", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "someBundle", context);
         assertNotNull(bundle);
 
-        String productName = "Shotgun";
-        BillingPeriod term = BillingPeriod.MONTHLY;
-        String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+        final String productName = "Shotgun";
+        final BillingPeriod term = BillingPeriod.MONTHLY;
+        final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
         entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context);
+                                              new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context);
 
         busHandler.reset();
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
+        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
         assertEquals(invoices.size(), 1);
 
         // TODO: Jeff implement repair
@@ -281,17 +280,17 @@ public class TestIntegration extends TestIntegrationBase {
 
         log.info("Starting testWithRecreatePlan");
 
-        DateTime initialDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
-        int billingDay = 2;
+        final DateTime initialDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
+        final int billingDay = 2;
 
         log.info("Beginning test with BCD of " + billingDay);
-        Account account = createAccountWithPaymentMethod(getAccountData(billingDay));
-        UUID accountId = account.getId();
+        final Account account = createAccountWithPaymentMethod(getAccountData(billingDay));
+        final UUID accountId = account.getId();
         assertNotNull(account);
 
         // set clock to the initial start date
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
-        SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever2", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever2", context);
 
         String productName = "Shotgun";
         BillingPeriod term = BillingPeriod.MONTHLY;
@@ -302,20 +301,20 @@ public class TestIntegration extends TestIntegrationBase {
         //
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
-        
+
         SubscriptionData subscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
-        
+                                                                                                               new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+
         assertNotNull(subscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
         //
         // VERIFY CTD HAS BEEN SET
         //
-        DateTime startDate = subscription.getCurrentPhaseStart();
+        final DateTime startDate = subscription.getCurrentPhaseStart();
         DateTime endDate = startDate.plusDays(30);
-        BigDecimal rate = subscription.getCurrentPhase().getFixedPrice().getPrice(Currency.USD);
-        int invoiceItemCount = 1;
+        final BigDecimal rate = subscription.getCurrentPhase().getFixedPrice().getPrice(Currency.USD);
+        final int invoiceItemCount = 1;
         verifyTestResult(accountId, subscription.getId(), startDate, endDate, rate, endDate, invoiceItemCount);
 
         //
@@ -333,7 +332,7 @@ public class TestIntegration extends TestIntegrationBase {
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         busHandler.pushExpectedEvent(NextEvent.CANCEL);
         endDate = subscription.getChargedThroughDate();
-        Interval it = new Interval(clock.getUTCNow(), endDate);
+        final Interval it = new Interval(clock.getUTCNow(), endDate);
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(busHandler.isCompleted(DELAY));
 
@@ -349,21 +348,21 @@ public class TestIntegration extends TestIntegrationBase {
 
         assertListenerStatus();
     }
-     
-    private void testBasePlanComplete(DateTime initialCreationDate, int billingDay,
-                                      boolean proRationExpected) throws Exception {
+
+    private void testBasePlanComplete(final DateTime initialCreationDate, final int billingDay,
+                                      final boolean proRationExpected) throws Exception {
 
         log.info("Beginning test with BCD of " + billingDay);
-        Account account = createAccountWithPaymentMethod(getAccountData(billingDay));
-        UUID accountId = account.getId();
-        
+        final Account account = createAccountWithPaymentMethod(getAccountData(billingDay));
+        final UUID accountId = account.getId();
+
         // set clock to the initial start date
         clock.setDeltaFromReality(initialCreationDate.getMillis() - clock.getUTCNow().getMillis());
-        SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
 
-        String productName = "Shotgun";
-        BillingPeriod term = BillingPeriod.MONTHLY;
-        String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+        final String productName = "Shotgun";
+        final BillingPeriod term = BillingPeriod.MONTHLY;
+        final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
         //
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
@@ -371,7 +370,7 @@ public class TestIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         SubscriptionData subscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+                                                                                                               new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
         assertNotNull(subscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
@@ -428,7 +427,7 @@ public class TestIntegration extends TestIntegrationBase {
         startDate = subscription.getCurrentPhaseStart();
         rate = subscription.getCurrentPhase().getRecurringPrice().getPrice(Currency.USD);
         BigDecimal price;
-        DateTime chargeThroughDate;
+        final DateTime chargeThroughDate;
 
         switch (billingDay) {
             case 1:
@@ -448,7 +447,7 @@ public class TestIntegration extends TestIntegrationBase {
             case 3:
                 // this will result in a 1-day leading pro-ration and a full-period invoice item
                 price = ONE.divide(TWENTY_NINE, 2 * NUMBER_OF_DECIMALS, ROUNDING_METHOD).multiply(rate).setScale(NUMBER_OF_DECIMALS, ROUNDING_METHOD);
-                DateTime firstEndDate = startDate.plusDays(1);
+                final DateTime firstEndDate = startDate.plusDays(1);
                 chargeThroughDate = firstEndDate.plusMonths(1);
                 invoiceItemCount += 2;
                 verifyTestResult(accountId, subscription.getId(), startDate, firstEndDate, price, chargeThroughDate, invoiceItemCount);
@@ -507,8 +506,8 @@ public class TestIntegration extends TestIntegrationBase {
             endDate = startDate.plusMonths(1);
             if (endDate.dayOfMonth().get() != billingDay) {
                 // adjust for end of month issues
-                int maximumDay = endDate.dayOfMonth().getMaximumValue();
-                int newDay = (maximumDay < billingDay) ? maximumDay : billingDay;
+                final int maximumDay = endDate.dayOfMonth().getMaximumValue();
+                final int newDay = (maximumDay < billingDay) ? maximumDay : billingDay;
                 endDate = endDate.toMutableDateTime().dayOfMonth().set(newDay).toDateTime();
             }
 
@@ -524,7 +523,7 @@ public class TestIntegration extends TestIntegrationBase {
 
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         busHandler.pushExpectedEvent(NextEvent.CANCEL);
-        Interval it = new Interval(clock.getUTCNow(), endDate);
+        final Interval it = new Interval(clock.getUTCNow(), endDate);
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(busHandler.isCompleted(DELAY));
 
@@ -536,16 +535,16 @@ public class TestIntegration extends TestIntegrationBase {
         assertTrue(busHandler.isCompleted(DELAY));
 
         subscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(subscription.getId()));
-        DateTime lastCtd = subscription.getChargedThroughDate();
+        final DateTime lastCtd = subscription.getChargedThroughDate();
         assertNotNull(lastCtd);
         log.info("Checking CTD: " + lastCtd.toString() + "; clock is " + clock.getUTCNow().toString());
         assertTrue(lastCtd.isBefore(clock.getUTCNow()));
 
         // The invoice system is still working to verify there is nothing to do
         Thread.sleep(DELAY);
-        
+
         assertListenerStatus();
-        
+
         log.info("TEST PASSED !");
     }
 
@@ -554,66 +553,66 @@ public class TestIntegration extends TestIntegrationBase {
     public void testForMultipleRecurringPhases() throws Exception {
 
         log.info("Starting testForMultipleRecurringPhases");
-        
-        DateTime initialCreationDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
+
+        final DateTime initialCreationDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialCreationDate.getMillis() - clock.getUTCNow().getMillis());
 
-        Account account = createAccountWithPaymentMethod(getAccountData(2));
-        UUID accountId = account.getId();
+        final Account account = createAccountWithPaymentMethod(getAccountData(2));
+        final UUID accountId = account.getId();
 
-        String productName = "Blowdart";
-        String planSetName = "DEFAULT";
+        final String productName = "Blowdart";
+        final String planSetName = "DEFAULT";
 
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
-        SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(accountId, "testKey", context);
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(accountId, "testKey", context);
         subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                                        new PlanPhaseSpecifier(productName, ProductCategory.BASE,
-                                        BillingPeriod.MONTHLY, planSetName, PhaseType.TRIAL), null, context));
+                                                                               new PlanPhaseSpecifier(productName, ProductCategory.BASE,
+                                                                                                      BillingPeriod.MONTHLY, planSetName, PhaseType.TRIAL), null, context));
 
         assertTrue(busHandler.isCompleted(DELAY));
         List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
         assertNotNull(invoices);
         assertTrue(invoices.size() == 1);
-        
+
         busHandler.pushExpectedEvent(NextEvent.PHASE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         clock.addDeltaFromReality(AT_LEAST_ONE_MONTH_MS);
-        assertTrue(busHandler.isCompleted(DELAY));           
+        assertTrue(busHandler.isCompleted(DELAY));
         invoices = invoiceUserApi.getInvoicesByAccount(accountId);
         assertNotNull(invoices);
-        assertEquals(invoices.size(),2);
-      
+        assertEquals(invoices.size(), 2);
+
         for (int i = 0; i < 5; i++) {
-            log.info("============== loop number " + i +"=======================");
+            log.info("============== loop number " + i + "=======================");
             busHandler.pushExpectedEvent(NextEvent.INVOICE);
             busHandler.pushExpectedEvent(NextEvent.PAYMENT);
             clock.addDeltaFromReality(AT_LEAST_ONE_MONTH_MS);
-            assertTrue(busHandler.isCompleted(DELAY));           
+            assertTrue(busHandler.isCompleted(DELAY));
         }
-        
+
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         busHandler.pushExpectedEvent(NextEvent.PHASE);
         clock.addDeltaFromReality(AT_LEAST_ONE_MONTH_MS);
-        assertTrue(busHandler.isCompleted(DELAY));           
- 
+        assertTrue(busHandler.isCompleted(DELAY));
+
         invoices = invoiceUserApi.getInvoicesByAccount(accountId);
         assertNotNull(invoices);
-        assertEquals(invoices.size(),8);
+        assertEquals(invoices.size(), 8);
 
         for (int i = 0; i <= 5; i++) {
-            log.info("============== second loop number " + i +"=======================");
+            log.info("============== second loop number " + i + "=======================");
             busHandler.pushExpectedEvent(NextEvent.INVOICE);
             busHandler.pushExpectedEvent(NextEvent.PAYMENT);
             clock.addDeltaFromReality(AT_LEAST_ONE_MONTH_MS);
-            assertTrue(busHandler.isCompleted(DELAY));           
+            assertTrue(busHandler.isCompleted(DELAY));
         }
-               
+
         invoices = invoiceUserApi.getInvoicesByAccount(accountId);
         assertNotNull(invoices);
-        assertEquals(invoices.size(),14);
+        assertEquals(invoices.size(), 14);
 
         assertListenerStatus();
     }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
index 99e5287..fbf4a68 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
@@ -15,19 +15,12 @@
  */
 package com.ning.billing.beatrix.integration;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.RandomStringUtils;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.IDBI;
@@ -44,6 +37,8 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountData;
 import com.ning.billing.account.api.AccountService;
 import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.analytics.AnalyticsListener;
+import com.ning.billing.analytics.api.user.DefaultAnalyticsUserApi;
 import com.ning.billing.api.TestApiListener;
 import com.ning.billing.api.TestListenerStatus;
 import com.ning.billing.beatrix.lifecycle.Lifecycle;
@@ -63,15 +58,21 @@ import com.ning.billing.invoice.model.InvoicingConfiguration;
 import com.ning.billing.junction.plumbing.api.BlockingSubscription;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentMethodPlugin;
+import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.io.IOUtils;
 
-public class TestIntegrationBase implements TestListenerStatus {
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
+public class TestIntegrationBase implements TestListenerStatus {
     protected static final int NUMBER_OF_DECIMALS = InvoicingConfiguration.getNumberOfDecimals();
     protected static final int ROUNDING_METHOD = InvoicingConfiguration.getRoundingMode();
 
@@ -81,7 +82,7 @@ public class TestIntegrationBase implements TestListenerStatus {
     protected static final BigDecimal THIRTY_ONE = new BigDecimal("31.0000").setScale(NUMBER_OF_DECIMALS);
 
     protected static final Logger log = LoggerFactory.getLogger(TestIntegration.class);
-    protected static long AT_LEAST_ONE_MONTH_MS =  31L * 24L * 3600L * 1000L;
+    protected static long AT_LEAST_ONE_MONTH_MS = 31L * 24L * 3600L * 1000L;
 
 
     protected static final long DELAY = 5000;
@@ -91,7 +92,7 @@ public class TestIntegrationBase implements TestListenerStatus {
 
     @Inject
     protected ClockMock clock;
-    
+
     protected CallContext context;
 
     @Inject
@@ -116,24 +117,33 @@ public class TestIntegrationBase implements TestListenerStatus {
 
     @Inject
     protected EntitlementTimelineApi repairApi;
-    
+
     @Inject
     protected InvoiceUserApi invoiceUserApi;
 
     @Inject
     protected PaymentApi paymentApi;
-    
+
     @Inject
     protected AccountUserApi accountUserApi;
 
+    @Inject
+    protected DefaultAnalyticsUserApi analyticsUserApi;
+
+    @Inject
+    protected TagUserApi tagUserApi;
+
+    @Inject
+    protected AnalyticsListener analyticsListener;
+
     protected TestApiListener busHandler;
 
-    
+
     private boolean isListenerFailed;
     private String listenerFailedMsg;
-    
+
     @Override
-    public void failed(String msg) {
+    public void failed(final String msg) {
         isListenerFailed = true;
         listenerFailedMsg = msg;
     }
@@ -144,7 +154,7 @@ public class TestIntegrationBase implements TestListenerStatus {
         listenerFailedMsg = null;
     }
 
-    
+
     protected void assertListenerStatus() {
         if (isListenerFailed) {
             log.error(listenerFailedMsg);
@@ -152,9 +162,9 @@ public class TestIntegrationBase implements TestListenerStatus {
         }
     }
 
-    protected void setupMySQL() throws IOException
-    {
+    protected void setupMySQL() throws IOException {
         final String accountDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
+        final String analyticsDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/analytics/ddl.sql"));
         final String entitlementDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
         final String invoiceDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
         final String paymentDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/payment/ddl.sql"));
@@ -164,6 +174,7 @@ public class TestIntegrationBase implements TestListenerStatus {
         helper.startMysql();
 
         helper.initDb(accountDdl);
+        helper.initDb(analyticsDdl);
         helper.initDb(entitlementDdl);
         helper.initDb(invoiceDdl);
         helper.initDb(paymentDdl);
@@ -171,15 +182,15 @@ public class TestIntegrationBase implements TestListenerStatus {
         helper.initDb(junctionDb);
     }
 
-  
+
     @BeforeClass(groups = "slow")
-    public void setup() throws Exception{
+    public void setup() throws Exception {
 
         setupMySQL();
-        
+
         context = new DefaultCallContextFactory(clock).createCallContext("Integration Test", CallOrigin.TEST, UserType.TEST);
         busHandler = new TestApiListener(this);
-        
+
     }
 
     @AfterClass(groups = "slow")
@@ -193,13 +204,13 @@ public class TestIntegrationBase implements TestListenerStatus {
 
         log.warn("\n");
         log.warn("RESET TEST FRAMEWORK\n\n");
-        
+
         // Pre test cleanup
         helper.cleanupAllTables();
 
         clock.resetDeltaFromReality();
         resetTestListenerStatus();
-        
+
         // Start services
         lifecycle.fireStartupSequencePriorEventRegistration();
         busService.getBus().register(busHandler);
@@ -214,24 +225,24 @@ public class TestIntegrationBase implements TestListenerStatus {
 
         log.warn("DONE WITH TEST\n");
     }
-    
 
-    protected void verifyTestResult(UUID accountId, UUID subscriptionId,
-                                  DateTime startDate, DateTime endDate,
-                                  BigDecimal amount, DateTime chargeThroughDate,
-                                  int totalInvoiceItemCount) throws EntitlementUserApiException {
-        SubscriptionData subscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(subscriptionId));
 
-        List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
-        List<InvoiceItem> invoiceItems = new ArrayList<InvoiceItem>();
-        for (Invoice invoice : invoices) {
+    protected void verifyTestResult(final UUID accountId, final UUID subscriptionId,
+                                    final DateTime startDate, final DateTime endDate,
+                                    final BigDecimal amount, final DateTime chargeThroughDate,
+                                    final int totalInvoiceItemCount) throws EntitlementUserApiException {
+        final SubscriptionData subscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(subscriptionId));
+
+        final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(accountId);
+        final List<InvoiceItem> invoiceItems = new ArrayList<InvoiceItem>();
+        for (final Invoice invoice : invoices) {
             invoiceItems.addAll(invoice.getInvoiceItems());
         }
         assertEquals(invoiceItems.size(), totalInvoiceItemCount);
 
         boolean wasFound = false;
 
-        for (InvoiceItem item : invoiceItems) {
+        for (final InvoiceItem item : invoiceItems) {
             if (item.getStartDate().compareTo(startDate) == 0) {
                 if (item.getEndDate().compareTo(endDate) == 0) {
                     if (item.getAmount().compareTo(amount) == 0) {
@@ -246,34 +257,37 @@ public class TestIntegrationBase implements TestListenerStatus {
             fail();
         }
 
-        DateTime ctd = subscription.getChargedThroughDate();
+        final DateTime ctd = subscription.getChargedThroughDate();
         assertNotNull(ctd);
         log.info("Checking CTD: " + ctd.toString() + "; clock is " + clock.getUTCNow().toString());
         assertTrue(clock.getUTCNow().isBefore(ctd));
         assertTrue(ctd.compareTo(chargeThroughDate) == 0);
     }
-       
-    protected SubscriptionData subscriptionDataFromSubscription(Subscription sub) {
-        return (SubscriptionData)((BlockingSubscription)sub).getDelegateSubscription();
+
+    protected SubscriptionData subscriptionDataFromSubscription(final Subscription sub) {
+        return (SubscriptionData) ((BlockingSubscription) sub).getDelegateSubscription();
     }
-    
-    protected Account createAccountWithPaymentMethod(AccountData accountData) throws Exception {
-        Account account = accountUserApi.createAccount(accountData, context);
+
+    protected Account createAccountWithPaymentMethod(final AccountData accountData) throws Exception {
+        final Account account = accountUserApi.createAccount(accountData, context);
         assertNotNull(account);
-        
-        PaymentMethodPlugin info = new PaymentMethodPlugin() {
+
+        final PaymentMethodPlugin info = new PaymentMethodPlugin() {
             @Override
             public boolean isDefaultPaymentMethod() {
                 return false;
             }
+
             @Override
-            public String getValueString(String key) {
+            public String getValueString(final String key) {
                 return null;
             }
+
             @Override
             public List<PaymentMethodKVInfo> getProperties() {
                 return null;
             }
+
             @Override
             public String getExternalPaymentMethodId() {
                 return UUID.randomUUID().toString();
@@ -283,35 +297,37 @@ public class TestIntegrationBase implements TestListenerStatus {
         return accountUserApi.getAccountById(account.getId());
     }
 
-    
-    protected AccountData getAccountData(final int billingDay) {
 
-        final String someRandomKey = RandomStringUtils.randomAlphanumeric(10);
+    protected AccountData getAccountData(final int billingDay) {
+        final String someRandomKey = UUID.randomUUID().toString();
         return new AccountData() {
             @Override
             public String getName() {
                 return "firstName lastName";
             }
+
             @Override
-            public int getFirstNameLength() {
+            public Integer getFirstNameLength() {
                 return "firstName".length();
             }
+
             @Override
             public String getEmail() {
-                return  someRandomKey + "@laposte.fr";
+                return someRandomKey + "@laposte.fr";
             }
+
             @Override
             public String getPhone() {
                 return "4152876341";
             }
 
             @Override
-            public boolean isMigrated() {
+            public Boolean isMigrated() {
                 return false;
             }
 
             @Override
-            public boolean isNotifiedForInvoices() {
+            public Boolean isNotifiedForInvoices() {
                 return false;
             }
 
@@ -319,14 +335,17 @@ public class TestIntegrationBase implements TestListenerStatus {
             public String getExternalKey() {
                 return someRandomKey;
             }
+
             @Override
-            public int getBillCycleDay() {
+            public Integer getBillCycleDay() {
                 return billingDay;
             }
+
             @Override
             public Currency getCurrency() {
                 return Currency.USD;
             }
+
             @Override
             public UUID getPaymentMethodId() {
                 return null;
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
index 08ba27a..426bac7 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.beatrix.integration;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import java.util.Collection;
 import java.util.Map;
 import java.util.UUID;
@@ -48,6 +44,10 @@ import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.TagDefinition;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 @Guice(modules = {BeatrixModule.class})
 public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
 
@@ -65,7 +65,7 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
 
     @BeforeMethod(groups = {"slow"})
     public void setupOverdue() throws Exception {
-        
+
         account = createAccountWithPaymentMethod(getAccountData(25));
         assertNotNull(account);
 
@@ -76,51 +76,51 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
         planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
     }
 
-    @Test(groups={"slow"}, enabled = true)
+    @Test(groups = {"slow"}, enabled = true)
     public void testAutoInvoiceOffAccount() throws Exception {
         clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
         addTag(account.getId(), ObjectType.ACCOUNT);
-       
+
         // set next invoice to fail and create network 
         busHandler.pushExpectedEvents(NextEvent.CREATE);
-        SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+        final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
 
- 
-        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());       
+
+        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
         assertEquals(invoices.size(), 0);
- 
+
         clock.addDays(10); // DAY 10 still in trial
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());       
+        invoices = invoiceApi.getInvoicesByAccount(account.getId());
         assertEquals(invoices.size(), 0);
 
         busHandler.pushExpectedEvents(NextEvent.PHASE);
         clock.addDays(30); // DAY 40 out of trial
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());       
+        invoices = invoiceApi.getInvoicesByAccount(account.getId());
         assertEquals(invoices.size(), 0);
 
     }
-    
-    @Test(groups={"slow"}, enabled = true)
+
+    @Test(groups = {"slow"}, enabled = true)
     public void testAutoInvoiceOffSingleSubscription() throws Exception {
         clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
-       
+
         // set next invoice to fail and create network 
-        busHandler.pushExpectedEvents(NextEvent.CREATE,NextEvent.INVOICE);
-        SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+        busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE);
+        final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
-        
-        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());       
+
+        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
         assertEquals(invoices.size(), 1); // first invoice is generated immediately after creation can't reliably stop it
- 
+
 
         addTag(baseSubscription.getBundleId(), ObjectType.BUNDLE);
 
@@ -128,49 +128,49 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
         clock.addDays(40); // DAY 40 out of trial
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());       
+        invoices = invoiceApi.getInvoicesByAccount(account.getId());
         assertEquals(invoices.size(), 1); //No additional invoices generated
 
     }
 
-    
-    @Test(groups={"slow"}, enabled = true)
+
+    @Test(groups = {"slow"}, enabled = true)
     public void testAutoInvoiceOffMultipleSubscriptions() throws Exception {
         clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
-       
+
         // set next invoice to fail and create network 
-        busHandler.pushExpectedEvents(NextEvent.CREATE,NextEvent.INVOICE);
-        SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+        busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE);
+        final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
- 
-        SubscriptionBundle bundle2 = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
 
-        busHandler.pushExpectedEvents(NextEvent.CREATE,NextEvent.INVOICE);
-        SubscriptionData baseSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle2.getId(),
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+        final SubscriptionBundle bundle2 = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+
+        busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE);
+        final SubscriptionData baseSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle2.getId(),
+                                                                                                                    new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
         assertNotNull(baseSubscription2);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());       
+        Collection<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
         assertEquals(invoices.size(), 2); // first invoice is generated immediately after creation can't reliably stop it
- 
+
         addTag(baseSubscription.getBundleId(), ObjectType.BUNDLE);
 
-        busHandler.pushExpectedEvents(NextEvent.PHASE,NextEvent.PHASE,NextEvent.INVOICE);
+        busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.PHASE, NextEvent.INVOICE);
         clock.addDays(40); // DAY 40 out of trial
         assertTrue(busHandler.isCompleted(DELAY));
 
-        invoices = invoiceApi.getInvoicesByAccount(account.getId());       
+        invoices = invoiceApi.getInvoicesByAccount(account.getId());
         assertEquals(invoices.size(), 3); // Only one additional invoice generated
     }
 
 
-    private void addTag(UUID id, ObjectType type) throws TagDefinitionApiException, TagApiException {
-        TagDefinition def = tagApi.getTagDefinition(ControlTagType.AUTO_INVOICING_OFF.name());
+    private void addTag(final UUID id, final ObjectType type) throws TagDefinitionApiException, TagApiException {
+        final TagDefinition def = tagApi.getTagDefinition(ControlTagType.AUTO_INVOICING_OFF.name());
         tagApi.addTag(id, type, def, context);
-        Map<String,Tag> tags = tagApi.getTags(id, type);
+        final Map<String, Tag> tags = tagApi.getTags(id, type);
         assertNotNull(tags.get(ControlTagType.AUTO_INVOICING_OFF.name()));
     }
 }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
index 4000606..ae3ecc3 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
@@ -15,10 +15,6 @@
  */
 package com.ning.billing.beatrix.integration;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.LinkedList;
@@ -44,48 +40,52 @@ import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.DeletedEvent;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.ExistingEvent;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.NewEvent;
+import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.api.user.SubscriptionEvents;
-import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
 
 @Test(groups = "slow")
 @Guice(modules = {BeatrixModule.class})
 public class TestRepairIntegration extends TestIntegrationBase {
 
-    
-    @Test(groups={"slow"}, enabled=false)
+
+    @Test(groups = {"slow"}, enabled = false)
     public void testRepairChangeBPWithAddonIncludedIntrial() throws Exception {
         log.info("Starting testRepairChangeBPWithAddonIncludedIntrial");
         testRepairChangeBPWithAddonIncluded(true);
     }
-    
-    @Test(groups={"slow"}, enabled=false)
+
+    @Test(groups = {"slow"}, enabled = false)
     public void testRepairChangeBPWithAddonIncludedOutOfTrial() throws Exception {
         log.info("Starting testRepairChangeBPWithAddonIncludedOutOfTrial");
         testRepairChangeBPWithAddonIncluded(false);
     }
-    
-    private void testRepairChangeBPWithAddonIncluded(boolean inTrial) throws Exception {
-        
-        DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
+
+    private void testRepairChangeBPWithAddonIncluded(final boolean inTrial) throws Exception {
+
+        final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
-        
-        Account account = createAccountWithPaymentMethod(getAccountData(25));
 
-        SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+        final Account account = createAccountWithPaymentMethod(getAccountData(25));
 
-        String productName = "Shotgun";
-        BillingPeriod term = BillingPeriod.MONTHLY;
-        String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+        final SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
+
+        final String productName = "Shotgun";
+        final BillingPeriod term = BillingPeriod.MONTHLY;
+        final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
-        SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
+        final SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+                                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
         assertNotNull(baseSubscription);
         assertTrue(busHandler.isCompleted(DELAY));
-   
+
         // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
         Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
         clock.addDeltaFromReality(it.toDurationMillis());
@@ -93,25 +93,25 @@ public class TestRepairIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-        SubscriptionData aoSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context));
+        final SubscriptionData aoSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+                                                                                                                 new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context));
         assertTrue(busHandler.isCompleted(DELAY));
-        
+
         busHandler.pushExpectedEvent(NextEvent.CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-        SubscriptionData aoSubscription2 = subscriptionDataFromSubscription( entitlementUserApi.createSubscription(bundle.getId(),
-                new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context)); 
+        final SubscriptionData aoSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
+                                                                                                                  new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null, context));
         assertTrue(busHandler.isCompleted(DELAY));
-        
+
 
         // MOVE CLOCK A LITTLE BIT MORE -- EITHER STAY IN TRIAL OR GET OUT   
-        int duration = inTrial ? 3 : 35;
+        final int duration = inTrial ? 3 : 35;
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(duration));
         if (!inTrial) {
             busHandler.pushExpectedEvent(NextEvent.PHASE);
             busHandler.pushExpectedEvent(NextEvent.PHASE);
-            busHandler.pushExpectedEvent(NextEvent.PHASE);            
+            busHandler.pushExpectedEvent(NextEvent.PHASE);
             busHandler.pushExpectedEvent(NextEvent.INVOICE);
             busHandler.pushExpectedEvent(NextEvent.PAYMENT);
         }
@@ -119,7 +119,7 @@ public class TestRepairIntegration extends TestIntegrationBase {
         if (!inTrial) {
             assertTrue(busHandler.isCompleted(DELAY));
         }
-        boolean ifRepair = false;
+        final boolean ifRepair = false;
         if (ifRepair) {
             BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
             sortEventsOnBundle(bundleRepair);
@@ -128,23 +128,23 @@ public class TestRepairIntegration extends TestIntegrationBase {
             SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
             assertEquals(bpRepair.getExistingEvents().size(), 2);
 
-            SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
+            final SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
             assertEquals(aoRepair.getExistingEvents().size(), 2);
 
-            SubscriptionTimeline aoRepair2 = getSubscriptionRepair(aoSubscription2.getId(), bundleRepair);
+            final SubscriptionTimeline aoRepair2 = getSubscriptionRepair(aoSubscription2.getId(), bundleRepair);
             assertEquals(aoRepair2.getExistingEvents().size(), 2);
 
-            DateTime bpChangeDate = clock.getUTCNow().minusDays(1);
+            final DateTime bpChangeDate = clock.getUTCNow().minusDays(1);
 
-            List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
-            des.add(createDeletedEvent(bpRepair.getExistingEvents().get(1).getEventId()));        
+            final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+            des.add(createDeletedEvent(bpRepair.getExistingEvents().get(1).getEventId()));
 
-            PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
-            NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, bpChangeDate, spec);
+            final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
+            final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, bpChangeDate, spec);
 
             bpRepair = createSubscriptionReapir(baseSubscription.getId(), des, Collections.singletonList(ne));
 
-            bundleRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
+            bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
 
             // TIME TO  REPAIR
             busHandler.pushExpectedEvent(NextEvent.INVOICE);
@@ -153,40 +153,43 @@ public class TestRepairIntegration extends TestIntegrationBase {
             repairApi.repairBundle(bundleRepair, false, context);
             assertTrue(busHandler.isCompleted(DELAY));
 
-            SubscriptionData newAoSubscription = subscriptionDataFromSubscription(  entitlementUserApi.getSubscriptionFromId(aoSubscription.getId()));
+            final SubscriptionData newAoSubscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(aoSubscription.getId()));
             assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
             assertEquals(newAoSubscription.getAllTransitions().size(), 2);
             assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
-            SubscriptionData newAoSubscription2 = subscriptionDataFromSubscription(  entitlementUserApi.getSubscriptionFromId(aoSubscription2.getId()));
+            final SubscriptionData newAoSubscription2 = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(aoSubscription2.getId()));
             assertEquals(newAoSubscription2.getState(), SubscriptionState.ACTIVE);
             assertEquals(newAoSubscription2.getAllTransitions().size(), 2);
             assertEquals(newAoSubscription2.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
 
-            SubscriptionData newBaseSubscription = subscriptionDataFromSubscription(  entitlementUserApi.getSubscriptionFromId(baseSubscription.getId()));
+            final SubscriptionData newBaseSubscription = subscriptionDataFromSubscription(entitlementUserApi.getSubscriptionFromId(baseSubscription.getId()));
             assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
             assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
             assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
             assertListenerStatus();
         }
-     }
-    
+    }
+
     protected SubscriptionTimeline createSubscriptionReapir(final UUID id, final List<DeletedEvent> deletedEvents, final List<NewEvent> newEvents) {
         return new SubscriptionTimeline() {
             @Override
             public UUID getId() {
                 return id;
             }
+
             @Override
             public List<NewEvent> getNewEvents() {
                 return newEvents;
             }
+
             @Override
             public List<ExistingEvent> getExistingEvents() {
                 return null;
             }
+
             @Override
             public List<DeletedEvent> getDeletedEvents() {
                 return deletedEvents;
@@ -194,21 +197,24 @@ public class TestRepairIntegration extends TestIntegrationBase {
         };
     }
 
-    
+
     protected BundleTimeline createBundleRepair(final UUID bundleId, final String viewId, final List<SubscriptionTimeline> subscriptionRepair) {
         return new BundleTimeline() {
             @Override
             public String getViewId() {
                 return viewId;
             }
+
             @Override
             public List<SubscriptionTimeline> getSubscriptions() {
                 return subscriptionRepair;
             }
+
             @Override
             public UUID getBundleId() {
                 return bundleId;
             }
+
             @Override
             public String getExternalKey() {
                 return null;
@@ -216,28 +222,32 @@ public class TestRepairIntegration extends TestIntegrationBase {
         };
     }
 
-    protected ExistingEvent createExistingEventForAssertion(final SubscriptionTransitionType type, 
-            final String productName, final PhaseType phaseType, final ProductCategory category, final String priceListName, final BillingPeriod billingPeriod,
-            final DateTime effectiveDateTime) {
+    protected ExistingEvent createExistingEventForAssertion(final SubscriptionTransitionType type,
+                                                            final String productName, final PhaseType phaseType, final ProductCategory category, final String priceListName, final BillingPeriod billingPeriod,
+                                                            final DateTime effectiveDateTime) {
 
         final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, category, billingPeriod, priceListName, phaseType);
-        ExistingEvent ev = new ExistingEvent() {
+        final ExistingEvent ev = new ExistingEvent() {
             @Override
             public SubscriptionTransitionType getSubscriptionTransitionType() {
                 return type;
             }
-             @Override
+
+            @Override
             public DateTime getRequestedDate() {
-                 return null;
+                return null;
             }
+
             @Override
             public PlanPhaseSpecifier getPlanPhaseSpecifier() {
                 return spec;
             }
+
             @Override
             public UUID getEventId() {
                 return null;
             }
+
             @Override
             public DateTime getEffectiveDate() {
                 return effectiveDateTime;
@@ -245,9 +255,9 @@ public class TestRepairIntegration extends TestIntegrationBase {
         };
         return ev;
     }
-    
+
     protected SubscriptionTimeline getSubscriptionRepair(final UUID id, final BundleTimeline bundleRepair) {
-        for (SubscriptionTimeline cur : bundleRepair.getSubscriptions()) {
+        for (final SubscriptionTimeline cur : bundleRepair.getSubscriptions()) {
             if (cur.getId().equals(id)) {
                 return cur;
             }
@@ -255,22 +265,23 @@ public class TestRepairIntegration extends TestIntegrationBase {
         Assert.fail("Failed to find SubscriptionReapir " + id);
         return null;
     }
+
     protected void validateExistingEventForAssertion(final ExistingEvent expected, final ExistingEvent input) {
-        
+
         log.info(String.format("Got %s -> Expected %s", input.getPlanPhaseSpecifier().getProductName(), expected.getPlanPhaseSpecifier().getProductName()));
         assertEquals(input.getPlanPhaseSpecifier().getProductName(), expected.getPlanPhaseSpecifier().getProductName());
         log.info(String.format("Got %s -> Expected %s", input.getPlanPhaseSpecifier().getPhaseType(), expected.getPlanPhaseSpecifier().getPhaseType()));
         assertEquals(input.getPlanPhaseSpecifier().getPhaseType(), expected.getPlanPhaseSpecifier().getPhaseType());
         log.info(String.format("Got %s -> Expected %s", input.getPlanPhaseSpecifier().getProductCategory(), expected.getPlanPhaseSpecifier().getProductCategory()));
-        assertEquals(input.getPlanPhaseSpecifier().getProductCategory(), expected.getPlanPhaseSpecifier().getProductCategory());                    
+        assertEquals(input.getPlanPhaseSpecifier().getProductCategory(), expected.getPlanPhaseSpecifier().getProductCategory());
         log.info(String.format("Got %s -> Expected %s", input.getPlanPhaseSpecifier().getPriceListName(), expected.getPlanPhaseSpecifier().getPriceListName()));
-        assertEquals(input.getPlanPhaseSpecifier().getPriceListName(), expected.getPlanPhaseSpecifier().getPriceListName());                    
+        assertEquals(input.getPlanPhaseSpecifier().getPriceListName(), expected.getPlanPhaseSpecifier().getPriceListName());
         log.info(String.format("Got %s -> Expected %s", input.getPlanPhaseSpecifier().getBillingPeriod(), expected.getPlanPhaseSpecifier().getBillingPeriod()));
         assertEquals(input.getPlanPhaseSpecifier().getBillingPeriod(), expected.getPlanPhaseSpecifier().getBillingPeriod());
         log.info(String.format("Got %s -> Expected %s", input.getEffectiveDate(), expected.getEffectiveDate()));
-        assertEquals(input.getEffectiveDate(), expected.getEffectiveDate());        
+        assertEquals(input.getEffectiveDate(), expected.getEffectiveDate());
     }
-    
+
     protected DeletedEvent createDeletedEvent(final UUID eventId) {
         return new DeletedEvent() {
             @Override
@@ -287,10 +298,12 @@ public class TestRepairIntegration extends TestIntegrationBase {
             public SubscriptionTransitionType getSubscriptionTransitionType() {
                 return type;
             }
+
             @Override
             public DateTime getRequestedDate() {
                 return requestedDate;
             }
+
             @Override
             public PlanPhaseSpecifier getPlanPhaseSpecifier() {
                 return spec;
@@ -302,7 +315,7 @@ public class TestRepairIntegration extends TestIntegrationBase {
         if (bundle.getSubscriptions() == null) {
             return;
         }
-        for (SubscriptionTimeline cur : bundle.getSubscriptions()) {
+        for (final SubscriptionTimeline cur : bundle.getSubscriptions()) {
             if (cur.getExistingEvents() != null) {
                 sortExistingEvent(cur.getExistingEvents());
             }
@@ -315,15 +328,16 @@ public class TestRepairIntegration extends TestIntegrationBase {
     protected void sortExistingEvent(final List<ExistingEvent> events) {
         Collections.sort(events, new Comparator<ExistingEvent>() {
             @Override
-            public int compare(ExistingEvent arg0, ExistingEvent arg1) {
+            public int compare(final ExistingEvent arg0, final ExistingEvent arg1) {
                 return arg0.getEffectiveDate().compareTo(arg1.getEffectiveDate());
             }
         });
     }
+
     protected void sortNewEvent(final List<NewEvent> events) {
         Collections.sort(events, new Comparator<NewEvent>() {
             @Override
-            public int compare(NewEvent arg0, NewEvent arg1) {
+            public int compare(final NewEvent arg0, final NewEvent arg1) {
                 return arg0.getRequestedDate().compareTo(arg1.getRequestedDate());
             }
         });
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java b/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java
index f60d61f..ac41b0e 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java
@@ -16,6 +16,12 @@
 
 package com.ning.billing.beatrix.lifecycle;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Inject;
@@ -24,16 +30,11 @@ import com.google.inject.Stage;
 import com.ning.billing.lifecycle.KillbillService;
 import com.ning.billing.lifecycle.LifecycleHandlerType;
 import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
 
 
 public class TestLifecycle {
 
-    private final static Logger log = LoggerFactory.getLogger(TestLifecycle.class);
+    private static final Logger log = LoggerFactory.getLogger(TestLifecycle.class);
 
     private Service1 s1;
     private Service2 s2;
@@ -61,7 +62,7 @@ public class TestLifecycle {
         }
     }
 
-    public static class Service1 extends ServiceBase implements KillbillService  {
+    public static class Service1 extends ServiceBase implements KillbillService {
 
         @LifecycleHandlerType(LifecycleLevel.INIT_BUS)
         public void initBus() {
@@ -120,8 +121,7 @@ public class TestLifecycle {
     }
 
 
-
-    @BeforeClass(alwaysRun=true)
+    @BeforeClass(alwaysRun = true)
     public void setup() {
         final Injector g = Guice.createInjector(Stage.DEVELOPMENT, new TestLifecycleModule());
         s1 = g.getInstance(Service1.class);
@@ -129,7 +129,7 @@ public class TestLifecycle {
         lifecycle = g.getInstance(DefaultLifecycle.class);
     }
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testLifecycle() {
         s1.reset();
         s2.reset();
@@ -155,11 +155,12 @@ public class TestLifecycle {
     public static class LifecycleNoWarn extends DefaultLifecycle {
 
         @Inject
-        public LifecycleNoWarn(Injector injector) {
+        public LifecycleNoWarn(final Injector injector) {
             super(injector);
         }
+
         @Override
-        protected void logWarn(String msg, Exception e) {
+        protected void logWarn(final String msg, final Exception e) {
         }
     }
 

catalog/pom.xml 13(+7 -6)

diff --git a/catalog/pom.xml b/catalog/pom.xml
index 3ad08f6..970a8a6 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-catalog</artifactId>
@@ -53,15 +53,16 @@
             <artifactId>joda-time</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.skife.config</groupId>
             <artifactId>config-magic</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
-     <build>
+    <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultCatalogService.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultCatalogService.java
index 2ed1cfa..9685457 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultCatalogService.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultCatalogService.java
@@ -37,11 +37,11 @@ public class DefaultCatalogService implements KillbillService, Provider<Catalog>
     private final CatalogConfig config;
     private boolean isInitialized;
 
-	private VersionedCatalogLoader loader;
+    private final VersionedCatalogLoader loader;
 
 
     @Inject
-    public DefaultCatalogService(CatalogConfig config, VersionedCatalogLoader loader) {
+    public DefaultCatalogService(final CatalogConfig config, final VersionedCatalogLoader loader) {
         this.config = config;
         this.isInitialized = false;
         this.loader = loader;
@@ -51,10 +51,9 @@ public class DefaultCatalogService implements KillbillService, Provider<Catalog>
     public synchronized void loadCatalog() throws ServiceException {
         if (!isInitialized) {
             try {
-            	String url = config.getCatalogURI();
-            	catalog = loader.load(url);
+                final String url = config.getCatalogURI();
+                catalog = loader.load(url);
 
-                //catalog = XMLLoader.getObjectFromProperty(config.getCatalogURI(), Catalog.class);
                 isInitialized = true;
             } catch (Exception e) {
                 throw new ServiceException(e);
@@ -69,10 +68,9 @@ public class DefaultCatalogService implements KillbillService, Provider<Catalog>
     }
 
 
-
     /* (non-Javadoc)
-     * @see com.ning.billing.catalog.ICatlogService#getCatalog()
-     */
+    * @see com.ning.billing.catalog.ICatlogService#getCatalog()
+    */
     @Override
     public Catalog getFullCatalog() {
         return catalog;
@@ -85,9 +83,9 @@ public class DefaultCatalogService implements KillbillService, Provider<Catalog>
         return catalog;
     }
 
-	@Override
-	public StaticCatalog getCurrentCatalog() {
-		return catalog;
-	}
+    @Override
+    public StaticCatalog getCurrentCatalog() {
+        return catalog;
+    }
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultDuration.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultDuration.java
index 34860be..87659e5 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultDuration.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultDuration.java
@@ -31,17 +31,17 @@ import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultDuration extends ValidatingConfig<StandaloneCatalog> implements Duration {
-	@XmlElement(required=true)
+    @XmlElement(required = true)
     private TimeUnit unit;
 
-	@XmlElement(required=false)
+    @XmlElement(required = false)
     private Integer number = -1;
-	
+
     /* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IDuration#getUnit()
-	 */
+      * @see com.ning.billing.catalog.IDuration#getUnit()
+      */
     @Override
-	public TimeUnit getUnit() {
+    public TimeUnit getUnit() {
         return unit;
     }
 
@@ -49,13 +49,15 @@ public class DefaultDuration extends ValidatingConfig<StandaloneCatalog> impleme
 	 * @see com.ning.billing.catalog.IDuration#getLength()
 	 */
     @Override
-	public int getNumber() {
+    public int getNumber() {
         return number;
     }
 
     @Override
-    public DateTime addToDateTime(DateTime dateTime) {
-        if ((number == null) && (unit != TimeUnit.UNLIMITED)) {return dateTime;}
+    public DateTime addToDateTime(final DateTime dateTime) {
+        if ((number == null) && (unit != TimeUnit.UNLIMITED)) {
+            return dateTime;
+        }
 
         switch (unit) {
             case DAYS:
@@ -72,30 +74,32 @@ public class DefaultDuration extends ValidatingConfig<StandaloneCatalog> impleme
     }
 
     @Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
         //Validation: TimeUnit UNLIMITED iff number == -1
-        if((unit == TimeUnit.UNLIMITED && number != -1)) {
-            errors.add(new ValidationError("Duration can only have 'UNLIMITED' unit if the number is omitted.", 
-                    catalog.getCatalogURI(), DefaultPlanPhase.class, ""));
+        if ((unit == TimeUnit.UNLIMITED && number != -1)) {
+            errors.add(new ValidationError("Duration can only have 'UNLIMITED' unit if the number is omitted.",
+                                           catalog.getCatalogURI(), DefaultPlanPhase.class, ""));
         }
 
-		//TODO MDW - Validation TimeUnit UNLIMITED iff number == -1
-		return errors;
-	}
+        //TODO MDW - Validation TimeUnit UNLIMITED iff number == -1
+        return errors;
+    }
+
+    protected DefaultDuration setUnit(final TimeUnit unit) {
+        this.unit = unit;
+        return this;
+    }
 
-	protected DefaultDuration setUnit(TimeUnit unit) {
-		this.unit = unit;
-		return this;
-	}
+    protected DefaultDuration setNumber(final Integer number) {
+        this.number = number;
+        return this;
+    }
 
-	protected DefaultDuration setNumber(Integer number) {
-		this.number = number;
-		return this;
-	}
-	
     @Override
     public Period toJodaPeriod() {
-        if ((number == null) && (unit != TimeUnit.UNLIMITED)) {return new Period();}
+        if ((number == null) && (unit != TimeUnit.UNLIMITED)) {
+            return new Period();
+        }
 
         switch (unit) {
             case DAYS:
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultInternationalPrice.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultInternationalPrice.java
index d0cf2c4..7411935 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultInternationalPrice.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultInternationalPrice.java
@@ -16,12 +16,11 @@
 
 package com.ning.billing.catalog;
 
-import java.math.BigDecimal;
-import java.net.URI;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
+import java.math.BigDecimal;
+import java.net.URI;
 
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -35,102 +34,101 @@ import com.ning.billing.util.config.ValidationErrors;
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultInternationalPrice extends ValidatingConfig<StandaloneCatalog> implements InternationalPrice {
 
-	//TODO: Must have a price point for every configured currency
-	//TODO: No prices is a zero cost plan
-	@XmlElement(name="price")
-	private DefaultPrice[] prices;
-
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.InternationalPrice#getPrices()
-	 */
-	@Override
-	public Price[] getPrices() {
-		return prices;
-	}
-
-
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IInternationalPrice#getPrice(com.ning.billing.catalog.api.Currency)
-	 */
-	@Override 
-	public BigDecimal getPrice(Currency currency) throws CatalogApiException {
-		for(Price p : prices) {
-			if(p.getCurrency() == currency) {
-				return p.getValue();
-			}
-		}
-		throw new CatalogApiException(ErrorCode.CAT_NO_PRICE_FOR_CURRENCY, currency);
-	}
-
-	protected DefaultInternationalPrice setPrices(DefaultPrice[] prices) {
-		this.prices = prices;
-		return this;
-	}
-
-
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors)  {
-		Currency[] supportedCurrencies = catalog.getCurrentSupportedCurrencies();
-		for (Price p : prices) {
-			Currency currency = p.getCurrency();
-			if(!currencyIsSupported(currency, supportedCurrencies)) {
-				errors.add("Unsupported currency: " + currency, catalog.getCatalogURI(), this.getClass(), "");
-			}
-			try {
-				if(p.getValue().doubleValue() < 0.0) {
-					errors.add("Negative value for price in currency: " + currency, catalog.getCatalogURI(), this.getClass(), "");
-				}
-			} catch (CurrencyValueNull e) {
-				// No currency => nothing to check, ignore exception
-			}
-		}
-		return errors;
-	}
-	
-	private boolean currencyIsSupported(Currency currency, Currency[] supportedCurrencies) {
-		for (Currency c : supportedCurrencies) {
-			if(c == currency) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-
-	@Override
-	public void initialize(StandaloneCatalog root, URI uri) {
-		if(prices == null) {
-			prices = getZeroPrice(root);
-		}
-		super.initialize(root, uri);
-	}
-
-	private synchronized DefaultPrice[] getZeroPrice(StandaloneCatalog root) {
-		Currency[] currencies = root.getCurrentSupportedCurrencies();
-		DefaultPrice[] zeroPrice = new DefaultPrice[currencies.length];
-		for(int i = 0; i < currencies.length; i++) {
-			zeroPrice[i] = new DefaultPrice();
-			zeroPrice[i].setCurrency(currencies[i]);
-			zeroPrice[i].setValue(new BigDecimal(0));
-		}
-
-		return zeroPrice;
-	}
-
-	@Override
-	public boolean isZero() {
-		for(DefaultPrice price :prices) {
-			try {
-				if( price.getValue().compareTo(BigDecimal.ZERO) != 0) {
-					return false;
-				}
-			} catch (CurrencyValueNull e) {
-				//Ignore if the currency is null we treat it as 0
-			}
-		}
-		return true;
-	}
+    //TODO: Must have a price point for every configured currency
+    //TODO: No prices is a zero cost plan
+    @XmlElement(name = "price")
+    private DefaultPrice[] prices;
+
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.InternationalPrice#getPrices()
+      */
+    @Override
+    public Price[] getPrices() {
+        return prices;
+    }
+
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IInternationalPrice#getPrice(com.ning.billing.catalog.api.Currency)
+      */
+    @Override
+    public BigDecimal getPrice(final Currency currency) throws CatalogApiException {
+        for (final Price p : prices) {
+            if (p.getCurrency() == currency) {
+                return p.getValue();
+            }
+        }
+        throw new CatalogApiException(ErrorCode.CAT_NO_PRICE_FOR_CURRENCY, currency);
+    }
+
+    protected DefaultInternationalPrice setPrices(final DefaultPrice[] prices) {
+        this.prices = prices;
+        return this;
+    }
+
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        final Currency[] supportedCurrencies = catalog.getCurrentSupportedCurrencies();
+        for (final Price p : prices) {
+            final Currency currency = p.getCurrency();
+            if (!currencyIsSupported(currency, supportedCurrencies)) {
+                errors.add("Unsupported currency: " + currency, catalog.getCatalogURI(), this.getClass(), "");
+            }
+            try {
+                if (p.getValue().doubleValue() < 0.0) {
+                    errors.add("Negative value for price in currency: " + currency, catalog.getCatalogURI(), this.getClass(), "");
+                }
+            } catch (CurrencyValueNull e) {
+                // No currency => nothing to check, ignore exception
+            }
+        }
+        return errors;
+    }
+
+    private boolean currencyIsSupported(final Currency currency, final Currency[] supportedCurrencies) {
+        for (final Currency c : supportedCurrencies) {
+            if (c == currency) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    @Override
+    public void initialize(final StandaloneCatalog root, final URI uri) {
+        if (prices == null) {
+            prices = getZeroPrice(root);
+        }
+        super.initialize(root, uri);
+    }
+
+    private synchronized DefaultPrice[] getZeroPrice(final StandaloneCatalog root) {
+        final Currency[] currencies = root.getCurrentSupportedCurrencies();
+        final DefaultPrice[] zeroPrice = new DefaultPrice[currencies.length];
+        for (int i = 0; i < currencies.length; i++) {
+            zeroPrice[i] = new DefaultPrice();
+            zeroPrice[i].setCurrency(currencies[i]);
+            zeroPrice[i].setValue(new BigDecimal(0));
+        }
+
+        return zeroPrice;
+    }
+
+    @Override
+    public boolean isZero() {
+        for (final DefaultPrice price : prices) {
+            try {
+                if (price.getValue().compareTo(BigDecimal.ZERO) != 0) {
+                    return false;
+                }
+            } catch (CurrencyValueNull e) {
+                //Ignore if the currency is null we treat it as 0
+            }
+        }
+        return true;
+    }
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultListing.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultListing.java
index bede9f0..70c6761 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultListing.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultListing.java
@@ -24,7 +24,7 @@ public class DefaultListing implements Listing {
     private final Plan plan;
     private final PriceList priceList;
 
-    public DefaultListing(Plan plan, PriceList priceList) {
+    public DefaultListing(final Plan plan, final PriceList priceList) {
         super();
         this.plan = plan;
         this.priceList = priceList;
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultPlan.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultPlan.java
index a249289..fcf35b5 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultPlan.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultPlan.java
@@ -18,6 +18,7 @@ package com.ning.billing.catalog;
 
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.Iterator;
 
@@ -34,7 +35,6 @@ import org.joda.time.DateTime;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.CatalogApiException;
-import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.Product;
@@ -45,46 +45,47 @@ import com.ning.billing.util.config.ValidationErrors;
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements Plan {
 
-	@XmlAttribute(required=true)
-	@XmlID
-	private String name;
-	
-	@XmlAttribute(required=false)
-	private Boolean retired = false;
-	
-	//TODO MDW Validation - effectiveDateForExistingSubscriptons > catalog effectiveDate 
-	@XmlElement(required=false)
-	private Date effectiveDateForExistingSubscriptons;
-
-	@XmlElement(required=true)
-	@XmlIDREF
+    @XmlAttribute(required = true)
+    @XmlID
+    private String name;
+
+    @XmlAttribute(required = false)
+    private Boolean retired = false;
+
+    //TODO MDW Validation - effectiveDateForExistingSubscriptons > catalog effectiveDate
+    @XmlElement(required = false)
+    private Date effectiveDateForExistingSubscriptons;
+
+    @XmlElement(required = true)
+    @XmlIDREF
     private DefaultProduct product;
 
-	@XmlElementWrapper(name="initialPhases", required=false)
-	@XmlElement(name="phase", required=true)
+    @XmlElementWrapper(name = "initialPhases", required = false)
+    @XmlElement(name = "phase", required = true)
     private DefaultPlanPhase[] initialPhases = new DefaultPlanPhase[0];
 
-	@XmlElement(name="finalPhase", required=true)
+    @XmlElement(name = "finalPhase", required = true)
     private DefaultPlanPhase finalPhase;
 
-	//If this is missing it defaults to 1
-	//No other value is allowed for BASE plans.
-	//No other value is allowed for Tiered ADDONS
-	//A value of -1 means unlimited
-	@XmlElement(required=false)
-	private Integer plansAllowedInBundle = 1;
+    //If this is missing it defaults to 1
+    //No other value is allowed for BASE plans.
+    //No other value is allowed for Tiered ADDONS
+    //A value of -1 means unlimited
+    @XmlElement(required = false)
+    private Integer plansAllowedInBundle = 1;
 
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlan#getEffectiveDateForExistingSubscriptons()
-	 */
-	@Override
-	public Date getEffectiveDateForExistingSubscriptons() {
-		return effectiveDateForExistingSubscriptons;
-	}	/* (non-Javadoc)
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlan#getEffectiveDateForExistingSubscriptons()
+      */
+    @Override
+    public Date getEffectiveDateForExistingSubscriptons() {
+        return effectiveDateForExistingSubscriptons;
+    }    /* (non-Javadoc)
 	 * @see com.ning.billing.catalog.IPlan#getPhases()
 	 */
+
     @Override
-	public DefaultPlanPhase[] getInitialPhases() {
+    public DefaultPlanPhase[] getInitialPhases() {
         return initialPhases;
     }
 
@@ -92,157 +93,166 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements 
 	 * @see com.ning.billing.catalog.IPlan#getProduct()
 	 */
     @Override
-	public Product getProduct() {
+    public Product getProduct() {
         return product;
     }
 
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlan#getName()
-	 */
-	@Override
-	public String getName() {
-		return name;
-	}
-	
-	@Override
-	public boolean isRetired() {
-		return retired;
-	}
-	
-	@Override
-	public DefaultPlanPhase getFinalPhase() {
-		return finalPhase;
-	}
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlan#getName()
+      */
+    @Override
+    public String getName() {
+        return name;
+    }
 
-	@Override
-	public PlanPhase[] getAllPhases() {
-	    int length = (initialPhases == null || initialPhases.length == 0) ? 1 : (initialPhases.length + 1);
-	    PlanPhase[] allPhases = new DefaultPlanPhase[length];
+    @Override
+    public boolean isRetired() {
+        return retired;
+    }
+
+    @Override
+    public DefaultPlanPhase getFinalPhase() {
+        return finalPhase;
+    }
+
+    @Override
+    public PlanPhase[] getAllPhases() {
+        final int length = (initialPhases == null || initialPhases.length == 0) ? 1 : (initialPhases.length + 1);
+        final PlanPhase[] allPhases = new DefaultPlanPhase[length];
         int cnt = 0;
-	    if (length > 1) {
-	        for (PlanPhase cur : initialPhases) {
-	            allPhases[cnt++] = cur;
-	        }
-	    }
+        if (length > 1) {
+            for (final PlanPhase cur : initialPhases) {
+                allPhases[cnt++] = cur;
+            }
+        }
         allPhases[cnt++] = finalPhase;
-	    return allPhases;
-	}
+        return allPhases;
+    }
 
-	@Override
-	public PlanPhase findPhase(String name) throws CatalogApiException {
-		for(PlanPhase pp : getAllPhases()) {
-			if(pp.getName().equals(name)) {
-				return pp;
-			}
+    @Override
+    public PlanPhase findPhase(final String name) throws CatalogApiException {
+        for (final PlanPhase pp : getAllPhases()) {
+            if (pp.getName().equals(name)) {
+                return pp;
+            }
 
-		}
-		throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PHASE, name);
-	}
+        }
+        throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PHASE, name);
+    }
 
-	@Override
-	public BillingPeriod getBillingPeriod(){
-		return finalPhase.getBillingPeriod();
-	}
+    @Override
+    public BillingPeriod getBillingPeriod() {
+        return finalPhase.getBillingPeriod();
+    }
 
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlan#getPlansAllowedInBundle()
-	 */
-	@Override
-	public int getPlansAllowedInBundle() {
-		return plansAllowedInBundle;
-	}
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlan#getPlansAllowedInBundle()
+      */
+    @Override
+    public int getPlansAllowedInBundle() {
+        return plansAllowedInBundle;
+    }
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlan#getPhaseIterator()
+      */
+    @Override
+    public Iterator<PlanPhase> getInitialPhaseIterator() {
+        final ArrayList<PlanPhase> list = new ArrayList<PlanPhase>();
+        for (final DefaultPlanPhase p : initialPhases) {
+            list.add(p);
+        }
+        return list.iterator();
+    }
+
+    @Override
+    public void initialize(final StandaloneCatalog catalog, final URI sourceURI) {
+        super.initialize(catalog, sourceURI);
+        if (finalPhase != null) {
+            finalPhase.setPlan(this);
+            finalPhase.initialize(catalog, sourceURI);
+        }
+        if (initialPhases != null) {
+            for (final DefaultPlanPhase p : initialPhases) {
+                p.setPlan(this);
+                p.initialize(catalog, sourceURI);
+            }
+        }
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        if (effectiveDateForExistingSubscriptons != null &&
+                catalog.getEffectiveDate().getTime() > effectiveDateForExistingSubscriptons.getTime()) {
+            errors.add(new ValidationError(String.format("Price effective date %s is before catalog effective date '%s'",
+                                                         effectiveDateForExistingSubscriptons,
+                                                         catalog.getEffectiveDate().getTime()),
+                                           catalog.getCatalogURI(), DefaultInternationalPrice.class, ""));
+        }
+
+        return errors;
+    }
+
+    protected void setEffectiveDateForExistingSubscriptons(
+            final Date effectiveDateForExistingSubscriptons) {
+        this.effectiveDateForExistingSubscriptons = effectiveDateForExistingSubscriptons;
+    }
+
+    protected DefaultPlan setName(final String name) {
+        this.name = name;
+        return this;
+    }
+
+    protected DefaultPlan setPlansAllowedInBundle(final int plansAllowedInBundle) {
+        this.plansAllowedInBundle = plansAllowedInBundle;
+        return this;
+    }
+
+    protected DefaultPlan setFinalPhase(final DefaultPlanPhase finalPhase) {
+        this.finalPhase = finalPhase;
+        return this;
+    }
+
+    protected DefaultPlan setProduct(final DefaultProduct product) {
+        this.product = product;
+        return this;
+    }
+
+    protected DefaultPlan setInitialPhases(final DefaultPlanPhase[] phases) {
+        this.initialPhases = phases;
+        return this;
+    }
+
+    public DefaultPlan setRetired(final boolean retired) {
+        this.retired = retired;
+        return this;
+    }
+
+    public DefaultPlan setPlansAllowedInBundle(final Integer plansAllowedInBundle) {
+        this.plansAllowedInBundle = plansAllowedInBundle;
+        return this;
+    }
+
+    @Override
+    public DateTime dateOfFirstRecurringNonZeroCharge(final DateTime subscriptionStartDate) {
+        DateTime result = subscriptionStartDate.toDateTime();
+        for (final PlanPhase phase : getAllPhases()) {
+            if (phase.getRecurringPrice() == null || phase.getRecurringPrice().isZero()) {
+                result = phase.getDuration().addToDateTime(result);
+            } else {
+                break;
+            }
+        }
+        return result;
+    }
 
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlan#getPhaseIterator()
-	 */
-	@Override
-	public Iterator<PlanPhase> getInitialPhaseIterator() {
-		ArrayList<PlanPhase> list = new ArrayList<PlanPhase>();
-		for(DefaultPlanPhase p : initialPhases) {
-			list.add(p);
-		}
-		return list.iterator();
-	}
 
-	@Override
-	public void initialize(StandaloneCatalog catalog, URI sourceURI) {
-		super.initialize(catalog, sourceURI);
-		if(finalPhase != null) {
-			finalPhase.setPlan(this);
-			finalPhase.initialize(catalog, sourceURI);
-		}
-		if(initialPhases != null) {
-			for(DefaultPlanPhase p : initialPhases) {
-				p.setPlan(this);
-				p.initialize(catalog, sourceURI);
-			}
-		}
-	}
 
 	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		if(effectiveDateForExistingSubscriptons != null &&
-				catalog.getEffectiveDate().getTime() > effectiveDateForExistingSubscriptons.getTime()) {
-			errors.add(new ValidationError(String.format("Price effective date %s is before catalog effective date '%s'",
-					effectiveDateForExistingSubscriptons,
-					catalog.getEffectiveDate().getTime()), 
-					catalog.getCatalogURI(), DefaultInternationalPrice.class, ""));
-		}
-		
-		return errors;
-	}
-
-	protected void setEffectiveDateForExistingSubscriptons(
-			Date effectiveDateForExistingSubscriptons) {
-		this.effectiveDateForExistingSubscriptons = effectiveDateForExistingSubscriptons;
-	}
-
-	protected DefaultPlan setName(String name) {
-		this.name = name;
-		return this;
-	}
-
-	protected DefaultPlan setPlansAllowedInBundle(int plansAllowedInBundle) {
-		this.plansAllowedInBundle = plansAllowedInBundle;
-		return this;
-	}
-
-	protected DefaultPlan setFinalPhase(DefaultPlanPhase finalPhase) {
-		this.finalPhase = finalPhase;
-		return this;
-	}
-
-	protected DefaultPlan setProduct(DefaultProduct product) {
-		this.product = product;
-		return this;
-	}
-
-	protected DefaultPlan setInitialPhases(DefaultPlanPhase[] phases) {
-		this.initialPhases = phases;
-		return this;
-	}
-
-	public DefaultPlan setRetired(boolean retired) {
-		this.retired = retired;
-		return this;
-	}
-	
-	public DefaultPlan setPlansAllowedInBundle(Integer plansAllowedInBundle) {
-		this.plansAllowedInBundle = plansAllowedInBundle;
-		return this;
-	}
-	@Override
-	public DateTime dateOfFirstRecurringNonZeroCharge(DateTime subscriptionStartDate) {
-		DateTime result = subscriptionStartDate.toDateTime();
-		for (PlanPhase phase : getAllPhases()) {
-			if(phase.getRecurringPrice() == null || phase.getRecurringPrice().isZero()) {
-				result = phase.getDuration().addToDateTime(result);
-			} else {
-				break;
-			}
-		}
-		return result;
-	}
-	
-	
+    public String toString() {
+        return "DefaultPlan [name=" + name + ", retired=" + retired + ", effectiveDateForExistingSubscriptons="
+                + effectiveDateForExistingSubscriptons + ", product=" + product + ", initialPhases="
+                + Arrays.toString(initialPhases) + ", finalPhase=" + finalPhase + ", plansAllowedInBundle="
+                + plansAllowedInBundle + "]";
+    }
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultPlanPhase.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultPlanPhase.java
index 8feff37..3bb0cb1 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultPlanPhase.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultPlanPhase.java
@@ -16,12 +16,11 @@
 
 package com.ning.billing.catalog;
 
-import java.net.URI;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
+import java.net.URI;
 
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -38,174 +37,178 @@ import com.ning.billing.util.config.ValidationErrors;
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultPlanPhase extends ValidatingConfig<StandaloneCatalog> implements PlanPhase {
 
-	@XmlAttribute (required=true)
-	private PhaseType type;
+    @XmlAttribute(required = true)
+    private PhaseType type;
 
-    @XmlElement(required=true)
+    @XmlElement(required = true)
     private DefaultDuration duration;
-    
-    @XmlElement(required=true)
+
+    @XmlElement(required = true)
     private BillingPeriod billingPeriod;
 
-	@XmlElement(required=false)
-	private DefaultInternationalPrice recurringPrice;
+    @XmlElement(required = false)
+    private DefaultInternationalPrice recurringPrice;
 
-	@XmlElement(required=false)
-	private DefaultInternationalPrice fixedPrice;
+    @XmlElement(required = false)
+    private DefaultInternationalPrice fixedPrice;
 
 //  Not supported: variable pricing
 //	@XmlElement(required=false)
 //	private InternationalPrice unitPrice;
 
-	//Not exposed in XML
-	private Plan plan;
-	
-	public static String phaseName(String planName, PhaseType phasetype) {
-		return planName + "-" + phasetype.toString().toLowerCase();
-	}
-	
-	public static String planName(String phaseName) throws CatalogApiException {
-		for(PhaseType type : PhaseType.values()) {
-			if(phaseName.endsWith(type.toString().toLowerCase())) {
-				return phaseName.substring(0, phaseName.length() - type.toString().length() - 1);
-			}
-		}
-		throw new CatalogApiException(ErrorCode.CAT_BAD_PHASE_NAME, phaseName);
-	}
-
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanPhase#getRecurringPrice()
-	 */
+    //Not exposed in XML
+    private Plan plan;
+
+    public static String phaseName(final String planName, final PhaseType phasetype) {
+        return planName + "-" + phasetype.toString().toLowerCase();
+    }
+
+    public static String planName(final String phaseName) throws CatalogApiException {
+        for (final PhaseType type : PhaseType.values()) {
+            if (phaseName.endsWith(type.toString().toLowerCase())) {
+                return phaseName.substring(0, phaseName.length() - type.toString().length() - 1);
+            }
+        }
+        throw new CatalogApiException(ErrorCode.CAT_BAD_PHASE_NAME, phaseName);
+    }
+
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlanPhase#getRecurringPrice()
+      */
     @Override
-	public DefaultInternationalPrice getRecurringPrice() {
+    public DefaultInternationalPrice getRecurringPrice() {
         return recurringPrice;
     }
 
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanPhase#getInternationalPrice()
-	 */
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlanPhase#getInternationalPrice()
+      */
     @Override
-	public InternationalPrice getFixedPrice() {
+    public InternationalPrice getFixedPrice() {
         return fixedPrice;
     }
 
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanPhase#getCohort()
-	 */
-	@Override
-	public PhaseType getPhaseType() {
-		return type;
-	}
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlanPhase#getCohort()
+      */
+    @Override
+    public PhaseType getPhaseType() {
+        return type;
+    }
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlanPhase#getBillCycleDuration()
+      */
+    @Override
+    public BillingPeriod getBillingPeriod() {
+        return billingPeriod;
+    }
 
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanPhase#getBillCycleDuration()
-	 */
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlanPhase#getName()
+      */
     @Override
-	public BillingPeriod getBillingPeriod() {
-    	return billingPeriod;
-    }
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanPhase#getName()
-	 */
-	@Override
-	public String getName() {
-		return phaseName(plan.getName(),this.getPhaseType());
-	}
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanPhase#getPlan()
-	 */
-	@Override
-	public Plan getPlan() {
-		return plan;
-	}
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanPhase#getDuration()
-	 */
-	@Override
-	public Duration getDuration() {
- 		return duration;
-	}
-
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		//Validation: check for nulls
-		if(billingPeriod == null) {
-			errors.add(new ValidationError(String.format("Phase %s of plan %s has a recurring price but no billing period", type.toString(), plan.getName()),
-					catalog.getCatalogURI(), DefaultPlanPhase.class, type.toString()));
-		}
-	
-		//Validation: if there is a recurring price there must be a billing period
-		if((recurringPrice != null) && (billingPeriod == null || billingPeriod == BillingPeriod.NO_BILLING_PERIOD)) {
-			errors.add(new ValidationError(String.format("Phase %s of plan %s has a recurring price but no billing period", type.toString(), plan.getName()),
-					catalog.getCatalogURI(), DefaultPlanPhase.class, type.toString()));
-		}
+    public String getName() {
+        return phaseName(plan.getName(), this.getPhaseType());
+    }
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlanPhase#getPlan()
+      */
+    @Override
+    public Plan getPlan() {
+        return plan;
+    }
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPlanPhase#getDuration()
+      */
+    @Override
+    public Duration getDuration() {
+        return duration;
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        //Validation: check for nulls
+        if (billingPeriod == null) {
+            errors.add(new ValidationError(String.format("Phase %s of plan %s has a recurring price but no billing period", type.toString(), plan.getName()),
+                                           catalog.getCatalogURI(), DefaultPlanPhase.class, type.toString()));
+        }
+
+        //Validation: if there is a recurring price there must be a billing period
+        if ((recurringPrice != null) && (billingPeriod == null || billingPeriod == BillingPeriod.NO_BILLING_PERIOD)) {
+            errors.add(new ValidationError(String.format("Phase %s of plan %s has a recurring price but no billing period", type.toString(), plan.getName()),
+                                           catalog.getCatalogURI(), DefaultPlanPhase.class, type.toString()));
+        }
 
         //Validation: if there is no recurring price there should be no billing period
-        if((recurringPrice == null) && billingPeriod != BillingPeriod.NO_BILLING_PERIOD) {
+        if ((recurringPrice == null) && billingPeriod != BillingPeriod.NO_BILLING_PERIOD) {
             errors.add(new ValidationError(String.format("Phase %s of plan %s has no recurring price but does have a billing period. The billing period should be set to '%s'",
-                    type.toString(), plan.getName(), BillingPeriod.NO_BILLING_PERIOD), 
-                    catalog.getCatalogURI(), DefaultPlanPhase.class, type.toString()));
+                                                         type.toString(), plan.getName(), BillingPeriod.NO_BILLING_PERIOD),
+                                           catalog.getCatalogURI(), DefaultPlanPhase.class, type.toString()));
         }
-        
+
         //Validation: if there BP is set to NO_BILLING_PERIOD there must be a fixed price
-        if((billingPeriod == BillingPeriod.NO_BILLING_PERIOD && fixedPrice == null)) {
+        if ((billingPeriod == BillingPeriod.NO_BILLING_PERIOD && fixedPrice == null)) {
             errors.add(new ValidationError(String.format("Phase %s of plan %s has no billing period. It must have a fixed price set.",
-                    type.toString(), plan.getName()), 
-                    catalog.getCatalogURI(), DefaultPlanPhase.class, type.toString()));
+                                                         type.toString(), plan.getName()),
+                                           catalog.getCatalogURI(), DefaultPlanPhase.class, type.toString()));
+        }
+
+        //Validation: there must be at least one of recurringPrice or fixedPrice
+        if ((recurringPrice == null) && fixedPrice == null) {
+            errors.add(new ValidationError(String.format("Phase %s of plan %s has neither a recurring price or a fixed price.",
+                                                         type.toString(), plan.getName()),
+                                           catalog.getCatalogURI(), DefaultPlanPhase.class, type.toString()));
         }
-        
-		//Validation: there must be at least one of recurringPrice or fixedPrice
-		if((recurringPrice == null) && fixedPrice == null) {
-			errors.add(new ValidationError(String.format("Phase %s of plan %s has neither a recurring price or a fixed price.",
-					type.toString(), plan.getName()), 
-					catalog.getCatalogURI(), DefaultPlanPhase.class, type.toString()));
-		}
         return errors;
-	}
-	
-	@Override
-	public void initialize(StandaloneCatalog root, URI uri) {
-		if (fixedPrice != null) { fixedPrice.initialize(root, uri);  }	
-		if (recurringPrice != null) { recurringPrice.initialize(root, uri); }
-	}
-	
-	protected DefaultPlanPhase setFixedPrice(DefaultInternationalPrice price) {
-		this.fixedPrice = price;
-		return this;
-	}
-
-	protected DefaultPlanPhase setRecurringPrice(DefaultInternationalPrice price) {
-		this.recurringPrice = price;
-		return this;
-	}
-
-	protected DefaultPlanPhase setPhaseType(PhaseType cohort) {
-		this.type = cohort;
-		return this;
-	}
-
-	protected DefaultPlanPhase setBillingPeriod(BillingPeriod billingPeriod) {
-		this.billingPeriod = billingPeriod;
-		return this;
-	}
-
-	protected DefaultPlanPhase setDuration(DefaultDuration duration) {
-		this.duration = duration;
-		return this;
-	}
-
-	protected DefaultPlanPhase setPlan(Plan plan) {
-		this.plan = plan;
-		return this;
-	}
-	
-	protected DefaultPlanPhase setBillCycleDuration(BillingPeriod billingPeriod) {
-		this.billingPeriod = billingPeriod;
-		return this;
-	}
+    }
+
+    @Override
+    public void initialize(final StandaloneCatalog root, final URI uri) {
+        if (fixedPrice != null) {
+            fixedPrice.initialize(root, uri);
+        }
+        if (recurringPrice != null) {
+            recurringPrice.initialize(root, uri);
+        }
+    }
+
+    protected DefaultPlanPhase setFixedPrice(final DefaultInternationalPrice price) {
+        this.fixedPrice = price;
+        return this;
+    }
+
+    protected DefaultPlanPhase setRecurringPrice(final DefaultInternationalPrice price) {
+        this.recurringPrice = price;
+        return this;
+    }
+
+    protected DefaultPlanPhase setPhaseType(final PhaseType cohort) {
+        this.type = cohort;
+        return this;
+    }
+
+    protected DefaultPlanPhase setBillingPeriod(final BillingPeriod billingPeriod) {
+        this.billingPeriod = billingPeriod;
+        return this;
+    }
+
+    protected DefaultPlanPhase setDuration(final DefaultDuration duration) {
+        this.duration = duration;
+        return this;
+    }
+
+    protected DefaultPlanPhase setPlan(final Plan plan) {
+        this.plan = plan;
+        return this;
+    }
+
+    protected DefaultPlanPhase setBillCycleDuration(final BillingPeriod billingPeriod) {
+        this.billingPeriod = billingPeriod;
+        return this;
+    }
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultPrice.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultPrice.java
index 9b5f00b..d07bc37 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultPrice.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultPrice.java
@@ -16,24 +16,24 @@
 
 package com.ning.billing.catalog;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import java.math.BigDecimal;
+
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.CurrencyValueNull;
 import com.ning.billing.catalog.api.Price;
 import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationErrors;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import java.math.BigDecimal;
-
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultPrice extends ValidatingConfig<StandaloneCatalog> implements Price {
-	@XmlElement(required=true)
-	private Currency currency;
+    @XmlElement(required = true)
+    private Currency currency;
 
-	@XmlElement(required=true,nillable=true)
-	private BigDecimal value;
+    @XmlElement(required = true, nillable = true)
+    private BigDecimal value;
 
     public DefaultPrice() {
         // for serialization support
@@ -45,38 +45,38 @@ public class DefaultPrice extends ValidatingConfig<StandaloneCatalog> implements
         this.currency = currency;
     }
 
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPrice#getCurrency()
-	 */
-	@Override
-	public Currency getCurrency() {
-		return currency;
-	}
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPrice#getCurrency()
+      */
+    @Override
+    public Currency getCurrency() {
+        return currency;
+    }
 
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPrice#getValue()
-	 */
-	@Override
-	public BigDecimal getValue() throws CurrencyValueNull {
-		if (value == null) {
-			throw new CurrencyValueNull(currency);
-		}
-		return value;
-	}
-	
-	protected DefaultPrice setCurrency(Currency currency) {
-		this.currency = currency;
-		return this;
-	}
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPrice#getValue()
+      */
+    @Override
+    public BigDecimal getValue() throws CurrencyValueNull {
+        if (value == null) {
+            throw new CurrencyValueNull(currency);
+        }
+        return value;
+    }
 
-	protected DefaultPrice setValue(BigDecimal value) {
-		this.value = value;
-		return this;
-	}
-	
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		return errors;
+    protected DefaultPrice setCurrency(final Currency currency) {
+        this.currency = currency;
+        return this;
+    }
 
-	}
+    protected DefaultPrice setValue(final BigDecimal value) {
+        this.value = value;
+        return this;
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        return errors;
+
+    }
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultPriceList.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultPriceList.java
index c597dc0..9c9ce54 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultPriceList.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultPriceList.java
@@ -16,13 +16,6 @@
 
 package com.ning.billing.catalog;
 
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.PriceList;
-import com.ning.billing.catalog.api.Product;
-import com.ning.billing.util.config.ValidatingConfig;
-import com.ning.billing.util.config.ValidationError;
-import com.ning.billing.util.config.ValidationErrors;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
@@ -31,96 +24,105 @@ import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlID;
 import javax.xml.bind.annotation.XmlIDREF;
 
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.PriceList;
+import com.ning.billing.catalog.api.Product;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationError;
+import com.ning.billing.util.config.ValidationErrors;
+
 @XmlAccessorType(XmlAccessType.NONE)
-public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implements PriceList  {
+public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implements PriceList {
+
+    @XmlAttribute(required = true)
+    @XmlID
+    private String name;
 
-	@XmlAttribute(required=true)
-	@XmlID
-	private String name;
+    @XmlAttribute(required = false)
+    private Boolean retired = false;
 
-	@XmlAttribute(required=false)
-	private Boolean retired = false;
-	
-	@XmlElementWrapper(name="plans", required=true)
-	@XmlIDREF @XmlElement(name="plan", required=true)
+    @XmlElementWrapper(name = "plans", required = true)
+    @XmlIDREF
+    @XmlElement(name = "plan", required = true)
     private DefaultPlan[] plans;
-	
-	public DefaultPriceList(){}
-
-	public DefaultPriceList(DefaultPlan[] plans, String name) {
-		this.plans = plans;
-		this.name = name;
-	}
-
-	protected DefaultPlan[] getPlans() {
-		return plans;
-	}
-
-	public boolean isRetired() {
-		return retired;
-	}
-	
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPriceList#getName()
-	 */
-	@Override
-	public String getName() {
+
+    public DefaultPriceList() {
+    }
+
+    public DefaultPriceList(final DefaultPlan[] plans, final String name) {
+        this.plans = plans;
+        this.name = name;
+    }
+
+    protected DefaultPlan[] getPlans() {
+        return plans;
+    }
+
+    public boolean isRetired() {
+        return retired;
+    }
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPriceList#getName()
+      */
+    @Override
+    public String getName() {
         return name;
     }
 
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPriceList#findPlan(com.ning.billing.catalog.api.IProduct, com.ning.billing.catalog.api.BillingPeriod)
-	 */
-	@Override
-	public DefaultPlan findPlan(Product product, BillingPeriod period) {
-        for (DefaultPlan cur : getPlans()) {
-            if (cur.getProduct().equals(product) && 
-            		(cur.getBillingPeriod() == null || cur.getBillingPeriod().equals(period))) {
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.IPriceList#findPlan(com.ning.billing.catalog.api.IProduct, com.ning.billing.catalog.api.BillingPeriod)
+      */
+    @Override
+    public DefaultPlan findPlan(final Product product, final BillingPeriod period) {
+        for (final DefaultPlan cur : getPlans()) {
+            if (cur.getProduct().equals(product) &&
+                    (cur.getBillingPeriod() == null || cur.getBillingPeriod().equals(period))) {
                 return cur;
             }
         }
         return null;
     }
 
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		 for (DefaultPlan cur : getPlans()) {
-			 int numPlans = findNumberOfPlans(cur.getProduct(), cur.getBillingPeriod());
-			 if ( numPlans > 1 ) {
-				 errors.add(new ValidationError(
-						 String.format("There are %d plans in pricelist %s and have the same product/billingPeriod (%s, %s)", 
-								 numPlans, getName(), cur.getProduct().getName(), cur.getBillingPeriod()), catalog.getCatalogURI(),
-								 DefaultPriceListSet.class, getName()));
-			 }
-		 }
-		return errors;
-	}
-	
-	private int findNumberOfPlans(Product product, BillingPeriod period) {
-		int count = 0;
-        for (DefaultPlan cur : getPlans()) {
-            if (cur.getProduct().equals(product) && 
-            		(cur.getBillingPeriod() == null || cur.getBillingPeriod().equals(period))) {
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        for (final DefaultPlan cur : getPlans()) {
+            final int numPlans = findNumberOfPlans(cur.getProduct(), cur.getBillingPeriod());
+            if (numPlans > 1) {
+                errors.add(new ValidationError(
+                        String.format("There are %d plans in pricelist %s and have the same product/billingPeriod (%s, %s)",
+                                      numPlans, getName(), cur.getProduct().getName(), cur.getBillingPeriod()), catalog.getCatalogURI(),
+                        DefaultPriceListSet.class, getName()));
+            }
+        }
+        return errors;
+    }
+
+    private int findNumberOfPlans(final Product product, final BillingPeriod period) {
+        int count = 0;
+        for (final DefaultPlan cur : getPlans()) {
+            if (cur.getProduct().equals(product) &&
+                    (cur.getBillingPeriod() == null || cur.getBillingPeriod().equals(period))) {
                 count++;
             }
         }
         return count;
     }
-	
-	protected DefaultPriceList setRetired(boolean retired) {
-		this.retired = retired;
-		return this;
-	}
-
-	public DefaultPriceList setName(String name) {
-		this.name = name;
-		return this;
-	}
-
-	public DefaultPriceList setPlans(DefaultPlan[] plans) {
-		this.plans = plans;
-		return this;
-	}
+
+    protected DefaultPriceList setRetired(final boolean retired) {
+        this.retired = retired;
+        return this;
+    }
+
+    public DefaultPriceList setName(final String name) {
+        this.name = name;
+        return this;
+    }
+
+    public DefaultPriceList setPlans(final DefaultPlan[] plans) {
+        this.plans = plans;
+        return this;
+    }
 
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultPriceListSet.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultPriceListSet.java
index b8a8695..a47abb8 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultPriceListSet.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultPriceListSet.java
@@ -16,12 +16,11 @@
 
 package com.ning.billing.catalog;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
+import java.util.ArrayList;
+import java.util.List;
 
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -35,83 +34,82 @@ import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultPriceListSet extends ValidatingConfig<StandaloneCatalog> {
-	@XmlElement(required=true, name="defaultPriceList")
-	private PriceListDefault defaultPricelist;
-	
-	@XmlElement(required=false, name="childPriceList")
-	private DefaultPriceList[] childPriceLists = new DefaultPriceList[0];
-	
-	public DefaultPriceListSet() {
-		if(childPriceLists == null) {
-			childPriceLists = new DefaultPriceList[0];
-		}
-	}
-
-	public DefaultPriceListSet(PriceListDefault defaultPricelist, DefaultPriceList[] childPriceLists) {
-		this.defaultPricelist = defaultPricelist;
-		this.childPriceLists = childPriceLists;
-	}
-
-	public DefaultPlan getPlanFrom(String priceListName, Product product,
-			BillingPeriod period) throws CatalogApiException {
-		DefaultPlan result = null;
-		DefaultPriceList pl = findPriceListFrom(priceListName);
-		if(pl != null) {
-			result = pl.findPlan(product, period);
-		}
-		if(result != null) {
-			return result;
-		}
-		
-		return defaultPricelist.findPlan(product, period);
-	}
-
-	public DefaultPriceList findPriceListFrom (String priceListName) throws CatalogApiException {
-		if(priceListName == null) {
-			throw new CatalogApiException(ErrorCode.CAT_NULL_PRICE_LIST_NAME);
-		}
-		if (defaultPricelist.getName().equals(priceListName)) {
-			return defaultPricelist;
-		} 
-		for(DefaultPriceList pl : childPriceLists) {
-			if(pl.getName().equals(priceListName)) {
-				return pl;
-			}
-		}
-		throw new CatalogApiException(ErrorCode.CAT_PRICE_LIST_NOT_FOUND, priceListName);
-	}
-
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		defaultPricelist.validate(catalog, errors);
-		//Check that the default pricelist name is not in use in the children
-		for(DefaultPriceList pl : childPriceLists) {
-			if(pl.getName().equals(PriceListSet.DEFAULT_PRICELIST_NAME)){
-				errors.add(new ValidationError("Pricelists cannot use the reserved name '" + PriceListSet.DEFAULT_PRICELIST_NAME + "'",
-						catalog.getCatalogURI(), DefaultPriceListSet.class, pl.getName()));
-			}
-			pl.validate(catalog, errors); // and validate the individual pricelists
-		}
-		return errors;
-	}
-
-	public DefaultPriceList getDefaultPricelist() {
-		return defaultPricelist;
-	}
-
-	public DefaultPriceList[] getChildPriceLists() {
-		return childPriceLists;
-	}
+    @XmlElement(required = true, name = "defaultPriceList")
+    private PriceListDefault defaultPricelist;
+
+    @XmlElement(required = false, name = "childPriceList")
+    private DefaultPriceList[] childPriceLists = new DefaultPriceList[0];
+
+    public DefaultPriceListSet() {
+        if (childPriceLists == null) {
+            childPriceLists = new DefaultPriceList[0];
+        }
+    }
+
+    public DefaultPriceListSet(final PriceListDefault defaultPricelist, final DefaultPriceList[] childPriceLists) {
+        this.defaultPricelist = defaultPricelist;
+        this.childPriceLists = childPriceLists;
+    }
+
+    public DefaultPlan getPlanFrom(final String priceListName, final Product product,
+                                   final BillingPeriod period) throws CatalogApiException {
+        DefaultPlan result = null;
+        final DefaultPriceList pl = findPriceListFrom(priceListName);
+        if (pl != null) {
+            result = pl.findPlan(product, period);
+        }
+        if (result != null) {
+            return result;
+        }
+
+        return defaultPricelist.findPlan(product, period);
+    }
+
+    public DefaultPriceList findPriceListFrom(final String priceListName) throws CatalogApiException {
+        if (priceListName == null) {
+            throw new CatalogApiException(ErrorCode.CAT_NULL_PRICE_LIST_NAME);
+        }
+        if (defaultPricelist.getName().equals(priceListName)) {
+            return defaultPricelist;
+        }
+        for (final DefaultPriceList pl : childPriceLists) {
+            if (pl.getName().equals(priceListName)) {
+                return pl;
+            }
+        }
+        throw new CatalogApiException(ErrorCode.CAT_PRICE_LIST_NOT_FOUND, priceListName);
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        defaultPricelist.validate(catalog, errors);
+        //Check that the default pricelist name is not in use in the children
+        for (final DefaultPriceList pl : childPriceLists) {
+            if (pl.getName().equals(PriceListSet.DEFAULT_PRICELIST_NAME)) {
+                errors.add(new ValidationError("Pricelists cannot use the reserved name '" + PriceListSet.DEFAULT_PRICELIST_NAME + "'",
+                                               catalog.getCatalogURI(), DefaultPriceListSet.class, pl.getName()));
+            }
+            pl.validate(catalog, errors); // and validate the individual pricelists
+        }
+        return errors;
+    }
+
+    public DefaultPriceList getDefaultPricelist() {
+        return defaultPricelist;
+    }
+
+    public DefaultPriceList[] getChildPriceLists() {
+        return childPriceLists;
+    }
 
     public List<PriceList> getAllPriceLists() {
-        List<PriceList> result = new ArrayList<PriceList> (childPriceLists.length + 1);
+        final List<PriceList> result = new ArrayList<PriceList>(childPriceLists.length + 1);
         result.add(getDefaultPricelist());
-        for(PriceList list : getChildPriceLists()) {
+        for (final PriceList list : getChildPriceLists()) {
             result.add(list);
         }
         return result;
     }
 
 
-	
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultProduct.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultProduct.java
index 6687c75..0c14bc5 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultProduct.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultProduct.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.catalog;
 
-import com.ning.billing.catalog.api.Product;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.util.config.ValidatingConfig;
-import com.ning.billing.util.config.ValidationErrors;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
@@ -29,133 +24,147 @@ import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlID;
 import javax.xml.bind.annotation.XmlIDREF;
 import java.net.URI;
+import java.util.Arrays;
+
+import com.ning.billing.catalog.api.Product;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implements Product {
-	private static final DefaultProduct[] EMPTY_PRODUCT_LIST = new DefaultProduct[0];
-	
-	@XmlAttribute(required=true)
-	@XmlID
+    private static final DefaultProduct[] EMPTY_PRODUCT_LIST = new DefaultProduct[0];
+
+    @XmlAttribute(required = true)
+    @XmlID
     private String name;
 
-	@XmlAttribute(required=false)
-	private Boolean retired = false;
-	
-	@XmlElement(required=true)
+    @XmlAttribute(required = false)
+    private Boolean retired = false;
+
+    @XmlElement(required = true)
     private ProductCategory category;
-	
-	@XmlElementWrapper(name="included", required=false)
-	@XmlIDREF @XmlElement(name="addonProduct", required=true)
+
+    @XmlElementWrapper(name = "included", required = false)
+    @XmlIDREF
+    @XmlElement(name = "addonProduct", required = true)
     private DefaultProduct[] included = EMPTY_PRODUCT_LIST;
 
-	@XmlElementWrapper(name="available", required=false)
-	@XmlIDREF @XmlElement(name="addonProduct", required=true)
+    @XmlElementWrapper(name = "available", required = false)
+    @XmlIDREF
+    @XmlElement(name = "addonProduct", required = true)
     private DefaultProduct[] available = EMPTY_PRODUCT_LIST;
 
-	//Not included in XML
-	private String catalogName;
-	
-	@Override
-	public String getCatalogName() {
-		return catalogName;
-	}
-
-	@Override
-	public boolean isRetired() {
-		return retired;
-	}
-	
-	@Override
+    //Not included in XML
+    private String catalogName;
+
+    @Override
+    public String getCatalogName() {
+        return catalogName;
+    }
+
+    @Override
+    public boolean isRetired() {
+        return retired;
+    }
+
+    @Override
     public ProductCategory getCategory() {
-		return category;
-	}
+        return category;
+    }
 
     @Override
-	public DefaultProduct[] getIncluded() {
-		return included;
-	}
+    public DefaultProduct[] getIncluded() {
+        return included;
+    }
 
     @Override
-	public DefaultProduct[] getAvailable() {
-		return available;
-	}
+    public DefaultProduct[] getAvailable() {
+        return available;
+    }
 
-	public DefaultProduct() {
+    public DefaultProduct() {
     }
 
-	public DefaultProduct(String name, ProductCategory category) {
-		this.category = category;
-		this.name = name;
+    public DefaultProduct(final String name, final ProductCategory category) {
+        this.category = category;
+        this.name = name;
     }
 
     @Override
-	public String getName() {
+    public String getName() {
         return name;
     }
 
-	public boolean isIncluded(DefaultProduct addon) {
-		for(DefaultProduct p : included) {
-			if (addon == p) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	public boolean isAvailable(DefaultProduct addon) {
-		for(DefaultProduct p : included) {
-			if (addon == p) {
-				return true;
-			}
-		}
-		return false;
-	}
-	
-	@Override
-	public void initialize(StandaloneCatalog catalog, URI sourceURI) {
-		catalogName = catalog.getCatalogName();
-	}
-
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		//TODO: MDW validation: inclusion and exclusion lists can only contain addon products
-		//TODO: MDW validation: a given product can only be in, at most, one of inclusion and exclusion lists
-		return errors;
-	}
-
-	protected DefaultProduct setName(String name) {
-		this.name = name;
-		return this;
-	}
-
-	protected DefaultProduct setCatagory(ProductCategory category) {
-		this.category = category;
-		return this;
-	}
-
-	protected DefaultProduct setCategory(ProductCategory category) {
-		this.category = category;
-		return this;
-	}
-
-	protected DefaultProduct setIncluded(DefaultProduct[] included) {
-		this.included = included;
-		return this;
-	}
-
-	protected DefaultProduct setAvailable(DefaultProduct[] available) {
-		this.available = available;
-		return this;
-	}
-
-	protected DefaultProduct setCatalogName(String catalogName) {
-		this.catalogName = catalogName;
-		return this;
-	}
-
-	public DefaultProduct setRetired(boolean retired) {
-		this.retired = retired;
-		return this;
-	}
+    public boolean isIncluded(final DefaultProduct addon) {
+        for (final DefaultProduct p : included) {
+            if (addon == p) {
+                return true;
+            }
+        }
+        return false;
+    }
 
+    public boolean isAvailable(final DefaultProduct addon) {
+        for (final DefaultProduct p : included) {
+            if (addon == p) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void initialize(final StandaloneCatalog catalog, final URI sourceURI) {
+        catalogName = catalog.getCatalogName();
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        //TODO: MDW validation: inclusion and exclusion lists can only contain addon products
+        //TODO: MDW validation: a given product can only be in, at most, one of inclusion and exclusion lists
+        return errors;
+    }
+
+    protected DefaultProduct setName(final String name) {
+        this.name = name;
+        return this;
+    }
+
+    protected DefaultProduct setCatagory(final ProductCategory category) {
+        this.category = category;
+        return this;
+    }
+
+    protected DefaultProduct setCategory(final ProductCategory category) {
+        this.category = category;
+        return this;
+    }
+
+    protected DefaultProduct setIncluded(final DefaultProduct[] included) {
+        this.included = included;
+        return this;
+    }
+
+    protected DefaultProduct setAvailable(final DefaultProduct[] available) {
+        this.available = available;
+        return this;
+    }
+
+    protected DefaultProduct setCatalogName(final String catalogName) {
+        this.catalogName = catalogName;
+        return this;
+    }
+
+    public DefaultProduct setRetired(final boolean retired) {
+        this.retired = retired;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "DefaultProduct [name=" + name + ", retired=" + retired + ", category=" + category + ", included="
+                + Arrays.toString(included) + ", available=" + Arrays.toString(available) + ", catalogName="
+                + catalogName + "]";
+    }
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/io/ICatalogLoader.java b/catalog/src/main/java/com/ning/billing/catalog/io/ICatalogLoader.java
index 4d1f139..d20a360 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/io/ICatalogLoader.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/io/ICatalogLoader.java
@@ -21,7 +21,7 @@ import com.ning.billing.lifecycle.KillbillService.ServiceException;
 
 public interface ICatalogLoader {
 
-	public abstract VersionedCatalog load(String urlString)
-			throws ServiceException;
+    public abstract VersionedCatalog load(String urlString)
+            throws ServiceException;
 
-}
\ No newline at end of file
+}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java b/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
index 7ef0600..95f5590 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
@@ -16,6 +16,12 @@
 
 package com.ning.billing.catalog.io;
 
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
 import com.google.inject.Inject;
 import com.ning.billing.catalog.StandaloneCatalog;
 import com.ning.billing.catalog.VersionedCatalog;
@@ -24,123 +30,120 @@ import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.config.UriAccessor;
 import com.ning.billing.util.config.XMLLoader;
 
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+public class VersionedCatalogLoader implements ICatalogLoader {
+    private static final Object PROTOCOL_FOR_FILE = "file";
+    private final String XML_EXTENSION = ".xml";
+    private final Clock clock;
+
+    @Inject
+    public VersionedCatalogLoader(final Clock clock) {
+        this.clock = clock;
+    }
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.io.ICatalogLoader#load(java.lang.String)
+      */
+    @Override
+    public VersionedCatalog load(final String uriString) throws ServiceException {
+        try {
+            List<URI> xmlURIs = null;
+
+            if (uriString.endsWith(XML_EXTENSION)) { //assume its an xml file
+                xmlURIs = new ArrayList<URI>();
+                xmlURIs.add(new URI(uriString));
+            } else { //assume its a directory
+                final String directoryContents = UriAccessor.accessUriAsString(uriString);
+                xmlURIs = findXmlReferences(directoryContents, new URL(uriString));
+            }
+
+            final VersionedCatalog result = new VersionedCatalog(clock);
+            for (final URI u : xmlURIs) {
+                final StandaloneCatalog catalog = XMLLoader.getObjectFromUri(u, StandaloneCatalog.class);
+                result.add(catalog);
+            }
+            return result;
+        } catch (Exception e) {
+            throw new ServiceException("Problem encountered loading catalog", e);
+        }
+    }
+
+    protected List<URI> findXmlReferences(final String directoryContents, final URL url) throws URISyntaxException {
+        if (url.getProtocol().equals(PROTOCOL_FOR_FILE)) {
+            return findXmlFileReferences(directoryContents, url);
+        }
+        return findXmlUrlReferences(directoryContents, url);
+    }
+
+    protected List<URI> findXmlUrlReferences(final String directoryContents, final URL url) throws URISyntaxException {
+        final List<URI> results = new ArrayList<URI>();
+        final List<String> urlFragments = extractHrefs(directoryContents);
+        for (final String u : urlFragments) {
+            if (u.endsWith(XML_EXTENSION)) { //points to xml
+                if (u.startsWith("/")) { //absolute path need to add the protocol
+                    results.add(new URI(url.getProtocol() + ":" + u));
+                } else if (u.startsWith("http:")) { // full url
+                    results.add(new URI(u));
+                } else { // relative url stick the name on the end
+                    results.add(appendToURI(url, u));
+                }
+            }
+        }
+        return results;
+    }
+
+    protected List<String> extractHrefs(final String directoryContents) {
+        final List<String> results = new ArrayList<String>();
+        int start = 0;
+        int end = 0;
+        final String HREF_SEARCH_END = "\"";
+        final String HREF_LOW_START = "href=\"";
+        while (start >= 0) {
+            start = directoryContents.indexOf(HREF_LOW_START, end);
+            if (start > 0) {
+                start = start + HREF_LOW_START.length();
+            }
+
+            end = directoryContents.indexOf(HREF_SEARCH_END, start);
+            if (start >= 0) { // We found something
+                results.add(directoryContents.substring(start, end));
+            }
+        }
+
+        start = 0;
+        end = 0;
+        while (start >= 0) {
+            final String HREF_CAPS_START = "HREF=\"";
+            start = directoryContents.indexOf(HREF_CAPS_START, end);
+            if (start > 0) {
+                start = +HREF_LOW_START.length();
+            }
+
+            end = directoryContents.indexOf(HREF_SEARCH_END, start);
+            if (start >= 0) { // We found something
+                results.add(directoryContents.substring(start, end));
+            }
+        }
+        return results;
+    }
+
+    protected List<URI> findXmlFileReferences(final String directoryContents, final URL url) throws URISyntaxException {
+        final List<URI> results = new ArrayList<URI>();
+        final String[] filenames = directoryContents.split("\\n");
+        for (final String filename : filenames) {
+            if (filename.endsWith(XML_EXTENSION)) {
+                results.add(appendToURI(url, filename));
+            }
+        }
+        return results;
+    }
+
+    protected URI appendToURI(final URL url, final String filename) throws URISyntaxException {
+        String f = filename;
+        if (!url.toString().endsWith("/")) {
+            f = "/" + filename;
+        }
+        return new URI(url.toString() + f);
+    }
+
 
-public class VersionedCatalogLoader implements ICatalogLoader  {
-	private static final Object PROTOCOL_FOR_FILE = "file";
-	private  final String XML_EXTENSION = ".xml";
-	private  final String HREF_LOW_START = "href=\""; 
-	private  final String HREF_CAPS_START = "HREF=\""; 
-	private  final String HREF_SEARCH_END = "\"";
-	private Clock clock;
-			
-	@Inject 
-	public VersionedCatalogLoader(Clock clock) {
-		this.clock = clock;
-	}
-	
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.io.ICatalogLoader#load(java.lang.String)
-	 */
-	@Override
-	public  VersionedCatalog load(String uriString) throws ServiceException{
-		try {
-			List<URI> xmlURIs = null;
-			
-			if(uriString.endsWith(XML_EXTENSION)) { //assume its an xml file
-				xmlURIs = new ArrayList<URI>();
-	        	xmlURIs.add(new URI(uriString));
-			} else { //assume its a directory
-				String directoryContents = UriAccessor.accessUriAsString(uriString);
-				xmlURIs = findXmlReferences(directoryContents, new URL(uriString));
-			}
-			
-			VersionedCatalog result = new VersionedCatalog(clock);
-			for(URI u : xmlURIs) {
-				StandaloneCatalog catalog = XMLLoader.getObjectFromUri(u, StandaloneCatalog.class);
-				result.add(catalog);
-			}
-			return result;
-		} catch (Exception e) {
-			throw new ServiceException("Problem encountered loading catalog", e);
-		}
-	}
-	
-	protected  List<URI> findXmlReferences(String directoryContents, URL url) throws URISyntaxException {
-		if(url.getProtocol().equals(PROTOCOL_FOR_FILE)) {
-			return findXmlFileReferences(directoryContents, url);
-		} 
-		return findXmlUrlReferences(directoryContents, url);
-	}
-
-	protected  List<URI> findXmlUrlReferences(String directoryContents, URL url) throws URISyntaxException {
-		List<URI> results = new ArrayList<URI>();
-		List<String> urlFragments = extractHrefs(directoryContents);
-		for(String u : urlFragments) {
-			if(u.endsWith(XML_EXTENSION)) { //points to xml
-				if(u.startsWith("/")) { //absolute path need to add the protocol
-					results.add(new URI(url.getProtocol() + ":" + u));
-				} else if (u.startsWith("http:")) { // full url
-					results.add(new URI(u));
-				} else { // relative url stick the name on the end
-					results.add(appendToURI(url,u));
-				}
-			}
-		}
-		return results;
-	}
-
-	protected  List<String> extractHrefs(String directoryContents) {
-		List<String> results = new ArrayList<String>();
-		int start = 0;
-		int end = 0;
-		while(start >= 0) {
-			start = directoryContents.indexOf(HREF_LOW_START, end);
-			if (start > 0) start = start + HREF_LOW_START.length();
-					
-			end = directoryContents.indexOf(HREF_SEARCH_END, start);
-			if(start >= 0) { // We found something
-				results.add(directoryContents.substring(start, end));
-			}
-		}
-		
-		start = 0;
-		end = 0;
-		while(start >= 0) {
-			start = directoryContents.indexOf(HREF_CAPS_START, end);
-			if (start > 0) start =+ HREF_LOW_START.length();
-			
-			end = directoryContents.indexOf(HREF_SEARCH_END, start);
-			if(start >= 0) { // We found something
-				results.add(directoryContents.substring(start, end));
-			}
-		}
-		return results;
-	}
-
-	protected  List<URI> findXmlFileReferences(String directoryContents, URL url) throws URISyntaxException {
-		List<URI> results = new ArrayList<URI>();
-		String[] filenames = directoryContents.split("\\n");
-		for(String filename : filenames) {
-			if(filename.endsWith(XML_EXTENSION)) {
-				results.add(appendToURI(url,filename));
-			}
-		}
-		return results;
-	}
-
-	protected  URI appendToURI(final URL url, final String filename) throws URISyntaxException {
-		String f = filename;
-		if (!url.toString().endsWith("/")) {
-			f = "/" + filename;
-		}
-		return new URI(url.toString() + f);
-	}
-
-	
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java b/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java
index f667e17..91bdc43 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java
@@ -16,36 +16,37 @@
 
 package com.ning.billing.catalog;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.util.config.ValidationError;
 import com.ning.billing.util.config.ValidationErrors;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-
 @XmlAccessorType(XmlAccessType.NONE)
 public class PriceListDefault extends DefaultPriceList {
-	
-	public PriceListDefault(){}
-	
-	public PriceListDefault(DefaultPlan[] defaultPlans) {
-		super(defaultPlans, PriceListSet.DEFAULT_PRICELIST_NAME);
-	}
-
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		super.validate(catalog, errors);
-		if(!getName().equals(PriceListSet.DEFAULT_PRICELIST_NAME)) {
-			errors.add(new ValidationError("The name of the default pricelist must be 'DEFAULT'", 
-					catalog.getCatalogURI(), DefaultPriceList.class, getName()));
-			
-		}
-		return errors;
-	}
-
-	@Override
-	public String getName() {
-		return PriceListSet.DEFAULT_PRICELIST_NAME;
-	}
+
+    public PriceListDefault() {
+    }
+
+    public PriceListDefault(final DefaultPlan[] defaultPlans) {
+        super(defaultPlans, PriceListSet.DEFAULT_PRICELIST_NAME);
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        super.validate(catalog, errors);
+        if (!getName().equals(PriceListSet.DEFAULT_PRICELIST_NAME)) {
+            errors.add(new ValidationError("The name of the default pricelist must be 'DEFAULT'",
+                                           catalog.getCatalogURI(), DefaultPriceList.class, getName()));
+
+        }
+        return errors;
+    }
+
+    @Override
+    public String getName() {
+        return PriceListSet.DEFAULT_PRICELIST_NAME;
+    }
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java b/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java
index 7ae442f..e1a75f9 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java
@@ -29,53 +29,53 @@ import com.ning.billing.util.config.ValidationErrors;
 
 public abstract class Case<T> extends ValidatingConfig<StandaloneCatalog> {
 
-	protected abstract T getResult();
-	
-	public abstract DefaultProduct getProduct();
-
-	public abstract ProductCategory getProductCategory();
-
-	public abstract BillingPeriod getBillingPeriod();
-	    
-	public abstract DefaultPriceList getPriceList();
-
-	public T getResult(PlanSpecifier planPhase, StandaloneCatalog c) throws CatalogApiException {
-		if (satisfiesCase(planPhase, c)	) {
-			return getResult(); 
-		}
-		return null;
-	}
-	
-	protected boolean satisfiesCase(PlanSpecifier planPhase, StandaloneCatalog c) throws CatalogApiException {
-		return (getProduct()         == null || getProduct().equals(c.findCurrentProduct(planPhase.getProductName()))) &&
-		(getProductCategory() == null || getProductCategory().equals(planPhase.getProductCategory())) &&
-		(getBillingPeriod()   == null || getBillingPeriod().equals(planPhase.getBillingPeriod())) &&
-		(getPriceList()       == null || getPriceList().equals(c.findCurrentPriceList(planPhase.getPriceListName())));
-	}
-
-	public static <K> K getResult(Case<K>[] cases, PlanSpecifier planSpec, StandaloneCatalog catalog) throws CatalogApiException {
-    	if(cases != null) {
-    		for(Case<K> c : cases) {
-    			K result = c.getResult(planSpec, catalog);
-    			if(result != null) { 
-    				return result; 
-    			}        					
-    		}
-    	}
+    protected abstract T getResult();
+
+    public abstract DefaultProduct getProduct();
+
+    public abstract ProductCategory getProductCategory();
+
+    public abstract BillingPeriod getBillingPeriod();
+
+    public abstract DefaultPriceList getPriceList();
+
+    public T getResult(final PlanSpecifier planPhase, final StandaloneCatalog c) throws CatalogApiException {
+        if (satisfiesCase(planPhase, c)) {
+            return getResult();
+        }
         return null;
-        
     }
-	
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		return errors;
-	}
 
-	protected abstract Case<T> setProduct(DefaultProduct product);
+    protected boolean satisfiesCase(final PlanSpecifier planPhase, final StandaloneCatalog c) throws CatalogApiException {
+        return (getProduct() == null || getProduct().equals(c.findCurrentProduct(planPhase.getProductName()))) &&
+                (getProductCategory() == null || getProductCategory().equals(planPhase.getProductCategory())) &&
+                (getBillingPeriod() == null || getBillingPeriod().equals(planPhase.getBillingPeriod())) &&
+                (getPriceList() == null || getPriceList().equals(c.findCurrentPriceList(planPhase.getPriceListName())));
+    }
+
+    public static <K> K getResult(final Case<K>[] cases, final PlanSpecifier planSpec, final StandaloneCatalog catalog) throws CatalogApiException {
+        if (cases != null) {
+            for (final Case<K> c : cases) {
+                final K result = c.getResult(planSpec, catalog);
+                if (result != null) {
+                    return result;
+                }
+            }
+        }
+        return null;
+
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        return errors;
+    }
+
+    protected abstract Case<T> setProduct(DefaultProduct product);
 
-	protected abstract  Case<T> setProductCategory(ProductCategory productCategory);
+    protected abstract Case<T> setProductCategory(ProductCategory productCategory);
 
-	protected abstract  Case<T> setBillingPeriod(BillingPeriod billingPeriod);
+    protected abstract Case<T> setBillingPeriod(BillingPeriod billingPeriod);
 
-	protected abstract  Case<T> setPriceList(DefaultPriceList priceList);
+    protected abstract Case<T> setPriceList(DefaultPriceList priceList);
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseBillingAlignment.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseBillingAlignment.java
index 8b8c9ab..e72a37e 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseBillingAlignment.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseBillingAlignment.java
@@ -22,18 +22,18 @@ import com.ning.billing.catalog.api.BillingAlignment;
 
 public class CaseBillingAlignment extends CasePhase<BillingAlignment> {
 
-	@XmlElement(required=true)
-	private BillingAlignment alignment;
-
-	@Override
-	protected BillingAlignment getResult() {
-		return alignment;
-	}
-
-	protected CaseBillingAlignment setAlignment(BillingAlignment alignment) {
-		this.alignment = alignment;
-		return this;
-	}
-	
-	
+    @XmlElement(required = true)
+    private BillingAlignment alignment;
+
+    @Override
+    protected BillingAlignment getResult() {
+        return alignment;
+    }
+
+    protected CaseBillingAlignment setAlignment(final BillingAlignment alignment) {
+        this.alignment = alignment;
+        return this;
+    }
+
+
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseCancelPolicy.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseCancelPolicy.java
index eb49803..dcf3358 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseCancelPolicy.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseCancelPolicy.java
@@ -20,19 +20,19 @@ import javax.xml.bind.annotation.XmlElement;
 
 import com.ning.billing.catalog.api.ActionPolicy;
 
-public class CaseCancelPolicy extends CasePhase<ActionPolicy>{
+public class CaseCancelPolicy extends CasePhase<ActionPolicy> {
 
-	@XmlElement(required=true)
-	private ActionPolicy policy;
+    @XmlElement(required = true)
+    private ActionPolicy policy;
 
-	@Override
-	protected ActionPolicy getResult() {
-		return policy;
-	}
+    @Override
+    protected ActionPolicy getResult() {
+        return policy;
+    }
 
-	protected CaseCancelPolicy setPolicy(ActionPolicy policy) {
-		this.policy = policy;
-		return this;
-	}
+    protected CaseCancelPolicy setPolicy(final ActionPolicy policy) {
+        this.policy = policy;
+        return this;
+    }
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java
index 963dc2f..fd243a2 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java
@@ -16,6 +16,11 @@
 
 package com.ning.billing.catalog.rules;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlIDREF;
+
 import com.ning.billing.catalog.DefaultPriceList;
 import com.ning.billing.catalog.DefaultProduct;
 import com.ning.billing.catalog.StandaloneCatalog;
@@ -28,127 +33,122 @@ import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationErrors;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlIDREF;
-
 @XmlAccessorType(XmlAccessType.NONE)
-public abstract class CaseChange<T>  extends ValidatingConfig<StandaloneCatalog> {
-
-	@XmlElement(required=false)
-	private PhaseType phaseType;
-
-	@XmlElement(required=false)
-	@XmlIDREF
-	private DefaultProduct fromProduct;
-
-	@XmlElement(required=false)
-	private ProductCategory fromProductCategory;
-
-	@XmlElement(required=false)
-	private BillingPeriod fromBillingPeriod;
-
-	@XmlElement(required=false)
-	@XmlIDREF
-	private DefaultPriceList fromPriceList;
-
-	@XmlElement(required=false)
-	@XmlIDREF
-	private DefaultProduct toProduct;
-
-	@XmlElement(required=false)
-	private ProductCategory toProductCategory;
-
-	@XmlElement(required=false)
-	private BillingPeriod toBillingPeriod;
-
-	@XmlElement(required=false)
-	@XmlIDREF
-	private DefaultPriceList toPriceList;
-
-	protected abstract T getResult();
-	
-	public T getResult(PlanPhaseSpecifier from,
-			PlanSpecifier to, StandaloneCatalog catalog) throws CatalogApiException {
-		if(	
-				(phaseType     	     == null || from.getPhaseType() == phaseType) &&
-				(fromProduct 	     == null || fromProduct.equals(catalog.findCurrentProduct(from.getProductName()))) &&
-				(fromProductCategory == null || fromProductCategory.equals(from.getProductCategory())) &&
-				(fromBillingPeriod   == null || fromBillingPeriod.equals(from.getBillingPeriod())) &&
-				(toProduct           == null || toProduct.equals(catalog.findCurrentProduct(to.getProductName()))) &&
-				(toProductCategory   == null || toProductCategory.equals(to.getProductCategory())) &&
-				(toBillingPeriod     == null || toBillingPeriod.equals(to.getBillingPeriod())) &&
-				(fromPriceList       == null || fromPriceList.equals(catalog.findCurrentPriceList(from.getPriceListName()))) &&
-				(toPriceList         == null || toPriceList.equals(catalog.findCurrentPriceList(to.getPriceListName())))
-				) {
-			return getResult();
-		}
-		return null;
-	}
-	
-	static public <K> K getResult(CaseChange<K>[] cases, PlanPhaseSpecifier from,
-			PlanSpecifier to, StandaloneCatalog catalog) throws CatalogApiException {
-    	if(cases != null) {
-    		for(CaseChange<K> cc : cases) {
-    			K result = cc.getResult(from, to, catalog);
-    			if(result != null) { 
-    				return result; 
-    			}        					
-    		}
-    	}
+public abstract class CaseChange<T> extends ValidatingConfig<StandaloneCatalog> {
+
+    @XmlElement(required = false)
+    private PhaseType phaseType;
+
+    @XmlElement(required = false)
+    @XmlIDREF
+    private DefaultProduct fromProduct;
+
+    @XmlElement(required = false)
+    private ProductCategory fromProductCategory;
+
+    @XmlElement(required = false)
+    private BillingPeriod fromBillingPeriod;
+
+    @XmlElement(required = false)
+    @XmlIDREF
+    private DefaultPriceList fromPriceList;
+
+    @XmlElement(required = false)
+    @XmlIDREF
+    private DefaultProduct toProduct;
+
+    @XmlElement(required = false)
+    private ProductCategory toProductCategory;
+
+    @XmlElement(required = false)
+    private BillingPeriod toBillingPeriod;
+
+    @XmlElement(required = false)
+    @XmlIDREF
+    private DefaultPriceList toPriceList;
+
+    protected abstract T getResult();
+
+    public T getResult(final PlanPhaseSpecifier from,
+                       final PlanSpecifier to, final StandaloneCatalog catalog) throws CatalogApiException {
+        if (
+                (phaseType == null || from.getPhaseType() == phaseType) &&
+                        (fromProduct == null || fromProduct.equals(catalog.findCurrentProduct(from.getProductName()))) &&
+                        (fromProductCategory == null || fromProductCategory.equals(from.getProductCategory())) &&
+                        (fromBillingPeriod == null || fromBillingPeriod.equals(from.getBillingPeriod())) &&
+                        (toProduct == null || toProduct.equals(catalog.findCurrentProduct(to.getProductName()))) &&
+                        (toProductCategory == null || toProductCategory.equals(to.getProductCategory())) &&
+                        (toBillingPeriod == null || toBillingPeriod.equals(to.getBillingPeriod())) &&
+                        (fromPriceList == null || fromPriceList.equals(catalog.findCurrentPriceList(from.getPriceListName()))) &&
+                        (toPriceList == null || toPriceList.equals(catalog.findCurrentPriceList(to.getPriceListName())))
+                ) {
+            return getResult();
+        }
+        return null;
+    }
+
+    public static <K> K getResult(final CaseChange<K>[] cases, final PlanPhaseSpecifier from,
+                                  final PlanSpecifier to, final StandaloneCatalog catalog) throws CatalogApiException {
+        if (cases != null) {
+            for (final CaseChange<K> cc : cases) {
+                final K result = cc.getResult(from, to, catalog);
+                if (result != null) {
+                    return result;
+                }
+            }
+        }
         return null;
-        
+
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        return errors;
+    }
+
+    protected CaseChange<T> setPhaseType(final PhaseType phaseType) {
+        this.phaseType = phaseType;
+        return this;
+    }
+
+    protected CaseChange<T> setFromProduct(final DefaultProduct fromProduct) {
+        this.fromProduct = fromProduct;
+        return this;
+    }
+
+    protected CaseChange<T> setFromProductCategory(final ProductCategory fromProductCategory) {
+        this.fromProductCategory = fromProductCategory;
+        return this;
+    }
+
+    protected CaseChange<T> setFromBillingPeriod(final BillingPeriod fromBillingPeriod) {
+        this.fromBillingPeriod = fromBillingPeriod;
+        return this;
+    }
+
+    protected CaseChange<T> setFromPriceList(final DefaultPriceList fromPriceList) {
+        this.fromPriceList = fromPriceList;
+        return this;
+    }
+
+    protected CaseChange<T> setToProduct(final DefaultProduct toProduct) {
+        this.toProduct = toProduct;
+        return this;
+    }
+
+    protected CaseChange<T> setToProductCategory(final ProductCategory toProductCategory) {
+        this.toProductCategory = toProductCategory;
+        return this;
+    }
+
+    protected CaseChange<T> setToBillingPeriod(final BillingPeriod toBillingPeriod) {
+        this.toBillingPeriod = toBillingPeriod;
+        return this;
+    }
+
+    protected CaseChange<T> setToPriceList(final DefaultPriceList toPriceList) {
+        this.toPriceList = toPriceList;
+        return this;
     }
-	
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		return errors;
-	}
-
-	protected CaseChange<T> setPhaseType(PhaseType phaseType) {
-		this.phaseType = phaseType;
-		return this;
-	}
-
-	protected CaseChange<T> setFromProduct(DefaultProduct fromProduct) {
-		this.fromProduct = fromProduct;
-		return this;
-	}
-
-	protected CaseChange<T> setFromProductCategory(ProductCategory fromProductCategory) {
-		this.fromProductCategory = fromProductCategory;
-		return this;
-	}
-
-	protected CaseChange<T> setFromBillingPeriod(BillingPeriod fromBillingPeriod) {
-		this.fromBillingPeriod = fromBillingPeriod;
-		return this;
-	}
-
-	protected CaseChange<T> setFromPriceList(DefaultPriceList fromPriceList) {
-		this.fromPriceList = fromPriceList;
-		return this;
-	}
-
-	protected CaseChange<T> setToProduct(DefaultProduct toProduct) {
-		this.toProduct = toProduct;
-		return this;
-	}
-
-	protected CaseChange<T> setToProductCategory(ProductCategory toProductCategory) {
-		this.toProductCategory = toProductCategory;
-		return this;
-	}
-
-	protected CaseChange<T> setToBillingPeriod(BillingPeriod toBillingPeriod) {
-		this.toBillingPeriod = toBillingPeriod;
-		return this;
-	}
-
-	protected CaseChange<T> setToPriceList(DefaultPriceList toPriceList) {
-		this.toPriceList = toPriceList;
-		return this;
-	}
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChangePlanAlignment.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChangePlanAlignment.java
index 3186288..1c92cca 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChangePlanAlignment.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChangePlanAlignment.java
@@ -22,17 +22,17 @@ import com.ning.billing.catalog.api.PlanAlignmentChange;
 
 public class CaseChangePlanAlignment extends CaseChange<PlanAlignmentChange> {
 
-	@XmlElement(required=true)
-	private PlanAlignmentChange alignment;
-
-	@Override
-	protected PlanAlignmentChange getResult() {
-		return alignment;
-	}
-
-	protected CaseChangePlanAlignment setAlignment(PlanAlignmentChange alignment) {
-		this.alignment = alignment;
-		return this;
-	}
-	
+    @XmlElement(required = true)
+    private PlanAlignmentChange alignment;
+
+    @Override
+    protected PlanAlignmentChange getResult() {
+        return alignment;
+    }
+
+    protected CaseChangePlanAlignment setAlignment(final PlanAlignmentChange alignment) {
+        this.alignment = alignment;
+        return this;
+    }
+
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChangePlanPolicy.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChangePlanPolicy.java
index f6862f9..321f500 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChangePlanPolicy.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChangePlanPolicy.java
@@ -23,18 +23,18 @@ import com.ning.billing.catalog.api.ActionPolicy;
 
 @XmlSeeAlso(CaseChange.class)
 public class CaseChangePlanPolicy extends CaseChange<ActionPolicy> {
-	
-	@XmlElement(required=true)
-	private ActionPolicy policy;
-
-	@Override
-	protected ActionPolicy getResult() {
-		return policy;
-	}
-
-	protected CaseChangePlanPolicy setPolicy(ActionPolicy policy) {
-		this.policy = policy;
-		return this;
-	}
-	
+
+    @XmlElement(required = true)
+    private ActionPolicy policy;
+
+    @Override
+    protected ActionPolicy getResult() {
+        return policy;
+    }
+
+    protected CaseChangePlanPolicy setPolicy(final ActionPolicy policy) {
+        this.policy = policy;
+        return this;
+    }
+
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseCreateAlignment.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseCreateAlignment.java
index 39f6607..77b0eb5 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseCreateAlignment.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseCreateAlignment.java
@@ -20,19 +20,19 @@ import javax.xml.bind.annotation.XmlElement;
 
 import com.ning.billing.catalog.api.PlanAlignmentCreate;
 
-public class CaseCreateAlignment extends CaseStandardNaming<PlanAlignmentCreate>{
+public class CaseCreateAlignment extends CaseStandardNaming<PlanAlignmentCreate> {
 
-	@XmlElement(required=true)
-	private PlanAlignmentCreate alignment;
+    @XmlElement(required = true)
+    private PlanAlignmentCreate alignment;
 
-	@Override
-	protected PlanAlignmentCreate getResult() {
-		return alignment;
-	}
+    @Override
+    protected PlanAlignmentCreate getResult() {
+        return alignment;
+    }
+
+    protected CaseCreateAlignment setAlignment(final PlanAlignmentCreate alignment) {
+        this.alignment = alignment;
+        return this;
+    }
 
-	protected CaseCreateAlignment setAlignment(PlanAlignmentCreate alignment) {
-		this.alignment = alignment;
-		return this;
-	}
-	
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java
index ebd7561..b7d71da 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java
@@ -16,6 +16,8 @@
 
 package com.ning.billing.catalog.rules;
 
+import javax.xml.bind.annotation.XmlElement;
+
 import com.ning.billing.catalog.StandaloneCatalog;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PhaseType;
@@ -23,44 +25,42 @@ import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.util.config.ValidationErrors;
 
-import javax.xml.bind.annotation.XmlElement;
-
 public abstract class CasePhase<T> extends CaseStandardNaming<T> {
 
-	@XmlElement(required=false)
-	private PhaseType phaseType;	
-	
-	public T getResult(PlanPhaseSpecifier specifier, StandaloneCatalog c) throws CatalogApiException {
-		if ((phaseType       == null ||  specifier.getPhaseType() == phaseType) 
-				&& satisfiesCase(new PlanSpecifier(specifier), c)
-				) {
-			return getResult(); 
-		}
-		return null;
-	}
-	
-	public static <K> K getResult(CasePhase<K>[] cases, PlanPhaseSpecifier planSpec, StandaloneCatalog catalog) throws CatalogApiException {
-    	if(cases != null) {
-    		for(CasePhase<K> cp : cases) {
-    			K result = cp.getResult(planSpec, catalog);
-    			if(result != null) { 
-    				return result; 
-    			}        					
-    		}
-    	}
+    @XmlElement(required = false)
+    private PhaseType phaseType;
+
+    public T getResult(final PlanPhaseSpecifier specifier, final StandaloneCatalog c) throws CatalogApiException {
+        if ((phaseType == null || specifier.getPhaseType() == phaseType)
+                && satisfiesCase(new PlanSpecifier(specifier), c)
+                ) {
+            return getResult();
+        }
         return null;
-        
     }
 
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		return errors;
-	}
+    public static <K> K getResult(final CasePhase<K>[] cases, final PlanPhaseSpecifier planSpec, final StandaloneCatalog catalog) throws CatalogApiException {
+        if (cases != null) {
+            for (final CasePhase<K> cp : cases) {
+                final K result = cp.getResult(planSpec, catalog);
+                if (result != null) {
+                    return result;
+                }
+            }
+        }
+        return null;
+
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        return errors;
+    }
+
+    protected CasePhase<T> setPhaseType(final PhaseType phaseType) {
+        this.phaseType = phaseType;
+        return this;
+    }
+
 
-	protected CasePhase<T> setPhaseType(PhaseType phaseType) {
-		this.phaseType = phaseType;
-		return this;
-	}
-	
-	
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CasePriceList.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CasePriceList.java
index 5063131..2777ec7 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CasePriceList.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CasePriceList.java
@@ -16,34 +16,34 @@
 
 package com.ning.billing.catalog.rules;
 
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlIDREF;
+
 import com.ning.billing.catalog.DefaultPriceList;
 import com.ning.billing.catalog.DefaultProduct;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
 
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlIDREF;
-
 public class CasePriceList extends Case<DefaultPriceList> {
-    @XmlElement(required=false, name="fromProduct")
+    @XmlElement(required = false, name = "fromProduct")
     @XmlIDREF
     private DefaultProduct fromProduct;
-    
-    @XmlElement(required=false, name="fromProductCategory")
+
+    @XmlElement(required = false, name = "fromProductCategory")
     private ProductCategory fromProductCategory;
-    
-    @XmlElement(required=false, name="fromBillingPeriod")
+
+    @XmlElement(required = false, name = "fromBillingPeriod")
     private BillingPeriod fromBillingPeriod;
-    
-    @XmlElement(required=false, name="fromPriceList")
+
+    @XmlElement(required = false, name = "fromPriceList")
     @XmlIDREF
     private DefaultPriceList fromPriceList;
 
-    @XmlElement(required=true, name="toPriceList")
+    @XmlElement(required = true, name = "toPriceList")
     @XmlIDREF
     private DefaultPriceList toPriceList;
 
-    public DefaultProduct getProduct(){
+    public DefaultProduct getProduct() {
         return fromProduct;
     }
 
@@ -54,7 +54,7 @@ public class CasePriceList extends Case<DefaultPriceList> {
     public BillingPeriod getBillingPeriod() {
         return fromBillingPeriod;
     }
-    
+
     public DefaultPriceList getPriceList() {
         return fromPriceList;
     }
@@ -63,33 +63,31 @@ public class CasePriceList extends Case<DefaultPriceList> {
         return toPriceList;
     }
 
-    protected CasePriceList setProduct(DefaultProduct product) {
+    protected CasePriceList setProduct(final DefaultProduct product) {
         this.fromProduct = product;
         return this;
     }
 
-    protected CasePriceList setProductCategory(ProductCategory productCategory) {
+    protected CasePriceList setProductCategory(final ProductCategory productCategory) {
         this.fromProductCategory = productCategory;
         return this;
     }
 
-    protected CasePriceList setBillingPeriod(BillingPeriod billingPeriod) {
+    protected CasePriceList setBillingPeriod(final BillingPeriod billingPeriod) {
         this.fromBillingPeriod = billingPeriod;
         return this;
     }
 
-    protected CasePriceList setPriceList(DefaultPriceList priceList) {
+    protected CasePriceList setPriceList(final DefaultPriceList priceList) {
         this.fromPriceList = priceList;
         return this;
     }
-    
-    
 
 
-	protected CasePriceList setToPriceList(DefaultPriceList toPriceList) {
-		this.toPriceList = toPriceList;
-		return this;
-	}
-	
-	
+    protected CasePriceList setToPriceList(final DefaultPriceList toPriceList) {
+        this.toPriceList = toPriceList;
+        return this;
+    }
+
+
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseStandardNaming.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseStandardNaming.java
index 8e161ce..e33ef59 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseStandardNaming.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseStandardNaming.java
@@ -16,60 +16,60 @@
 
 package com.ning.billing.catalog.rules;
 
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlIDREF;
+
 import com.ning.billing.catalog.DefaultPriceList;
 import com.ning.billing.catalog.DefaultProduct;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
 
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlIDREF;
-
 public abstract class CaseStandardNaming<T> extends Case<T> {
-    @XmlElement(required=false, name="product")
+    @XmlElement(required = false, name = "product")
     @XmlIDREF
     private DefaultProduct product;
-    @XmlElement(required=false, name="productCategory")
+    @XmlElement(required = false, name = "productCategory")
     private ProductCategory productCategory;
-    
-    @XmlElement(required=false, name="billingPeriod")
+
+    @XmlElement(required = false, name = "billingPeriod")
     private BillingPeriod billingPeriod;
-    
-    @XmlElement(required=false, name="priceList")
+
+    @XmlElement(required = false, name = "priceList")
     @XmlIDREF
     private DefaultPriceList priceList;
 
-	public DefaultProduct getProduct(){
-		return product;
-	}
+    public DefaultProduct getProduct() {
+        return product;
+    }
+
+    public ProductCategory getProductCategory() {
+        return productCategory;
+    }
 
-	public ProductCategory getProductCategory() {
-		return productCategory;
-	}
+    public BillingPeriod getBillingPeriod() {
+        return billingPeriod;
+    }
 
-	public BillingPeriod getBillingPeriod() {
-		return billingPeriod;
-	}
-	
-	public DefaultPriceList getPriceList() {
-		return priceList;
-	}
+    public DefaultPriceList getPriceList() {
+        return priceList;
+    }
 
-    protected CaseStandardNaming<T> setProduct(DefaultProduct product) {
+    protected CaseStandardNaming<T> setProduct(final DefaultProduct product) {
         this.product = product;
         return this;
     }
 
-    protected CaseStandardNaming<T> setProductCategory(ProductCategory productCategory) {
+    protected CaseStandardNaming<T> setProductCategory(final ProductCategory productCategory) {
         this.productCategory = productCategory;
         return this;
     }
 
-    protected CaseStandardNaming<T> setBillingPeriod(BillingPeriod billingPeriod) {
+    protected CaseStandardNaming<T> setBillingPeriod(final BillingPeriod billingPeriod) {
         this.billingPeriod = billingPeriod;
         return this;
     }
 
-    protected CaseStandardNaming<T> setPriceList(DefaultPriceList priceList) {
+    protected CaseStandardNaming<T> setPriceList(final DefaultPriceList priceList) {
         this.priceList = priceList;
         return this;
     }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java b/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java
index c47529a..f4b1a5e 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java
@@ -21,15 +21,12 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 
-import org.joda.time.DateTime;
-
 import com.ning.billing.catalog.DefaultPriceList;
 import com.ning.billing.catalog.StandaloneCatalog;
 import com.ning.billing.catalog.api.ActionPolicy;
 import com.ning.billing.catalog.api.BillingAlignment;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.IllegalPlanChange;
-import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanAlignmentChange;
 import com.ning.billing.catalog.api.PlanAlignmentCreate;
 import com.ning.billing.catalog.api.PlanChangeResult;
@@ -39,134 +36,134 @@ import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class PlanRules extends ValidatingConfig<StandaloneCatalog>  {
-
-	@XmlElementWrapper(name="changePolicy")
-	@XmlElement(name="changePolicyCase", required=false)
-	private CaseChangePlanPolicy[] changeCase;
-	
-	@XmlElementWrapper(name="changeAlignment")
-	@XmlElement(name="changeAlignmentCase", required=false)
-	private CaseChangePlanAlignment[] changeAlignmentCase;
-
-	@XmlElementWrapper(name="cancelPolicy")
-	@XmlElement(name="cancelPolicyCase", required=false)
-	private CaseCancelPolicy[] cancelCase;
-
-	@XmlElementWrapper(name="createAlignment")
-	@XmlElement(name="createAlignmentCase", required=false)
-	private CaseCreateAlignment[] createAlignmentCase;
-	
-	@XmlElementWrapper(name="billingAlignment")
-	@XmlElement(name="billingAlignmentCase", required=false)
-	private CaseBillingAlignment[] billingAlignmentCase;
-
-	@XmlElementWrapper(name="priceList")
-	@XmlElement(name="priceListCase", required=false)
-	private CasePriceList[] priceListCase;
-
-	public PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier, StandaloneCatalog catalog) throws CatalogApiException {
-		return Case.getResult(createAlignmentCase, specifier, catalog);      
+public class PlanRules extends ValidatingConfig<StandaloneCatalog> {
+
+    @XmlElementWrapper(name = "changePolicy")
+    @XmlElement(name = "changePolicyCase", required = false)
+    private CaseChangePlanPolicy[] changeCase;
+
+    @XmlElementWrapper(name = "changeAlignment")
+    @XmlElement(name = "changeAlignmentCase", required = false)
+    private CaseChangePlanAlignment[] changeAlignmentCase;
+
+    @XmlElementWrapper(name = "cancelPolicy")
+    @XmlElement(name = "cancelPolicyCase", required = false)
+    private CaseCancelPolicy[] cancelCase;
+
+    @XmlElementWrapper(name = "createAlignment")
+    @XmlElement(name = "createAlignmentCase", required = false)
+    private CaseCreateAlignment[] createAlignmentCase;
+
+    @XmlElementWrapper(name = "billingAlignment")
+    @XmlElement(name = "billingAlignmentCase", required = false)
+    private CaseBillingAlignment[] billingAlignmentCase;
+
+    @XmlElementWrapper(name = "priceList")
+    @XmlElement(name = "priceListCase", required = false)
+    private CasePriceList[] priceListCase;
+
+    public PlanAlignmentCreate getPlanCreateAlignment(final PlanSpecifier specifier, final StandaloneCatalog catalog) throws CatalogApiException {
+        return Case.getResult(createAlignmentCase, specifier, catalog);
+    }
+
+    public ActionPolicy getPlanCancelPolicy(final PlanPhaseSpecifier planPhase, final StandaloneCatalog catalog) throws CatalogApiException {
+        return CasePhase.getResult(cancelCase, planPhase, catalog);
+    }
+
+    public BillingAlignment getBillingAlignment(final PlanPhaseSpecifier planPhase, final StandaloneCatalog catalog) throws CatalogApiException {
+        return CasePhase.getResult(billingAlignmentCase, planPhase, catalog);
+    }
+
+    public PlanChangeResult planChange(final PlanPhaseSpecifier from, PlanSpecifier to, final StandaloneCatalog catalog) throws CatalogApiException {
+        final DefaultPriceList toPriceList;
+        if (to.getPriceListName() == null) { // Pricelist may be null because it is unspecified this is the principal use-case
+            toPriceList = findPriceList(from.toPlanSpecifier(), catalog);
+            to = new PlanSpecifier(to.getProductName(), to.getProductCategory(), to.getBillingPeriod(), toPriceList.getName());
+        } else {
+            toPriceList = catalog.findCurrentPriceList(to.getPriceListName());
+        }
+
+        final ActionPolicy policy = getPlanChangePolicy(from, to, catalog);
+        if (policy == ActionPolicy.ILLEGAL) {
+            throw new IllegalPlanChange(from, to);
+        }
+
+        final PlanAlignmentChange alignment = getPlanChangeAlignment(from, to, catalog);
+
+        return new PlanChangeResult(toPriceList, policy, alignment);
+    }
+
+    public PlanAlignmentChange getPlanChangeAlignment(final PlanPhaseSpecifier from,
+                                                      final PlanSpecifier to, final StandaloneCatalog catalog) throws CatalogApiException {
+        return CaseChange.getResult(changeAlignmentCase, from, to, catalog);
+    }
+
+    public ActionPolicy getPlanChangePolicy(final PlanPhaseSpecifier from,
+                                            final PlanSpecifier to, final StandaloneCatalog catalog) throws CatalogApiException {
+        if (from.getProductName().equals(to.getProductName()) &&
+                from.getBillingPeriod() == to.getBillingPeriod() &&
+                from.getPriceListName().equals(to.getPriceListName())) {
+            return ActionPolicy.ILLEGAL;
+        }
+        //Plan toPlan = catalog.findPlan()
+
+        return CaseChange.getResult(changeCase, from, to, catalog);
+    }
+
+    private DefaultPriceList findPriceList(final PlanSpecifier specifier, final StandaloneCatalog catalog) throws CatalogApiException {
+        DefaultPriceList result = Case.getResult(priceListCase, specifier, catalog);
+        if (result == null) {
+            result = catalog.findCurrentPriceList(specifier.getPriceListName());
+        }
+        return result;
+    }
+
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        //TODO: MDW - Validation: check that the plan change special case pairs are unique!
+        //TODO: MDW - Validation: check that the each product appears in at most one tier.
+        //TODO: MDW - Unit tests for rules
+        //TODO: MDW - validate that there is a default policy for change AND cancel
+
+        return errors;
+    }
+
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    // Setters for testing
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    protected PlanRules setChangeCase(final CaseChangePlanPolicy[] changeCase) {
+        this.changeCase = changeCase;
+        return this;
+    }
+
+    protected PlanRules setChangeAlignmentCase(
+            final CaseChangePlanAlignment[] changeAlignmentCase) {
+        this.changeAlignmentCase = changeAlignmentCase;
+        return this;
+    }
+
+    protected PlanRules setCancelCase(final CaseCancelPolicy[] cancelCase) {
+        this.cancelCase = cancelCase;
+        return this;
     }
-	
-	public ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase, StandaloneCatalog catalog) throws CatalogApiException {
-		return CasePhase.getResult(cancelCase, planPhase, catalog);      
-	}
-
-	public BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase, StandaloneCatalog catalog) throws CatalogApiException {
-		return CasePhase.getResult(billingAlignmentCase, planPhase, catalog);      
-	}
-
-	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to, StandaloneCatalog catalog) throws CatalogApiException {
-		DefaultPriceList toPriceList;
-		if( to.getPriceListName() == null ) { // Pricelist may be null because it is unspecified this is the principal use-case
-			toPriceList = findPriceList(from.toPlanSpecifier(), catalog);
-			to = new PlanSpecifier(to.getProductName(), to.getProductCategory(), to.getBillingPeriod(), toPriceList.getName());
-		} else {
-			toPriceList = catalog.findCurrentPriceList(to.getPriceListName());
-		}
-		
-		ActionPolicy policy = getPlanChangePolicy(from, to, catalog);
-		if(policy == ActionPolicy.ILLEGAL) {
-			throw new IllegalPlanChange(from, to);
-		}
-		
-		PlanAlignmentChange alignment = getPlanChangeAlignment(from, to, catalog);
-		
-		return new PlanChangeResult(toPriceList, policy, alignment);
-	}
-	
-	public PlanAlignmentChange getPlanChangeAlignment(PlanPhaseSpecifier from,
-			PlanSpecifier to, StandaloneCatalog catalog) throws CatalogApiException {
-		return CaseChange.getResult(changeAlignmentCase, from, to, catalog);      
+
+    protected PlanRules setCreateAlignmentCase(final CaseCreateAlignment[] createAlignmentCase) {
+        this.createAlignmentCase = createAlignmentCase;
+        return this;
     }
 
-	public ActionPolicy getPlanChangePolicy(PlanPhaseSpecifier from,
-			PlanSpecifier to, StandaloneCatalog catalog) throws CatalogApiException {
-		if(from.getProductName().equals(to.getProductName()) &&
-				from.getBillingPeriod() == to.getBillingPeriod() &&
-				from.getPriceListName().equals(to.getPriceListName())) {
-			return ActionPolicy.ILLEGAL;
-		}
-		//Plan toPlan = catalog.findPlan()
-		
-		return CaseChange.getResult(changeCase, from, to, catalog); 
-	}
-	
-	private DefaultPriceList findPriceList(PlanSpecifier specifier, StandaloneCatalog catalog) throws CatalogApiException {
-		DefaultPriceList result = Case.getResult(priceListCase, specifier, catalog);
-		if (result == null) {
-			result = catalog.findCurrentPriceList(specifier.getPriceListName());
-		}
-		return result;
-	}
-	
-	
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-	    //TODO: MDW - Validation: check that the plan change special case pairs are unique!
-	    //TODO: MDW - Validation: check that the each product appears in at most one tier.
-		//TODO: MDW - Unit tests for rules
-		//TODO: MDW - validate that there is a default policy for change AND cancel
-
-		return errors;
-	}
-
-	
-	/////////////////////////////////////////////////////////////////////////////////////
-	// Setters for testing
-	/////////////////////////////////////////////////////////////////////////////////////
-	
-	protected PlanRules setChangeCase(CaseChangePlanPolicy[] changeCase) {
-		this.changeCase = changeCase;
-		return this;
-	}
-
-	protected PlanRules setChangeAlignmentCase(
-			CaseChangePlanAlignment[] changeAlignmentCase) {
-		this.changeAlignmentCase = changeAlignmentCase;
-		return this;
-	}
-
-	protected PlanRules setCancelCase(CaseCancelPolicy[] cancelCase) {
-		this.cancelCase = cancelCase;
-		return this;
-	}
-
-	protected PlanRules setCreateAlignmentCase(CaseCreateAlignment[] createAlignmentCase) {
-		this.createAlignmentCase = createAlignmentCase;
-		return this;
-	}
-
-	protected PlanRules setBillingAlignmentCase(
-			CaseBillingAlignment[] billingAlignmentCase) {
-		this.billingAlignmentCase = billingAlignmentCase;
-		return this;
-	}
-
-	protected PlanRules setPriceListCase(CasePriceList[] priceListCase) {
-		this.priceListCase = priceListCase;
-		return this;
-	}
+    protected PlanRules setBillingAlignmentCase(
+            final CaseBillingAlignment[] billingAlignmentCase) {
+        this.billingAlignmentCase = billingAlignmentCase;
+        return this;
+    }
+
+    protected PlanRules setPriceListCase(final CasePriceList[] priceListCase) {
+        this.priceListCase = priceListCase;
+        return this;
+    }
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/StandaloneCatalog.java b/catalog/src/main/java/com/ning/billing/catalog/StandaloneCatalog.java
index 32324f9..22c091b 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/StandaloneCatalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/StandaloneCatalog.java
@@ -16,17 +16,16 @@
 
 package com.ning.billing.catalog;
 
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
 
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.ActionPolicy;
@@ -50,288 +49,287 @@ import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationError;
 import com.ning.billing.util.config.ValidationErrors;
 
-@XmlRootElement(name="catalog")
+@XmlRootElement(name = "catalog")
 @XmlAccessorType(XmlAccessType.NONE)
 public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> implements StaticCatalog {
-	@XmlElement(required=true)
-	private Date effectiveDate;
+    @XmlElement(required = true)
+    private Date effectiveDate;
 
-	@XmlElement(required=true)
-	private String catalogName;
+    @XmlElement(required = true)
+    private String catalogName;
 
-	private URI catalogURI;
+    private URI catalogURI;
 
-	@XmlElementWrapper(name="currencies", required=true)
-	@XmlElement(name="currency", required=true)
-	private Currency[] supportedCurrencies;
+    @XmlElementWrapper(name = "currencies", required = true)
+    @XmlElement(name = "currency", required = true)
+    private Currency[] supportedCurrencies;
 
-	@XmlElementWrapper(name="products", required=true)
-	@XmlElement(name="product", required=true)
-	private DefaultProduct[] products;
+    @XmlElementWrapper(name = "products", required = true)
+    @XmlElement(name = "product", required = true)
+    private DefaultProduct[] products;
 
-	@XmlElement(name="rules", required=true)
-	private PlanRules planRules;
+    @XmlElement(name = "rules", required = true)
+    private PlanRules planRules;
 
-	@XmlElementWrapper(name="plans", required=true)
-	@XmlElement(name="plan", required=true) 
-	private DefaultPlan[] plans;
+    @XmlElementWrapper(name = "plans", required = true)
+    @XmlElement(name = "plan", required = true)
+    private DefaultPlan[] plans;
 
-    @XmlElement(name="priceLists", required=true)
+    @XmlElement(name = "priceLists", required = true)
     private DefaultPriceListSet priceLists;
 
-	public StandaloneCatalog() {}
-
-	protected StandaloneCatalog (Date effectiveDate) {
-		this.effectiveDate = effectiveDate;
-	}
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.ICatalog#getCalalogName()
-	 */
-	@Override
-	public String getCatalogName() {
-		return catalogName;
-	}
-
-	@Override
-	public Date getEffectiveDate() {
-		return effectiveDate;
-	}
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.ICatalog#getProducts()
-	 */
-	@Override
-	public DefaultProduct[] getCurrentProducts() {
-		return products;
-	}
-
-
-	@Override
-	public Currency[] getCurrentSupportedCurrencies() {
-		return supportedCurrencies;
-	}
-
-	@Override
-	public DefaultPlan[] getCurrentPlans() {
-		return plans;
-	}
-
-	public URI getCatalogURI() {
-		return catalogURI;
-	}
-
-	public PlanRules getPlanRules() { 
-		return planRules;
-	}
-	
-	public DefaultPriceList findCurrentPriceList(String priceListName) throws CatalogApiException {
-		return priceLists.findPriceListFrom(priceListName);
-	}
-	
-	public DefaultPriceListSet getPriceLists() {
-		return this.priceLists;
-	}
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.ICatalog#getPlan(java.lang.String, java.lang.String)
-	 */
-	@Override
-	public DefaultPlan findCurrentPlan(String productName, BillingPeriod period, String priceListName) throws CatalogApiException {
-		if (productName == null ) {
-			throw new CatalogApiException(ErrorCode.CAT_NULL_PRODUCT_NAME);
-		}
-		if (priceLists == null) {
-			throw new CatalogApiException(ErrorCode.CAT_PRICE_LIST_NOT_FOUND,priceListName);
-		}
-		Product product = findCurrentProduct(productName);
-		DefaultPlan result = priceLists.getPlanFrom(priceListName, product, period);
-		if ( result == null) {
-			String periodString = (period == null) ? "NULL" :  period.toString();
-			throw new CatalogApiException(ErrorCode.CAT_PLAN_NOT_FOUND, productName, periodString, priceListName);
-		}
-		return result;
-	}
-	
-	@Override
-	public DefaultPlan findCurrentPlan(String name) throws CatalogApiException {
-		if (name == null || plans == null) {
-			throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PLAN, name);
-		}
-		for(DefaultPlan p : plans) {
-			if(p.getName().equals(name)) {
-				return p;
-			}
-		}
-		throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PLAN, name);
-	}
-	
-	@Override
-	public Product findCurrentProduct(String name) throws CatalogApiException {
-		if (name == null || products == null) {
-			throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PRODUCT, name);
-		}
-		for(DefaultProduct p : products) {
-			if (p.getName().equals(name)) {
-				return p;
-			}
-		}
-		throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PRODUCT, name);
-	}
-
-	@Override
-	public PlanPhase findCurrentPhase(String name) throws CatalogApiException {
-		if (name == null || plans == null) {
-			throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PHASE, name);
-		}
-		
-		String  planName = DefaultPlanPhase.planName(name);
-		Plan plan = findCurrentPlan(planName);
-		return plan.findPhase(name);
-	}
+    public StandaloneCatalog() {
+    }
+
+    protected StandaloneCatalog(final Date effectiveDate) {
+        this.effectiveDate = effectiveDate;
+    }
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.ICatalog#getCalalogName()
+      */
+    @Override
+    public String getCatalogName() {
+        return catalogName;
+    }
+
+    @Override
+    public Date getEffectiveDate() {
+        return effectiveDate;
+    }
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.ICatalog#getProducts()
+      */
+    @Override
+    public DefaultProduct[] getCurrentProducts() {
+        return products;
+    }
+
+
+    @Override
+    public Currency[] getCurrentSupportedCurrencies() {
+        return supportedCurrencies;
+    }
+
+    @Override
+    public DefaultPlan[] getCurrentPlans() {
+        return plans;
+    }
+
+    public URI getCatalogURI() {
+        return catalogURI;
+    }
+
+    public PlanRules getPlanRules() {
+        return planRules;
+    }
+
+    public DefaultPriceList findCurrentPriceList(final String priceListName) throws CatalogApiException {
+        return priceLists.findPriceListFrom(priceListName);
+    }
+
+    public DefaultPriceListSet getPriceLists() {
+        return this.priceLists;
+    }
+
+    /* (non-Javadoc)
+      * @see com.ning.billing.catalog.ICatalog#getPlan(java.lang.String, java.lang.String)
+      */
+    @Override
+    public DefaultPlan findCurrentPlan(final String productName, final BillingPeriod period, final String priceListName) throws CatalogApiException {
+        if (productName == null) {
+            throw new CatalogApiException(ErrorCode.CAT_NULL_PRODUCT_NAME);
+        }
+        if (priceLists == null) {
+            throw new CatalogApiException(ErrorCode.CAT_PRICE_LIST_NOT_FOUND, priceListName);
+        }
+        final Product product = findCurrentProduct(productName);
+        final DefaultPlan result = priceLists.getPlanFrom(priceListName, product, period);
+        if (result == null) {
+            final String periodString = (period == null) ? "NULL" : period.toString();
+            throw new CatalogApiException(ErrorCode.CAT_PLAN_NOT_FOUND, productName, periodString, priceListName);
+        }
+        return result;
+    }
+
+    @Override
+    public DefaultPlan findCurrentPlan(final String name) throws CatalogApiException {
+        if (name == null || plans == null) {
+            throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PLAN, name);
+        }
+        for (final DefaultPlan p : plans) {
+            if (p.getName().equals(name)) {
+                return p;
+            }
+        }
+        throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PLAN, name);
+    }
+
+    @Override
+    public Product findCurrentProduct(final String name) throws CatalogApiException {
+        if (name == null || products == null) {
+            throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PRODUCT, name);
+        }
+        for (final DefaultProduct p : products) {
+            if (p.getName().equals(name)) {
+                return p;
+            }
+        }
+        throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PRODUCT, name);
+    }
+
+    @Override
+    public PlanPhase findCurrentPhase(final String name) throws CatalogApiException {
+        if (name == null || plans == null) {
+            throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PHASE, name);
+        }
+
+        final String planName = DefaultPlanPhase.planName(name);
+        final Plan plan = findCurrentPlan(planName);
+        return plan.findPhase(name);
+    }
 
     @Override
-    public PriceList findCurrentPricelist(String name)
+    public PriceList findCurrentPricelist(final String name)
             throws CatalogApiException {
         if (name == null || priceLists == null) {
             throw new CatalogApiException(ErrorCode.CAT_PRICE_LIST_NOT_FOUND, name);
         }
-        
+
         return priceLists.findPriceListFrom(name);
     }
 
 
+    //////////////////////////////////////////////////////////////////////////////
+    //
+    // RULES
+    //
+    //////////////////////////////////////////////////////////////////////////////
+    @Override
+    public ActionPolicy planChangePolicy(final PlanPhaseSpecifier from, final PlanSpecifier to) throws CatalogApiException {
+        return planRules.getPlanChangePolicy(from, to, this);
+    }
+
+    @Override
+    public PlanAlignmentChange planChangeAlignment(final PlanPhaseSpecifier from, final PlanSpecifier to) throws CatalogApiException {
+        return planRules.getPlanChangeAlignment(from, to, this);
+    }
+
+    @Override
+    public ActionPolicy planCancelPolicy(final PlanPhaseSpecifier planPhase) throws CatalogApiException {
+        return planRules.getPlanCancelPolicy(planPhase, this);
+    }
+
+    @Override
+    public PlanAlignmentCreate planCreateAlignment(final PlanSpecifier specifier) throws CatalogApiException {
+        return planRules.getPlanCreateAlignment(specifier, this);
+    }
+
+    @Override
+    public BillingAlignment billingAlignment(final PlanPhaseSpecifier planPhase) throws CatalogApiException {
+        return planRules.getBillingAlignment(planPhase, this);
+    }
+
+    @Override
+    public PlanChangeResult planChange(final PlanPhaseSpecifier from, final PlanSpecifier to)
+            throws CatalogApiException {
+        return planRules.planChange(from, to, this);
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        validate(catalog, errors, products);
+        validate(catalog, errors, plans);
+        priceLists.validate(catalog, errors);
+        planRules.validate(catalog, errors);
+        return errors;
+    }
+
+    private Collection<? extends ValidationError> validate(final StandaloneCatalog catalog,
+                                                           final ValidationErrors errors, final ValidatingConfig<StandaloneCatalog>[] configs) {
+        for (final ValidatingConfig<StandaloneCatalog> config : configs) {
+            config.validate(catalog, errors);
+        }
+        return errors;
+    }
 
-	//////////////////////////////////////////////////////////////////////////////
-	//
-	// RULES
-	//
-	//////////////////////////////////////////////////////////////////////////////
-	@Override
-	public ActionPolicy planChangePolicy(PlanPhaseSpecifier from, PlanSpecifier to) throws CatalogApiException {
-		return planRules.getPlanChangePolicy(from, to, this);
-	}
-
-	@Override
-	public PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from, PlanSpecifier to) throws CatalogApiException {
-		return planRules.getPlanChangeAlignment(from, to, this);
-	}
-
-	@Override
-	public ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase) throws CatalogApiException {
-		return planRules.getPlanCancelPolicy(planPhase, this);
-	}
-
-	@Override
-	public PlanAlignmentCreate planCreateAlignment(PlanSpecifier specifier) throws CatalogApiException {
-		return planRules.getPlanCreateAlignment(specifier, this);
-	}
-
-	@Override
-	public BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase) throws CatalogApiException {
-		return planRules.getBillingAlignment(planPhase, this);
-	}
-
-	@Override
-	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to)
-			throws CatalogApiException {
-		return planRules.planChange(from, to, this);
-	}
-
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		validate(catalog,errors, products);
-		validate(catalog,errors, plans);
-		priceLists.validate(catalog,errors);
-		planRules.validate(catalog, errors);
-		return errors;
-	}
-
-	private Collection<? extends ValidationError> validate(StandaloneCatalog catalog,
-			ValidationErrors errors, ValidatingConfig<StandaloneCatalog>[] configs) {
-		for(ValidatingConfig<StandaloneCatalog> config: configs) {
-			config.validate(catalog, errors);
-		}
-		return errors;
-	}
-	
-
-	@Override
-	public void initialize(StandaloneCatalog catalog, URI sourceURI) {
-		catalogURI = sourceURI;
-		super.initialize(catalog, sourceURI);
-		planRules.initialize(catalog, sourceURI);
-		priceLists.initialize(catalog, sourceURI);
-		for(DefaultProduct p : products) {
-			p.initialize(catalog, sourceURI);
-		}
-		for(DefaultPlan p : plans) {
-			p.initialize(catalog, sourceURI);
-		}
-		
-	}
-
-
-	protected StandaloneCatalog setProducts(DefaultProduct[] products) {
-		this.products = products;
-		return this;
-	}
-	protected StandaloneCatalog setSupportedCurrencies(Currency[] supportedCurrencies) {
-		this.supportedCurrencies = supportedCurrencies;
-		return this;
-	}
-
-	protected StandaloneCatalog setPlanChangeRules(PlanRules planChangeRules) {
-		this.planRules = planChangeRules;
-		return this;
-	}
-
-	protected StandaloneCatalog setPlans(DefaultPlan[] plans) {
-		this.plans = plans;
-		return this;
-	}
-
-	protected StandaloneCatalog setEffectiveDate(Date effectiveDate) {
-		this.effectiveDate = effectiveDate;
-		return this;
-	}
-
-	protected StandaloneCatalog setPlanRules(PlanRules planRules) {
-		this.planRules = planRules;
-		return this;
-	}
-
-    protected StandaloneCatalog setPriceLists(DefaultPriceListSet priceLists) {
+
+    @Override
+    public void initialize(final StandaloneCatalog catalog, final URI sourceURI) {
+        catalogURI = sourceURI;
+        super.initialize(catalog, sourceURI);
+        planRules.initialize(catalog, sourceURI);
+        priceLists.initialize(catalog, sourceURI);
+        for (final DefaultProduct p : products) {
+            p.initialize(catalog, sourceURI);
+        }
+        for (final DefaultPlan p : plans) {
+            p.initialize(catalog, sourceURI);
+        }
+
+    }
+
+
+    protected StandaloneCatalog setProducts(final DefaultProduct[] products) {
+        this.products = products;
+        return this;
+    }
+
+    protected StandaloneCatalog setSupportedCurrencies(final Currency[] supportedCurrencies) {
+        this.supportedCurrencies = supportedCurrencies;
+        return this;
+    }
+
+    protected StandaloneCatalog setPlanChangeRules(final PlanRules planChangeRules) {
+        this.planRules = planChangeRules;
+        return this;
+    }
+
+    protected StandaloneCatalog setPlans(final DefaultPlan[] plans) {
+        this.plans = plans;
+        return this;
+    }
+
+    protected StandaloneCatalog setEffectiveDate(final Date effectiveDate) {
+        this.effectiveDate = effectiveDate;
+        return this;
+    }
+
+    protected StandaloneCatalog setPlanRules(final PlanRules planRules) {
+        this.planRules = planRules;
+        return this;
+    }
+
+    protected StandaloneCatalog setPriceLists(final DefaultPriceListSet priceLists) {
         this.priceLists = priceLists;
         return this;
     }
 
     @Override
-    public boolean canCreatePlan(PlanSpecifier specifier) throws CatalogApiException {
-        Product product = findCurrentProduct(specifier.getProductName());
-        Plan plan = findCurrentPlan(specifier.getProductName(), specifier.getBillingPeriod(), specifier.getPriceListName());
-        DefaultPriceList priceList = findCurrentPriceList(specifier.getPriceListName());
-        
+    public boolean canCreatePlan(final PlanSpecifier specifier) throws CatalogApiException {
+        final Product product = findCurrentProduct(specifier.getProductName());
+        final Plan plan = findCurrentPlan(specifier.getProductName(), specifier.getBillingPeriod(), specifier.getPriceListName());
+        final DefaultPriceList priceList = findCurrentPriceList(specifier.getPriceListName());
+
         return (!product.isRetired()) &&
                 (!plan.isRetired()) &&
                 (!priceList.isRetired());
     }
 
     @Override
-    public List<Listing> getAvailableAddonListings(String baseProductName) {
-        List<Listing> availAddons = new ArrayList<Listing>();
+    public List<Listing> getAvailableAddonListings(final String baseProductName) {
+        final List<Listing> availAddons = new ArrayList<Listing>();
 
         try {
             Product product = findCurrentProduct(baseProductName);
             if ( product != null ) {
                 for ( Product availAddon : product.getAvailable() ) {
-                    for ( Plan plan : getCurrentPlans()) {
-                        if( plan.getProduct().equals(availAddon)) {
-                            for( PriceList priceList : getPriceLists().getAllPriceLists()) {
-                                if ( priceList.findPlan(availAddon, plan.getBillingPeriod()) != null &&
-                                     priceList.findPlan(product, plan.getBillingPeriod()).equals(plan)) {
-                                    availAddons.add(new DefaultListing(plan, priceList));
-                                }
+                    for ( BillingPeriod billingPeriod : BillingPeriod.values()) {
+                        for( PriceList priceList : getPriceLists().getAllPriceLists()) {
+                            Plan addonInList = priceList.findPlan(availAddon, billingPeriod);
+                            if ( (addonInList != null) ) {
+                                availAddons.add(new DefaultListing(addonInList, priceList));
                             }
                         }
                     }
@@ -341,6 +339,7 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
             // No such product - just return an empty list
         }
 
-        return availAddons;    }
+        return availAddons;
+    }
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java b/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
index 3bd370a..5050a17 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
@@ -15,6 +15,10 @@
  */
 package com.ning.billing.catalog;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -23,11 +27,6 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -55,399 +54,397 @@ import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationErrors;
 
 
-@XmlRootElement(name="catalog")
+@XmlRootElement(name = "catalog")
 @XmlAccessorType(XmlAccessType.NONE)
 public class VersionedCatalog extends ValidatingConfig<StandaloneCatalog> implements Catalog, StaticCatalog {
-	private static final Logger log = LoggerFactory.getLogger(VersionedCatalog.class);
-	
-	final private Clock clock;
-	private String catalogName;
-	
-	@XmlElement(name="catalogVersion", required=true)
-	private final List<StandaloneCatalog> versions = new ArrayList<StandaloneCatalog>();
-
-	public VersionedCatalog(Clock clock) {
-		this.clock = clock;
-	}
-
-	//
-	// Private methods
-	//
-	private StandaloneCatalog versionForDate(DateTime date) throws CatalogApiException {
-		return versions.get(indexOfVersionForDate(date.toDate()));
-	}
-
-	private List<StandaloneCatalog> versionsBeforeDate(Date date) throws CatalogApiException {
-		List<StandaloneCatalog> result = new ArrayList<StandaloneCatalog>();
-		int index = indexOfVersionForDate(date);
-		for(int i = 0; i <= index; i++) {
-			result.add(versions.get(i));
-		}
-		return result;
-	}
-
-	private int indexOfVersionForDate(Date date) throws CatalogApiException {
-		for(int i = versions.size() - 1; i >= 0; i--) {
-			StandaloneCatalog c = versions.get(i);
-			if(c.getEffectiveDate().getTime() < date.getTime()) {
-				return i;
-			}
-		}
-		throw new CatalogApiException(ErrorCode.CAT_NO_CATALOG_FOR_GIVEN_DATE, date.toString());
-	}
-	
-	private class PlanRequestWrapper {
-		String name;
-		String productName;
-		BillingPeriod bp;
-		String priceListName;
-		
-		public PlanRequestWrapper(String name) {
-			super();
-			this.name = name;
-		}
-
-		public PlanRequestWrapper(String productName, BillingPeriod bp,
-				String priceListName) {
-			super();
-			this.productName = productName;
-			this.bp = bp;
-			this.priceListName = priceListName;
-		}
-		
-		public Plan findPlan(StandaloneCatalog catalog) throws CatalogApiException {
-			if(name != null) {
-				return catalog.findCurrentPlan(name);
-			} else {
-				return catalog.findCurrentPlan(productName, bp, priceListName);
-			}
-		}
-	}
-	
-	private Plan findPlan(PlanRequestWrapper wrapper, 
-			DateTime requestedDate,
-			DateTime subscriptionStartDate) 
-					throws CatalogApiException {
-		List<StandaloneCatalog> catalogs = versionsBeforeDate(requestedDate.toDate());
-		if(catalogs.size() == 0) {
-			throw new CatalogApiException(ErrorCode.CAT_NO_CATALOG_FOR_GIVEN_DATE, requestedDate.toDate().toString());
-		}
-		
-		for(int i = catalogs.size() - 1; i >= 0 ; i--) { // Working backwards to find the latest applicable plan
-			StandaloneCatalog c = catalogs.get(i);
-			Plan plan = null;
-			try {
-				 plan = wrapper.findPlan(c);
-			} catch (CatalogApiException e) {
-				if(e.getCode() != ErrorCode.CAT_NO_SUCH_PLAN.getCode()) {
-					throw e;
-				} else { 
-					break;
-				}
-			}
-				
-			DateTime catalogEffectiveDate = new DateTime(c.getEffectiveDate());
-			if(subscriptionStartDate.isAfter(catalogEffectiveDate)) { // Its a new subscription this plan always applies
-				return plan;
-			} else { //Its an existing subscription
-				if(plan.getEffectiveDateForExistingSubscriptons() != null) { //if it is null any change to this does not apply to existing subscriptions
-					DateTime existingSubscriptionDate = new DateTime(plan.getEffectiveDateForExistingSubscriptons());
-					if(requestedDate.isAfter(existingSubscriptionDate)){ // this plan is now applicable to existing subs
-						return plan;
-					}
-				}
-			}
-		}
-		
-		throw new CatalogApiException(ErrorCode.CAT_NO_CATALOG_FOR_GIVEN_DATE, requestedDate.toDate().toString());
-	}
-	
-	
-	
-	//
-	// Public methods not exposed in interface
-	//
-	public void add(StandaloneCatalog e) throws CatalogApiException {
-		if(catalogName == null) {
-			catalogName = e.getCatalogName();
-		} else {
-			if(!catalogName.equals(getCatalogName())) {
-				throw new CatalogApiException(ErrorCode.CAT_CATALOG_NAME_MISMATCH,catalogName, e.getCatalogName());
-			}
-		}
-		versions.add(e);
-		Collections.sort(versions,new Comparator<StandaloneCatalog>() {
-			@Override
-			public int compare(StandaloneCatalog c1, StandaloneCatalog c2) {
-				return c1.getEffectiveDate().compareTo(c2.getEffectiveDate());
-			}
-		});
-	}
-		
-	public Iterator<StandaloneCatalog> iterator() {
-		return versions.iterator();
-	}
-
-	public int size() {
-		return versions.size();
-	}
-
-	//
+    private static final Logger log = LoggerFactory.getLogger(VersionedCatalog.class);
+
+    private final Clock clock;
+    private String catalogName;
+
+    @XmlElement(name = "catalogVersion", required = true)
+    private final List<StandaloneCatalog> versions = new ArrayList<StandaloneCatalog>();
+
+    public VersionedCatalog(final Clock clock) {
+        this.clock = clock;
+    }
+
+    //
+    // Private methods
+    //
+    private StandaloneCatalog versionForDate(final DateTime date) throws CatalogApiException {
+        return versions.get(indexOfVersionForDate(date.toDate()));
+    }
+
+    private List<StandaloneCatalog> versionsBeforeDate(final Date date) throws CatalogApiException {
+        final List<StandaloneCatalog> result = new ArrayList<StandaloneCatalog>();
+        final int index = indexOfVersionForDate(date);
+        for (int i = 0; i <= index; i++) {
+            result.add(versions.get(i));
+        }
+        return result;
+    }
+
+    private int indexOfVersionForDate(final Date date) throws CatalogApiException {
+        for (int i = versions.size() - 1; i >= 0; i--) {
+            final StandaloneCatalog c = versions.get(i);
+            if (c.getEffectiveDate().getTime() < date.getTime()) {
+                return i;
+            }
+        }
+        throw new CatalogApiException(ErrorCode.CAT_NO_CATALOG_FOR_GIVEN_DATE, date.toString());
+    }
+
+    private class PlanRequestWrapper {
+        String name;
+        String productName;
+        BillingPeriod bp;
+        String priceListName;
+
+        public PlanRequestWrapper(final String name) {
+            super();
+            this.name = name;
+        }
+
+        public PlanRequestWrapper(final String productName, final BillingPeriod bp,
+                                  final String priceListName) {
+            super();
+            this.productName = productName;
+            this.bp = bp;
+            this.priceListName = priceListName;
+        }
+
+        public Plan findPlan(final StandaloneCatalog catalog) throws CatalogApiException {
+            if (name != null) {
+                return catalog.findCurrentPlan(name);
+            } else {
+                return catalog.findCurrentPlan(productName, bp, priceListName);
+            }
+        }
+    }
+
+    private Plan findPlan(final PlanRequestWrapper wrapper,
+                          final DateTime requestedDate,
+                          final DateTime subscriptionStartDate)
+            throws CatalogApiException {
+        final List<StandaloneCatalog> catalogs = versionsBeforeDate(requestedDate.toDate());
+        if (catalogs.size() == 0) {
+            throw new CatalogApiException(ErrorCode.CAT_NO_CATALOG_FOR_GIVEN_DATE, requestedDate.toDate().toString());
+        }
+
+        for (int i = catalogs.size() - 1; i >= 0; i--) { // Working backwards to find the latest applicable plan
+            final StandaloneCatalog c = catalogs.get(i);
+            Plan plan = null;
+            try {
+                plan = wrapper.findPlan(c);
+            } catch (CatalogApiException e) {
+                if (e.getCode() != ErrorCode.CAT_NO_SUCH_PLAN.getCode()) {
+                    throw e;
+                } else {
+                    break;
+                }
+            }
+
+            final DateTime catalogEffectiveDate = new DateTime(c.getEffectiveDate());
+            if (subscriptionStartDate.isAfter(catalogEffectiveDate)) { // Its a new subscription this plan always applies
+                return plan;
+            } else { //Its an existing subscription
+                if (plan.getEffectiveDateForExistingSubscriptons() != null) { //if it is null any change to this does not apply to existing subscriptions
+                    final DateTime existingSubscriptionDate = new DateTime(plan.getEffectiveDateForExistingSubscriptons());
+                    if (requestedDate.isAfter(existingSubscriptionDate)) { // this plan is now applicable to existing subs
+                        return plan;
+                    }
+                }
+            }
+        }
+
+        throw new CatalogApiException(ErrorCode.CAT_NO_CATALOG_FOR_GIVEN_DATE, requestedDate.toDate().toString());
+    }
+
+
+    //
+    // Public methods not exposed in interface
+    //
+    public void add(final StandaloneCatalog e) throws CatalogApiException {
+        if (catalogName == null) {
+            catalogName = e.getCatalogName();
+        } else {
+            if (!catalogName.equals(getCatalogName())) {
+                throw new CatalogApiException(ErrorCode.CAT_CATALOG_NAME_MISMATCH, catalogName, e.getCatalogName());
+            }
+        }
+        versions.add(e);
+        Collections.sort(versions, new Comparator<StandaloneCatalog>() {
+            @Override
+            public int compare(final StandaloneCatalog c1, final StandaloneCatalog c2) {
+                return c1.getEffectiveDate().compareTo(c2.getEffectiveDate());
+            }
+        });
+    }
+
+    public Iterator<StandaloneCatalog> iterator() {
+        return versions.iterator();
+    }
+
+    public int size() {
+        return versions.size();
+    }
+
+    //
     // Simple getters
     //
-	@Override
-	public String getCatalogName() {
-		return catalogName;
-	}
-
-	@Override
-	public DefaultProduct[] getProducts(DateTime requestedDate) throws CatalogApiException {
-		return versionForDate(requestedDate).getCurrentProducts();
-	}
-
-	@Override
-	public Currency[] getSupportedCurrencies(DateTime requestedDate) throws CatalogApiException {
-		return versionForDate(requestedDate).getCurrentSupportedCurrencies();
-	}
-
-	@Override
-	public DefaultPlan[] getPlans(DateTime requestedDate) throws CatalogApiException {
-		return versionForDate(requestedDate).getCurrentPlans();
-	}
-
-	//
-	// Find a plan
-	//
-	@Override
-	public Plan findPlan(String name, 
-			DateTime requestedDate) 
-					throws CatalogApiException {
-		return versionForDate(requestedDate).findCurrentPlan(name);
-	}
-
-	@Override
-	public Plan findPlan(String productName, 
-			BillingPeriod term,
-			String priceListName,
-			DateTime requestedDate) 
-					throws CatalogApiException {
-		return versionForDate(requestedDate).findCurrentPlan(productName, term, priceListName);
-	}
-
-	@Override
-	public Plan findPlan(String name, 
-			DateTime requestedDate,
-			DateTime subscriptionStartDate) 
-					throws CatalogApiException {
-		return findPlan(new PlanRequestWrapper(name), requestedDate, subscriptionStartDate);
-	}
-
-	@Override
-	public Plan findPlan(String productName, 
-			BillingPeriod term,
-			String priceListName,
-			DateTime requestedDate,
-			DateTime subscriptionStartDate) 
-					throws CatalogApiException {
-		return findPlan(new PlanRequestWrapper(productName, term, priceListName), requestedDate, subscriptionStartDate);
-	}
-
-	//
-	// Find a product
-	//
-	@Override
-	public Product findProduct(String name, DateTime requestedDate) throws CatalogApiException {
-		return versionForDate(requestedDate).findCurrentProduct(name);
-	}
+    @Override
+    public String getCatalogName() {
+        return catalogName;
+    }
+
+    @Override
+    public DefaultProduct[] getProducts(final DateTime requestedDate) throws CatalogApiException {
+        return versionForDate(requestedDate).getCurrentProducts();
+    }
+
+    @Override
+    public Currency[] getSupportedCurrencies(final DateTime requestedDate) throws CatalogApiException {
+        return versionForDate(requestedDate).getCurrentSupportedCurrencies();
+    }
+
+    @Override
+    public DefaultPlan[] getPlans(final DateTime requestedDate) throws CatalogApiException {
+        return versionForDate(requestedDate).getCurrentPlans();
+    }
+
+    //
+    // Find a plan
+    //
+    @Override
+    public Plan findPlan(final String name,
+                         final DateTime requestedDate)
+            throws CatalogApiException {
+        return versionForDate(requestedDate).findCurrentPlan(name);
+    }
+
+    @Override
+    public Plan findPlan(final String productName,
+                         final BillingPeriod term,
+                         final String priceListName,
+                         final DateTime requestedDate)
+            throws CatalogApiException {
+        return versionForDate(requestedDate).findCurrentPlan(productName, term, priceListName);
+    }
+
+    @Override
+    public Plan findPlan(final String name,
+                         final DateTime requestedDate,
+                         final DateTime subscriptionStartDate)
+            throws CatalogApiException {
+        return findPlan(new PlanRequestWrapper(name), requestedDate, subscriptionStartDate);
+    }
+
+    @Override
+    public Plan findPlan(final String productName,
+                         final BillingPeriod term,
+                         final String priceListName,
+                         final DateTime requestedDate,
+                         final DateTime subscriptionStartDate)
+            throws CatalogApiException {
+        return findPlan(new PlanRequestWrapper(productName, term, priceListName), requestedDate, subscriptionStartDate);
+    }
+
+    //
+    // Find a product
+    //
+    @Override
+    public Product findProduct(final String name, final DateTime requestedDate) throws CatalogApiException {
+        return versionForDate(requestedDate).findCurrentProduct(name);
+    }
 
 
     //
     // Find a phase
     //
-	@Override
-	public PlanPhase findPhase(String phaseName, 
-			DateTime requestedDate,
-			DateTime subscriptionStartDate) 
-					throws CatalogApiException {
-		String planName = DefaultPlanPhase.planName(phaseName);
-		Plan plan = findPlan(planName, requestedDate, subscriptionStartDate);
-		return plan.findPhase(phaseName);
-	}
-	
-	
-	//
+    @Override
+    public PlanPhase findPhase(final String phaseName,
+                               final DateTime requestedDate,
+                               final DateTime subscriptionStartDate)
+            throws CatalogApiException {
+        final String planName = DefaultPlanPhase.planName(phaseName);
+        final Plan plan = findPlan(planName, requestedDate, subscriptionStartDate);
+        return plan.findPhase(phaseName);
+    }
+
+
+    //
     // Find a price list
     //
     @Override
-    public PriceList findPriceList(String name, DateTime requestedDate)
+    public PriceList findPriceList(final String name, final DateTime requestedDate)
             throws CatalogApiException {
         return versionForDate(requestedDate).findCurrentPriceList(name);
     }
 
- 
+
     //
     // Rules
     //
-	@Override
-	public ActionPolicy planChangePolicy(PlanPhaseSpecifier from,
-			PlanSpecifier to, DateTime requestedDate) throws CatalogApiException {
-		return versionForDate(requestedDate).planChangePolicy(from, to);
-	}
-
-	@Override
-	public ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase, DateTime requestedDate) throws CatalogApiException {
-		return versionForDate(requestedDate).planCancelPolicy(planPhase);
-	}
-
-	@Override
-	public PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from,
-			PlanSpecifier to, DateTime requestedDate) throws CatalogApiException {
-		return versionForDate(requestedDate).planChangeAlignment(from, to);
-	}
-
-	@Override
-	public PlanAlignmentCreate planCreateAlignment(PlanSpecifier specifier, DateTime requestedDate) throws CatalogApiException {
-		return versionForDate(requestedDate).planCreateAlignment(specifier);
-	}
-
-	
-
-	@Override
-	public BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase, DateTime requestedDate) throws CatalogApiException {
-		return versionForDate(requestedDate).billingAlignment(planPhase);
-	}
-
-	@Override
-	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to, DateTime requestedDate)
-			throws CatalogApiException {
-		return versionForDate(requestedDate).planChange(from, to);
-	}
-
-	@Override
-	public boolean canCreatePlan(PlanSpecifier specifier, DateTime requestedDate)
-			throws CatalogApiException {
-		return versionForDate(requestedDate).canCreatePlan(specifier);
-	}
-
-	//
-	// VerifiableConfig API
-	//
-	@Override
-	public void initialize(StandaloneCatalog catalog, URI sourceURI) {
-		for(StandaloneCatalog c : versions) {
-			c.initialize(catalog, sourceURI);
-		}
-	}
-
-	@Override
-	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
-		for(StandaloneCatalog c : versions) {
-			errors.addAll(c.validate(c, errors));
-		}
-		//TODO MDW validation - ensure all catalog versions have a single name
-		//TODO MDW validation - ensure effective dates are different (actually do we want this?)
-		//TODO MDW validation - check that all products are there
-		//TODO MDW validation - check that all plans are there
-		//TODO MDW validation - check that all currencies are there
-		//TODO MDW validation - check that all pricelists are there
-		return errors;
-	}
-
-	//
-	// Static catalog API
-	//
-	@Override
-	public Date getEffectiveDate() throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).getEffectiveDate();
-	}
-
-	@Override
-	public Currency[] getCurrentSupportedCurrencies() throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).getCurrentSupportedCurrencies();
-	}
-
-	@Override
-	public Product[] getCurrentProducts() throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).getCurrentProducts() ;
-	}
-
-	@Override
-	public Plan[] getCurrentPlans() throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).getCurrentPlans();
-	}
-
-	@Override
-	public Plan findCurrentPlan(String productName, BillingPeriod term,
-			String priceList) throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).findCurrentPlan(productName, term, priceList);
-	}
-
-	@Override
-	public Plan findCurrentPlan(String name) throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).findCurrentPlan(name);
-	}
-
-	@Override
-	public Product findCurrentProduct(String name) throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).findCurrentProduct(name);
-	}
-
-	@Override
-	public PlanPhase findCurrentPhase(String name) throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).findCurrentPhase(name);
-	}
-	
-
-    @Override
-    public PriceList findCurrentPricelist(String name)
+    @Override
+    public ActionPolicy planChangePolicy(final PlanPhaseSpecifier from,
+                                         final PlanSpecifier to, final DateTime requestedDate) throws CatalogApiException {
+        return versionForDate(requestedDate).planChangePolicy(from, to);
+    }
+
+    @Override
+    public ActionPolicy planCancelPolicy(final PlanPhaseSpecifier planPhase, final DateTime requestedDate) throws CatalogApiException {
+        return versionForDate(requestedDate).planCancelPolicy(planPhase);
+    }
+
+    @Override
+    public PlanAlignmentChange planChangeAlignment(final PlanPhaseSpecifier from,
+                                                   final PlanSpecifier to, final DateTime requestedDate) throws CatalogApiException {
+        return versionForDate(requestedDate).planChangeAlignment(from, to);
+    }
+
+    @Override
+    public PlanAlignmentCreate planCreateAlignment(final PlanSpecifier specifier, final DateTime requestedDate) throws CatalogApiException {
+        return versionForDate(requestedDate).planCreateAlignment(specifier);
+    }
+
+
+    @Override
+    public BillingAlignment billingAlignment(final PlanPhaseSpecifier planPhase, final DateTime requestedDate) throws CatalogApiException {
+        return versionForDate(requestedDate).billingAlignment(planPhase);
+    }
+
+    @Override
+    public PlanChangeResult planChange(final PlanPhaseSpecifier from, final PlanSpecifier to, final DateTime requestedDate)
+            throws CatalogApiException {
+        return versionForDate(requestedDate).planChange(from, to);
+    }
+
+    @Override
+    public boolean canCreatePlan(final PlanSpecifier specifier, final DateTime requestedDate)
+            throws CatalogApiException {
+        return versionForDate(requestedDate).canCreatePlan(specifier);
+    }
+
+    //
+    // VerifiableConfig API
+    //
+    @Override
+    public void initialize(final StandaloneCatalog catalog, final URI sourceURI) {
+        for (final StandaloneCatalog c : versions) {
+            c.initialize(catalog, sourceURI);
+        }
+    }
+
+    @Override
+    public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
+        for (final StandaloneCatalog c : versions) {
+            errors.addAll(c.validate(c, errors));
+        }
+        //TODO MDW validation - ensure all catalog versions have a single name
+        //TODO MDW validation - ensure effective dates are different (actually do we want this?)
+        //TODO MDW validation - check that all products are there
+        //TODO MDW validation - check that all plans are there
+        //TODO MDW validation - check that all currencies are there
+        //TODO MDW validation - check that all pricelists are there
+        return errors;
+    }
+
+    //
+    // Static catalog API
+    //
+    @Override
+    public Date getEffectiveDate() throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).getEffectiveDate();
+    }
+
+    @Override
+    public Currency[] getCurrentSupportedCurrencies() throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).getCurrentSupportedCurrencies();
+    }
+
+    @Override
+    public Product[] getCurrentProducts() throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).getCurrentProducts();
+    }
+
+    @Override
+    public Plan[] getCurrentPlans() throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).getCurrentPlans();
+    }
+
+    @Override
+    public Plan findCurrentPlan(final String productName, final BillingPeriod term,
+                                final String priceList) throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).findCurrentPlan(productName, term, priceList);
+    }
+
+    @Override
+    public Plan findCurrentPlan(final String name) throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).findCurrentPlan(name);
+    }
+
+    @Override
+    public Product findCurrentProduct(final String name) throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).findCurrentProduct(name);
+    }
+
+    @Override
+    public PlanPhase findCurrentPhase(final String name) throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).findCurrentPhase(name);
+    }
+
+
+    @Override
+    public PriceList findCurrentPricelist(final String name)
             throws CatalogApiException {
         return versionForDate(clock.getUTCNow()).findCurrentPriceList(name);
     }
 
-	@Override
-	public ActionPolicy planChangePolicy(PlanPhaseSpecifier from,
-			PlanSpecifier to) throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).planChangePolicy(from, to);
-	}
-
-	@Override
-	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to)
-			throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).planChange(from, to);
-	}
-
-	@Override
-	public ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase)
-			throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).planCancelPolicy(planPhase);
-	}
-
-	@Override
-	public PlanAlignmentCreate planCreateAlignment(PlanSpecifier specifier)
-			throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).planCreateAlignment(specifier);
-	}
-
-	@Override
-	public BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase)
-			throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).billingAlignment(planPhase);
-	}
-
-	@Override
-	public PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from,
-			PlanSpecifier to) throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).planChangeAlignment(from, to);
-	}
-
-	@Override
-	public boolean canCreatePlan(PlanSpecifier specifier)
-			throws CatalogApiException {
-		return versionForDate(clock.getUTCNow()).canCreatePlan(specifier);
-	}
-
-    @Override
-    public List<Listing> getAvailableAddonListings(String baseProductName) throws CatalogApiException {
+    @Override
+    public ActionPolicy planChangePolicy(final PlanPhaseSpecifier from,
+                                         final PlanSpecifier to) throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).planChangePolicy(from, to);
+    }
+
+    @Override
+    public PlanChangeResult planChange(final PlanPhaseSpecifier from, final PlanSpecifier to)
+            throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).planChange(from, to);
+    }
+
+    @Override
+    public ActionPolicy planCancelPolicy(final PlanPhaseSpecifier planPhase)
+            throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).planCancelPolicy(planPhase);
+    }
+
+    @Override
+    public PlanAlignmentCreate planCreateAlignment(final PlanSpecifier specifier)
+            throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).planCreateAlignment(specifier);
+    }
+
+    @Override
+    public BillingAlignment billingAlignment(final PlanPhaseSpecifier planPhase)
+            throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).billingAlignment(planPhase);
+    }
+
+    @Override
+    public PlanAlignmentChange planChangeAlignment(final PlanPhaseSpecifier from,
+                                                   final PlanSpecifier to) throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).planChangeAlignment(from, to);
+    }
+
+    @Override
+    public boolean canCreatePlan(final PlanSpecifier specifier)
+            throws CatalogApiException {
+        return versionForDate(clock.getUTCNow()).canCreatePlan(specifier);
+    }
+
+    @Override
+    public List<Listing> getAvailableAddonListings(final String baseProductName) throws CatalogApiException {
         return versionForDate(clock.getUTCNow()).getAvailableAddonListings(baseProductName);
     }
 
diff --git a/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java b/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java
index 4367c9a..b037f6e 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java
@@ -16,28 +16,28 @@
 
 package com.ning.billing.catalog;
 
-import com.ning.billing.util.config.XMLSchemaGenerator;
-
 import java.io.File;
 import java.io.FileWriter;
 import java.io.Writer;
 
+import com.ning.billing.util.config.XMLSchemaGenerator;
+
 public class CreateCatalogSchema {
 
-	/**
-	 * @param args
-	 */
-	public static void main(String[] args) throws Exception {
-		if(args.length != 1) {
-			System.err.println("Usage: <filepath>");
-			System.exit(0);
-		}
-		
-		File f = new File(args[0]);
-		Writer w = new FileWriter(f);
-		w.write(XMLSchemaGenerator.xmlSchemaAsString(StandaloneCatalog.class));
-		w.close();
-
-	}
+    /**
+     * @param args
+     */
+    public static void main(final String[] args) throws Exception {
+        if (args.length != 1) {
+            System.err.println("Usage: <filepath>");
+            System.exit(0);
+        }
+
+        final File f = new File(args[0]);
+        final Writer w = new FileWriter(f);
+        w.write(XMLSchemaGenerator.xmlSchemaAsString(StandaloneCatalog.class));
+        w.close();
+
+    }
 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/io/TestVersionedCatalogLoader.java b/catalog/src/test/java/com/ning/billing/catalog/io/TestVersionedCatalogLoader.java
index 0d5ac66..dc2b28b 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/io/TestVersionedCatalogLoader.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/io/TestVersionedCatalogLoader.java
@@ -15,16 +15,6 @@
  */
 package com.ning.billing.catalog.io;
 
-import com.google.common.io.Resources;
-import com.ning.billing.catalog.StandaloneCatalog;
-import com.ning.billing.catalog.VersionedCatalog;
-import com.ning.billing.catalog.api.InvalidConfigException;
-import com.ning.billing.lifecycle.KillbillService.ServiceException;
-import com.ning.billing.util.clock.DefaultClock;
-import org.joda.time.DateTime;
-import org.testng.annotations.Test;
-import org.xml.sax.SAXException;
-
 import javax.xml.bind.JAXBException;
 import javax.xml.transform.TransformerException;
 import java.io.IOException;
@@ -35,99 +25,108 @@ import java.net.URL;
 import java.util.Iterator;
 import java.util.List;
 
+import org.joda.time.DateTime;
+import org.testng.annotations.Test;
+import org.xml.sax.SAXException;
+
+import com.google.common.io.Resources;
+import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.VersionedCatalog;
+import com.ning.billing.catalog.api.InvalidConfigException;
+import com.ning.billing.lifecycle.KillbillService.ServiceException;
+import com.ning.billing.util.clock.DefaultClock;
+
 import static org.testng.AssertJUnit.assertEquals;
 
 public class TestVersionedCatalogLoader {
-	private final VersionedCatalogLoader loader = new VersionedCatalogLoader(new DefaultClock());
-
-	
-	@Test(enabled=true)
-	public void testAppendToURI() throws MalformedURLException, IOException, URISyntaxException {
-		URL u1 = new URL("http://www.ning.com/foo");
-		assertEquals("http://www.ning.com/foo/bar",loader.appendToURI(u1, "bar").toString());
-
-		URL u2 = new URL("http://www.ning.com/foo/");
-		assertEquals("http://www.ning.com/foo/bar",loader.appendToURI(u2, "bar").toString());
-		
-	}
-	
-	
-
-	
-	@Test(enabled=true)
-	public void testFindXmlFileReferences() throws MalformedURLException, URISyntaxException {
-		String page = "dg.xml\n" + 
-				"replica.foo\n" + 
-				"snv1/\n" + 
-				"viking.xml\n" ;
-		List<URI> urls = loader.findXmlFileReferences(page, new URL("http://ning.com/"));
-		assertEquals(2, urls.size());
-		assertEquals("http://ning.com/dg.xml", urls.get(0).toString());
-		assertEquals("http://ning.com/viking.xml", urls.get(1).toString());
-		
-	}
-	
-	@Test(enabled=true)
-	public void testExtractHrefs() {
-		String page = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">" + 
-				"<html>" + 
-				" <head>" + 
-				"  <title>Index of /config/trunk/xno</title>" + 
-				" </head>" + 
-				" <body>" + 
-				"<h1>Index of /config/trunk/xno</h1>" + 
-				"<ul><li><a href=\"/config/trunk/\"> Parent Directory</a></li>" + 
-				"<li><a href=\"dg.xml\"> dg.xml</a></li>" + 
-				"<li><a href=\"replica.foo\"> replica/</a></li>" + 
-				"<li><a href=\"replica2/\"> replica2/</a></li>" + 
-				"<li><a href=\"replica_dyson/\"> replica_dyson/</a></li>" + 
-				"<li><a href=\"snv1/\"> snv1/</a></li>" + 
-				"<li><a href=\"viking.xml\"> viking.xml</a></li>" + 
-				"</ul>" + 
-				"<address>Apache/2.2.3 (CentOS) Server at <a href=\"mailto:kate@ning.com\">gepo.ningops.net</a> Port 80</address>" + 
-				"</body></html>" ;
-		List<String> hrefs = loader.extractHrefs(page);
-		assertEquals(8, hrefs.size());
-		assertEquals("/config/trunk/", hrefs.get(0));
-		assertEquals("dg.xml", hrefs.get(1));
-	}
-	
-	@Test(enabled=true)
-	public void testFindXmlUrlReferences() throws MalformedURLException, URISyntaxException {
-		String page = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">" + 
-				"<html>" + 
-				" <head>" + 
-				"  <title>Index of /config/trunk/xno</title>" + 
-				" </head>" + 
-				" <body>" + 
-				"<h1>Index of /config/trunk/xno</h1>" + 
-				"<ul><li><a href=\"/config/trunk/\"> Parent Directory</a></li>" + 
-				"<li><a href=\"dg.xml\"> dg.xml</a></li>" + 
-				"<li><a href=\"replica.foo\"> replica/</a></li>" + 
-				"<li><a href=\"replica2/\"> replica2/</a></li>" + 
-				"<li><a href=\"replica_dyson/\"> replica_dyson/</a></li>" + 
-				"<li><a href=\"snv1/\"> snv1/</a></li>" + 
-				"<li><a href=\"viking.xml\"> viking.xml</a></li>" + 
-				"</ul>" + 
-				"<address>Apache/2.2.3 (CentOS) Server at <a href=\"mailto:kate@ning.com\">gepo.ningops.net</a> Port 80</address>" + 
-				"</body></html>" ;
-		List<URI> uris = loader.findXmlUrlReferences(page, new URL("http://ning.com/"));
-		assertEquals(2, uris.size());
-		assertEquals("http://ning.com/dg.xml", uris.get(0).toString());
-		assertEquals("http://ning.com/viking.xml", uris.get(1).toString());
-		
-	}
-	
-	@Test(enabled=true)
-	public void testLoad() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException {
-		VersionedCatalog c = loader.load(Resources.getResource("versionedCatalog").toString());
-		assertEquals(3, c.size());
-		Iterator<StandaloneCatalog> it = c.iterator();
-		DateTime dt = new DateTime("2011-01-01T00:00:00+00:00");
-		assertEquals(dt.toDate(),it.next().getEffectiveDate());
-		dt = new DateTime("2011-02-02T00:00:00+00:00");
-		assertEquals(dt.toDate(),it.next().getEffectiveDate());
-		dt = new DateTime("2011-03-03T00:00:00+00:00");
-		assertEquals(dt.toDate(),it.next().getEffectiveDate());
-	}
+    private final VersionedCatalogLoader loader = new VersionedCatalogLoader(new DefaultClock());
+
+
+    @Test(enabled = true)
+    public void testAppendToURI() throws MalformedURLException, IOException, URISyntaxException {
+        final URL u1 = new URL("http://www.ning.com/foo");
+        assertEquals("http://www.ning.com/foo/bar", loader.appendToURI(u1, "bar").toString());
+
+        final URL u2 = new URL("http://www.ning.com/foo/");
+        assertEquals("http://www.ning.com/foo/bar", loader.appendToURI(u2, "bar").toString());
+
+    }
+
+
+    @Test(enabled = true)
+    public void testFindXmlFileReferences() throws MalformedURLException, URISyntaxException {
+        final String page = "dg.xml\n" +
+                "replica.foo\n" +
+                "snv1/\n" +
+                "viking.xml\n";
+        final List<URI> urls = loader.findXmlFileReferences(page, new URL("http://ning.com/"));
+        assertEquals(2, urls.size());
+        assertEquals("http://ning.com/dg.xml", urls.get(0).toString());
+        assertEquals("http://ning.com/viking.xml", urls.get(1).toString());
+
+    }
+
+    @Test(enabled = true)
+    public void testExtractHrefs() {
+        final String page = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">" +
+                "<html>" +
+                " <head>" +
+                "  <title>Index of /config/trunk/xno</title>" +
+                " </head>" +
+                " <body>" +
+                "<h1>Index of /config/trunk/xno</h1>" +
+                "<ul><li><a href=\"/config/trunk/\"> Parent Directory</a></li>" +
+                "<li><a href=\"dg.xml\"> dg.xml</a></li>" +
+                "<li><a href=\"replica.foo\"> replica/</a></li>" +
+                "<li><a href=\"replica2/\"> replica2/</a></li>" +
+                "<li><a href=\"replica_dyson/\"> replica_dyson/</a></li>" +
+                "<li><a href=\"snv1/\"> snv1/</a></li>" +
+                "<li><a href=\"viking.xml\"> viking.xml</a></li>" +
+                "</ul>" +
+                "<address>Apache/2.2.3 (CentOS) Server at <a href=\"mailto:kate@ning.com\">gepo.ningops.net</a> Port 80</address>" +
+                "</body></html>";
+        final List<String> hrefs = loader.extractHrefs(page);
+        assertEquals(8, hrefs.size());
+        assertEquals("/config/trunk/", hrefs.get(0));
+        assertEquals("dg.xml", hrefs.get(1));
+    }
+
+    @Test(enabled = true)
+    public void testFindXmlUrlReferences() throws MalformedURLException, URISyntaxException {
+        final String page = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">" +
+                "<html>" +
+                " <head>" +
+                "  <title>Index of /config/trunk/xno</title>" +
+                " </head>" +
+                " <body>" +
+                "<h1>Index of /config/trunk/xno</h1>" +
+                "<ul><li><a href=\"/config/trunk/\"> Parent Directory</a></li>" +
+                "<li><a href=\"dg.xml\"> dg.xml</a></li>" +
+                "<li><a href=\"replica.foo\"> replica/</a></li>" +
+                "<li><a href=\"replica2/\"> replica2/</a></li>" +
+                "<li><a href=\"replica_dyson/\"> replica_dyson/</a></li>" +
+                "<li><a href=\"snv1/\"> snv1/</a></li>" +
+                "<li><a href=\"viking.xml\"> viking.xml</a></li>" +
+                "</ul>" +
+                "<address>Apache/2.2.3 (CentOS) Server at <a href=\"mailto:kate@ning.com\">gepo.ningops.net</a> Port 80</address>" +
+                "</body></html>";
+        final List<URI> uris = loader.findXmlUrlReferences(page, new URL("http://ning.com/"));
+        assertEquals(2, uris.size());
+        assertEquals("http://ning.com/dg.xml", uris.get(0).toString());
+        assertEquals("http://ning.com/viking.xml", uris.get(1).toString());
+
+    }
+
+    @Test(enabled = true)
+    public void testLoad() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException {
+        final VersionedCatalog c = loader.load(Resources.getResource("versionedCatalog").toString());
+        assertEquals(3, c.size());
+        final Iterator<StandaloneCatalog> it = c.iterator();
+        DateTime dt = new DateTime("2011-01-01T00:00:00+00:00");
+        assertEquals(dt.toDate(), it.next().getEffectiveDate());
+        dt = new DateTime("2011-02-02T00:00:00+00:00");
+        assertEquals(dt.toDate(), it.next().getEffectiveDate());
+        dt = new DateTime("2011-03-03T00:00:00+00:00");
+        assertEquals(dt.toDate(), it.next().getEffectiveDate());
+    }
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java b/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java
index 77f7248..b03f18b 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java
@@ -16,17 +16,18 @@
 
 package com.ning.billing.catalog.io;
 
+import org.testng.annotations.Test;
+
 import com.google.common.io.Resources;
 import com.ning.billing.catalog.StandaloneCatalog;
 import com.ning.billing.util.config.XMLLoader;
-import org.testng.annotations.Test;
 
 public class TestXMLReader {
 
-	@Test(enabled=true)
-	public void testCatalogLoad() throws Exception {
-		XMLLoader.getObjectFromString(Resources.getResource("WeaponsHire.xml").toExternalForm(), StandaloneCatalog.class);
-		XMLLoader.getObjectFromString(Resources.getResource("WeaponsHireSmall.xml").toExternalForm(), StandaloneCatalog.class);
-	}
-	
+    @Test(enabled = true)
+    public void testCatalogLoad() throws Exception {
+        XMLLoader.getObjectFromString(Resources.getResource("WeaponsHire.xml").toExternalForm(), StandaloneCatalog.class);
+        XMLLoader.getObjectFromString(Resources.getResource("WeaponsHireSmall.xml").toExternalForm(), StandaloneCatalog.class);
+    }
+
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java b/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
index ac090de..c4e1f84 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
@@ -42,195 +42,194 @@ import com.ning.billing.catalog.rules.CaseCreateAlignment;
 import com.ning.billing.catalog.rules.PlanRules;
 
 public class MockCatalog extends StandaloneCatalog implements Catalog {
-	private static final String[] PRODUCT_NAMES = new String[]{ "TestProduct1", "TestProduct2", "TestProduct3"};
+    private static final String[] PRODUCT_NAMES = new String[]{"TestProduct1", "TestProduct2", "TestProduct3"};
     private boolean canCreatePlan;
     private PlanChangeResult planChange;
     private BillingAlignment billingAlignment;
     private PlanAlignmentCreate planCreateAlignment;
-	
-	public MockCatalog() {
-		setEffectiveDate(new Date());
-		setProducts(MockProduct.createAll());
-		setPlans((DefaultPlan[])MockPlan.createAll());
-		populateRules();
-		populatePriceLists();
-	}
-
-    public void populateRules(){
-		setPlanRules(new PlanRules());
-	}
-
-	public void setRules( 
-			CaseChangePlanPolicy[] caseChangePlanPolicy,
-			CaseChangePlanAlignment[] caseChangePlanAlignment,
-			CaseCancelPolicy[] caseCancelPolicy,
-			CaseCreateAlignment[] caseCreateAlignment
-			){
-		
-	}
-	
-	
-
-	public void populatePriceLists() {
-		DefaultPlan[] plans = getCurrentPlans();
-		
-		DefaultPriceList[] priceList = new DefaultPriceList[plans.length - 1];
-		for(int i = 1; i < plans.length; i++) {
-			priceList[i-1] = new DefaultPriceList(new DefaultPlan[]{plans[i]},plans[i].getName()+ "-pl");
-		}
-		
-		DefaultPriceListSet set = new DefaultPriceListSet(new PriceListDefault(new DefaultPlan[]{plans[0]}),priceList);
-		setPriceLists(set);
-	}
-	
-	public String[] getProductNames() {
-		return PRODUCT_NAMES;
-	}
-
-    @Override
-    public Currency[] getSupportedCurrencies(DateTime requestedDate) throws CatalogApiException {
+
+    public MockCatalog() {
+        setEffectiveDate(new Date());
+        setProducts(MockProduct.createAll());
+        setPlans((DefaultPlan[]) MockPlan.createAll());
+        populateRules();
+        populatePriceLists();
+    }
+
+    public void populateRules() {
+        setPlanRules(new PlanRules());
+    }
+
+    public void setRules(
+            final CaseChangePlanPolicy[] caseChangePlanPolicy,
+            final CaseChangePlanAlignment[] caseChangePlanAlignment,
+            final CaseCancelPolicy[] caseCancelPolicy,
+            final CaseCreateAlignment[] caseCreateAlignment
+                        ) {
+
+    }
+
+
+    public void populatePriceLists() {
+        final DefaultPlan[] plans = getCurrentPlans();
+
+        final DefaultPriceList[] priceList = new DefaultPriceList[plans.length - 1];
+        for (int i = 1; i < plans.length; i++) {
+            priceList[i - 1] = new DefaultPriceList(new DefaultPlan[]{plans[i]}, plans[i].getName() + "-pl");
+        }
+
+        final DefaultPriceListSet set = new DefaultPriceListSet(new PriceListDefault(new DefaultPlan[]{plans[0]}), priceList);
+        setPriceLists(set);
+    }
+
+    public String[] getProductNames() {
+        return PRODUCT_NAMES;
+    }
+
+    @Override
+    public Currency[] getSupportedCurrencies(final DateTime requestedDate) throws CatalogApiException {
         return getCurrentSupportedCurrencies();
     }
 
     @Override
-    public Product[] getProducts(DateTime requestedDate) throws CatalogApiException {
-       return getCurrentProducts();
+    public Product[] getProducts(final DateTime requestedDate) throws CatalogApiException {
+        return getCurrentProducts();
     }
 
     @Override
-    public Plan[] getPlans(DateTime requestedDate) throws CatalogApiException {
+    public Plan[] getPlans(final DateTime requestedDate) throws CatalogApiException {
         return getCurrentPlans();
     }
 
     @Override
-    public Plan findPlan(String name, DateTime requestedDate) throws CatalogApiException {
+    public Plan findPlan(final String name, final DateTime requestedDate) throws CatalogApiException {
         return findCurrentPlan(name);
     }
 
     @Override
-    public Plan findPlan(String productName, BillingPeriod term, String priceListName, DateTime requestedDate)
+    public Plan findPlan(final String productName, final BillingPeriod term, final String priceListName, final DateTime requestedDate)
             throws CatalogApiException {
         return findCurrentPlan(productName, term, priceListName);
     }
 
     @Override
-    public Plan findPlan(String name, DateTime effectiveDate, DateTime subscriptionStartDate)
+    public Plan findPlan(final String name, final DateTime effectiveDate, final DateTime subscriptionStartDate)
             throws CatalogApiException {
         return findCurrentPlan(name);
     }
 
     @Override
-    public Plan findPlan(String productName, BillingPeriod term, String priceListName, DateTime requestedDate,
-            DateTime subscriptionStartDate) throws CatalogApiException {
-       return findCurrentPlan(productName, term, priceListName);
+    public Plan findPlan(final String productName, final BillingPeriod term, final String priceListName, final DateTime requestedDate,
+                         final DateTime subscriptionStartDate) throws CatalogApiException {
+        return findCurrentPlan(productName, term, priceListName);
     }
-    
+
     @Override
-    public Product findProduct(String name, DateTime requestedDate) throws CatalogApiException {
+    public Product findProduct(final String name, final DateTime requestedDate) throws CatalogApiException {
         return findCurrentProduct(name);
     }
 
     @Override
-    public PlanPhase findPhase(String name, DateTime requestedDate, DateTime subscriptionStartDate)
+    public PlanPhase findPhase(final String name, final DateTime requestedDate, final DateTime subscriptionStartDate)
             throws CatalogApiException {
         return findCurrentPhase(name);
     }
 
     @Override
-    public PriceList findPriceList(String name, DateTime requestedDate) throws CatalogApiException {
+    public PriceList findPriceList(final String name, final DateTime requestedDate) throws CatalogApiException {
         return findCurrentPricelist(name);
     }
 
     @Override
-    public ActionPolicy planChangePolicy(PlanPhaseSpecifier from, PlanSpecifier to, DateTime requestedDate)
+    public ActionPolicy planChangePolicy(final PlanPhaseSpecifier from, final PlanSpecifier to, final DateTime requestedDate)
             throws CatalogApiException {
         return planChangePolicy(from, to);
     }
 
     @Override
-    public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to, DateTime requestedDate)
+    public PlanChangeResult planChange(final PlanPhaseSpecifier from, final PlanSpecifier to, final DateTime requestedDate)
             throws CatalogApiException {
         return planChange(from, to);
     }
 
     @Override
-    public ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase, DateTime requestedDate)
+    public ActionPolicy planCancelPolicy(final PlanPhaseSpecifier planPhase, final DateTime requestedDate)
             throws CatalogApiException {
         return planCancelPolicy(planPhase);
     }
 
     @Override
-    public PlanAlignmentCreate planCreateAlignment(PlanSpecifier specifier, DateTime requestedDate)
+    public PlanAlignmentCreate planCreateAlignment(final PlanSpecifier specifier, final DateTime requestedDate)
             throws CatalogApiException {
-        return planCreateAlignment(specifier);  
+        return planCreateAlignment(specifier);
     }
 
     @Override
-    public BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase, DateTime requestedDate)
+    public BillingAlignment billingAlignment(final PlanPhaseSpecifier planPhase, final DateTime requestedDate)
             throws CatalogApiException {
         return billingAlignment(planPhase);
     }
 
     @Override
-    public PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from, PlanSpecifier to, DateTime requestedDate)
+    public PlanAlignmentChange planChangeAlignment(final PlanPhaseSpecifier from, final PlanSpecifier to, final DateTime requestedDate)
             throws CatalogApiException {
         return planChangeAlignment(from, to);
     }
 
     @Override
-    public boolean canCreatePlan(PlanSpecifier specifier, DateTime requestedDate) throws CatalogApiException {
+    public boolean canCreatePlan(final PlanSpecifier specifier, final DateTime requestedDate) throws CatalogApiException {
         return canCreatePlan(specifier);
     }
 
     @Override
-    public ActionPolicy planChangePolicy(PlanPhaseSpecifier from, PlanSpecifier to) throws CatalogApiException {
+    public ActionPolicy planChangePolicy(final PlanPhaseSpecifier from, final PlanSpecifier to) throws CatalogApiException {
         return super.planChangePolicy(from, to);
     }
 
     @Override
-    public PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from, PlanSpecifier to)
+    public PlanAlignmentChange planChangeAlignment(final PlanPhaseSpecifier from, final PlanSpecifier to)
             throws CatalogApiException {
         return super.planChangeAlignment(from, to);
     }
 
     @Override
-    public ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase) throws CatalogApiException {
+    public ActionPolicy planCancelPolicy(final PlanPhaseSpecifier planPhase) throws CatalogApiException {
         return super.planCancelPolicy(planPhase);
     }
 
     @Override
-    public PlanAlignmentCreate planCreateAlignment(PlanSpecifier specifier) throws CatalogApiException {
+    public PlanAlignmentCreate planCreateAlignment(final PlanSpecifier specifier) throws CatalogApiException {
         return planCreateAlignment;
     }
 
     @Override
-    public BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase) throws CatalogApiException {
+    public BillingAlignment billingAlignment(final PlanPhaseSpecifier planPhase) throws CatalogApiException {
         return billingAlignment;
     }
 
     @Override
-    public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to) throws CatalogApiException {
+    public PlanChangeResult planChange(final PlanPhaseSpecifier from, final PlanSpecifier to) throws CatalogApiException {
         return planChange;
     }
 
     @Override
-    public boolean canCreatePlan(PlanSpecifier specifier) throws CatalogApiException {
+    public boolean canCreatePlan(final PlanSpecifier specifier) throws CatalogApiException {
         return canCreatePlan;
     }
 
-    public void setCanCreatePlan(boolean canCreatePlan) {
+    public void setCanCreatePlan(final boolean canCreatePlan) {
         this.canCreatePlan = canCreatePlan;
     }
 
-    public void setPlanChange(PlanChangeResult planChange) {
+    public void setPlanChange(final PlanChangeResult planChange) {
         this.planChange = planChange;
     }
 
-    public void setBillingAlignment(BillingAlignment billingAlignment) {
+    public void setBillingAlignment(final BillingAlignment billingAlignment) {
         this.billingAlignment = billingAlignment;
     }
 
-    public void setPlanCreateAlignment(PlanAlignmentCreate planCreateAlignment) {
+    public void setPlanCreateAlignment(final PlanAlignmentCreate planCreateAlignment) {
         this.planCreateAlignment = planCreateAlignment;
     }
 
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockCatalogModule.java b/catalog/src/test/java/com/ning/billing/catalog/MockCatalogModule.java
index d61d6ae..4af0136 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockCatalogModule.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockCatalogModule.java
@@ -28,12 +28,12 @@ public class MockCatalogModule extends AbstractModule {
     protected void configure() {
         CatalogService catalogService = BrainDeadProxyFactory.createBrainDeadProxyFor(CatalogService.class);
         ((ZombieControl) catalogService).addResult("getCurrentCatalog", new MockCatalog());
-        
+
         catalogService = BrainDeadProxyFactory.createBrainDeadProxyFor(CatalogService.class);
-        Catalog catalog = BrainDeadProxyFactory.createBrainDeadProxyFor(Catalog.class);
+        final Catalog catalog = BrainDeadProxyFactory.createBrainDeadProxyFor(Catalog.class);
+
+        ((ZombieControl) catalogService).addResult("getFullCatalog", catalog);
 
-        ((ZombieControl) catalogService).addResult("getFullCatalog", catalog); 
-        
         bind(CatalogService.class).toInstance(catalogService);
     }
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockCatalogService.java b/catalog/src/test/java/com/ning/billing/catalog/MockCatalogService.java
index f7277c7..ddd235c 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockCatalogService.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockCatalogService.java
@@ -22,9 +22,9 @@ import com.ning.billing.catalog.api.StaticCatalog;
 
 public class MockCatalogService extends DefaultCatalogService {
 
-    private MockCatalog catalog;
+    private final MockCatalog catalog;
 
-    public MockCatalogService(MockCatalog catalog) {
+    public MockCatalogService(final MockCatalog catalog) {
         super(null, null);
         this.catalog = catalog;
     }
@@ -45,7 +45,7 @@ public class MockCatalogService extends DefaultCatalogService {
 
     @Override
     public Catalog get() {
-         return catalog;
+        return catalog;
     }
 
     @Override
@@ -53,5 +53,5 @@ public class MockCatalogService extends DefaultCatalogService {
         return catalog;
     }
 
-    
+
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java b/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java
index 3df36aa..b94b713 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java
@@ -21,21 +21,21 @@ import java.math.BigDecimal;
 import com.ning.billing.catalog.api.Currency;
 
 public class MockInternationalPrice extends DefaultInternationalPrice {
-	
-	public static MockInternationalPrice create0USD() {
-		return new MockInternationalPrice(new DefaultPrice().setCurrency(Currency.USD).setValue(BigDecimal.ZERO));
-	}
-	
-	public static MockInternationalPrice create1USD() {
-		return new MockInternationalPrice(new DefaultPrice().setCurrency(Currency.USD).setValue(BigDecimal.ONE));
-	}
-
-	public static MockInternationalPrice createUSD(String value) {
-		return new MockInternationalPrice(new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(value)));
-	}
-
-	public MockInternationalPrice(DefaultPrice... price) {
-		setPrices(price);
-	}
+
+    public static MockInternationalPrice create0USD() {
+        return new MockInternationalPrice(new DefaultPrice().setCurrency(Currency.USD).setValue(BigDecimal.ZERO));
+    }
+
+    public static MockInternationalPrice create1USD() {
+        return new MockInternationalPrice(new DefaultPrice().setCurrency(Currency.USD).setValue(BigDecimal.ONE));
+    }
+
+    public static MockInternationalPrice createUSD(final String value) {
+        return new MockInternationalPrice(new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(value)));
+    }
+
+    public MockInternationalPrice(final DefaultPrice... price) {
+        setPrices(price);
+    }
 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockPlan.java b/catalog/src/test/java/com/ning/billing/catalog/MockPlan.java
index f4dfab1..7774d7c 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockPlan.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockPlan.java
@@ -18,124 +18,122 @@ package com.ning.billing.catalog;
 
 
 public class MockPlan extends DefaultPlan {
-	
-	public static MockPlan createBicycleTrialEvergreen1USD(int trialDurationInDays) {
-		return new MockPlan("BicycleTrialEvergreen1USD",
-				MockProduct.createBicycle(),
-				new DefaultPlanPhase[]{ MockPlanPhase.createTrial(trialDurationInDays) },
-				MockPlanPhase.create1USDMonthlyEvergreen(),
-				-1);
-	}
-
-	
-	public static MockPlan createBicycleTrialEvergreen1USD() {
-		return new MockPlan("BicycleTrialEvergreen1USD",
-				MockProduct.createBicycle(),
-				new DefaultPlanPhase[]{ MockPlanPhase.create30DayTrial() },
-				MockPlanPhase.create1USDMonthlyEvergreen(),
-				-1);
-	}
-
-	public static MockPlan createSportsCarTrialEvergreen100USD() {
-		return new MockPlan("SportsCarTrialEvergreen100USD",
-				MockProduct.createSportsCar(),
-				new DefaultPlanPhase[]{ MockPlanPhase.create30DayTrial() },
-				MockPlanPhase.createUSDMonthlyEvergreen("100.00",null),
-				-1);
-	}
-	
-	public static MockPlan createPickupTrialEvergreen10USD() {
-		return new MockPlan("PickupTrialEvergreen10USD",
-				MockProduct.createPickup(),
-				new DefaultPlanPhase[]{ MockPlanPhase.create30DayTrial() },
-				MockPlanPhase.createUSDMonthlyEvergreen("10.00",null),
-				-1);
-	}
-
-	public static MockPlan createJetTrialEvergreen1000USD() {
-		return new MockPlan("JetTrialEvergreen1000USD",
-				MockProduct.createJet(),
-				new DefaultPlanPhase[]{ MockPlanPhase.create30DayTrial() },
-				MockPlanPhase.create1USDMonthlyEvergreen(),
-				-1);
-	}
+
+    public static MockPlan createBicycleTrialEvergreen1USD(final int trialDurationInDays) {
+        return new MockPlan("BicycleTrialEvergreen1USD",
+                            MockProduct.createBicycle(),
+                            new DefaultPlanPhase[]{MockPlanPhase.createTrial(trialDurationInDays)},
+                            MockPlanPhase.create1USDMonthlyEvergreen(),
+                            -1);
+    }
+
+
+    public static MockPlan createBicycleTrialEvergreen1USD() {
+        return new MockPlan("BicycleTrialEvergreen1USD",
+                            MockProduct.createBicycle(),
+                            new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial()},
+                            MockPlanPhase.create1USDMonthlyEvergreen(),
+                            -1);
+    }
+
+    public static MockPlan createSportsCarTrialEvergreen100USD() {
+        return new MockPlan("SportsCarTrialEvergreen100USD",
+                            MockProduct.createSportsCar(),
+                            new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial()},
+                            MockPlanPhase.createUSDMonthlyEvergreen("100.00", null),
+                            -1);
+    }
+
+    public static MockPlan createPickupTrialEvergreen10USD() {
+        return new MockPlan("PickupTrialEvergreen10USD",
+                            MockProduct.createPickup(),
+                            new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial()},
+                            MockPlanPhase.createUSDMonthlyEvergreen("10.00", null),
+                            -1);
+    }
+
+    public static MockPlan createJetTrialEvergreen1000USD() {
+        return new MockPlan("JetTrialEvergreen1000USD",
+                            MockProduct.createJet(),
+                            new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial()},
+                            MockPlanPhase.create1USDMonthlyEvergreen(),
+                            -1);
+    }
 
     public static MockPlan createJetTrialFixedTermEvergreen1000USD() {
         return new MockPlan("JetTrialEvergreen1000USD",
-                MockProduct.createJet(),
-                new DefaultPlanPhase[]{ MockPlanPhase.create30DayTrial(), MockPlanPhase.createUSDMonthlyFixedTerm("500.00", null, 6) },
-                MockPlanPhase.create1USDMonthlyEvergreen(),
-                -1);
+                            MockProduct.createJet(),
+                            new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial(), MockPlanPhase.createUSDMonthlyFixedTerm("500.00", null, 6)},
+                            MockPlanPhase.create1USDMonthlyEvergreen(),
+                            -1);
     }
 
     public static MockPlan createHornMonthlyNoTrial1USD() {
         return new MockPlan("Horn1USD",
-                MockProduct.createHorn(),
-                new DefaultPlanPhase[]{ },
-                MockPlanPhase.create1USDMonthlyEvergreen(),
-                -1);
+                            MockProduct.createHorn(),
+                            new DefaultPlanPhase[]{},
+                            MockPlanPhase.create1USDMonthlyEvergreen(),
+                            -1);
+    }
+
+    public MockPlan() {
+        this("BicycleTrialEvergreen1USD",
+             MockProduct.createBicycle(),
+             new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial()},
+             MockPlanPhase.create1USDMonthlyEvergreen(),
+             -1);
+    }
+
+    public MockPlan(final String name, final DefaultProduct product, final DefaultPlanPhase[] planPhases, final DefaultPlanPhase finalPhase, final int plansAllowedInBundle) {
+        setName(name);
+        setProduct(product);
+        setFinalPhase(finalPhase);
+        setInitialPhases(planPhases);
+        setPlansAllowedInBundle(plansAllowedInBundle);
+
+        finalPhase.setPlan(this);
+        for (final DefaultPlanPhase pp : planPhases) {
+            pp.setPlan(this);
+        }
+    }
+
+
+    public static MockPlan createBicycleNoTrialEvergreen1USD() {
+        return new MockPlan("BicycleNoTrialEvergreen1USD",
+                            MockProduct.createBicycle(),
+                            new DefaultPlanPhase[]{},
+                            MockPlanPhase.createUSDMonthlyEvergreen("1.0", null),
+                            -1);
+    }
+
+    public MockPlan(final MockPlanPhase mockPlanPhase) {
+        setName("Test");
+        setProduct(MockProduct.createBicycle());
+        setFinalPhase(mockPlanPhase);
+
+        mockPlanPhase.setPlan(this);
+    }
+
+    public MockPlan(final String planName) {
+        setName(planName);
+        setProduct(new MockProduct());
+        setFinalPhase(new MockPlanPhase(this));
+        setInitialPhases(null);
+        setPlansAllowedInBundle(1);
+    }
+
+
+    public static DefaultPlan[] createAll() {
+        return new DefaultPlan[]{
+                createBicycleTrialEvergreen1USD(),
+                createBicycleNoTrialEvergreen1USD(),
+                createPickupTrialEvergreen10USD(),
+                createSportsCarTrialEvergreen100USD(),
+                createJetTrialEvergreen1000USD(),
+                createJetTrialFixedTermEvergreen1000USD(),
+                createHornMonthlyNoTrial1USD()
+        };
     }
 
-	public MockPlan() {
-		this("BicycleTrialEvergreen1USD",
-				MockProduct.createBicycle(),
-				new DefaultPlanPhase[]{ MockPlanPhase.create30DayTrial()},
-				MockPlanPhase.create1USDMonthlyEvergreen(),
-				-1);
-	}
-
-	public MockPlan(String name, DefaultProduct product, DefaultPlanPhase[] planPhases, DefaultPlanPhase finalPhase, int plansAllowedInBundle) {
-		setName(name);
-		setProduct(product);
-		setFinalPhase(finalPhase);
-		setInitialPhases(planPhases);
-		setPlansAllowedInBundle(plansAllowedInBundle);
-		
-		finalPhase.setPlan(this);
-		for (DefaultPlanPhase pp : planPhases) {
-			pp.setPlan(this);
-		}
-	}
-
-
-
-	public static MockPlan createBicycleNoTrialEvergreen1USD() {
-		return new MockPlan("BicycleNoTrialEvergreen1USD",
-				MockProduct.createBicycle(),
-				new DefaultPlanPhase[]{ },
-				MockPlanPhase.createUSDMonthlyEvergreen("1.0", null)	,
-				-1);
-	}
-	
-	public MockPlan(MockPlanPhase mockPlanPhase) {
-		setName("Test");
-		setProduct(MockProduct.createBicycle());
-		setFinalPhase(mockPlanPhase);
-		
-		mockPlanPhase.setPlan(this);
-	}
-
-	  public MockPlan(String planName) {
-			setName(planName);
-			setProduct(new MockProduct());
-			setFinalPhase(new MockPlanPhase(this));
-			setInitialPhases(null);
-			setPlansAllowedInBundle(1);
-	  }
-
-
-	public static DefaultPlan[] createAll() {
-		return new DefaultPlan[]{
-				createBicycleTrialEvergreen1USD(),
-				createBicycleNoTrialEvergreen1USD(),
-				createPickupTrialEvergreen10USD(),
-				createSportsCarTrialEvergreen100USD(),
-				createJetTrialEvergreen1000USD(),
-				createJetTrialFixedTermEvergreen1000USD(),
-				createHornMonthlyNoTrial1USD()
-		};
-	}
-	
-	
 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java b/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
index b995bef..ed3e103 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
@@ -24,100 +24,100 @@ import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.TimeUnit;
 
 public class MockPlanPhase extends DefaultPlanPhase {
-	
-	public static MockPlanPhase create1USDMonthlyEvergreen() {
-		return (MockPlanPhase) new MockPlanPhase(BillingPeriod.MONTHLY,
-				PhaseType.EVERGREEN,
-				new DefaultDuration().setUnit(TimeUnit.UNLIMITED),
-				MockInternationalPrice.create1USD(),
-				null).setPlan(MockPlan.createBicycleNoTrialEvergreen1USD());
-	}
-	
-	public static MockPlanPhase createUSDMonthlyEvergreen(String reccuringUSDPrice, String fixedPrice) {
-		return new MockPlanPhase(BillingPeriod.MONTHLY,
-				PhaseType.EVERGREEN,
-				new DefaultDuration().setUnit(TimeUnit.UNLIMITED),
-				(reccuringUSDPrice == null) ? null : MockInternationalPrice.createUSD(reccuringUSDPrice),
-				(fixedPrice == null) ? null :MockInternationalPrice.createUSD(fixedPrice));
-	}
-
-	public static MockPlanPhase createUSDMonthlyFixedTerm(String reccuringUSDPrice, String fixedPrice, int durationInMonths) {
-		return new MockPlanPhase(BillingPeriod.MONTHLY,
-				PhaseType.FIXEDTERM,
-				new DefaultDuration().setUnit(TimeUnit.MONTHS).setNumber(durationInMonths),
-				(reccuringUSDPrice == null) ? null : MockInternationalPrice.createUSD(reccuringUSDPrice),
-				(fixedPrice == null) ? null :MockInternationalPrice.createUSD(fixedPrice));
-	}
-
-	public static MockPlanPhase create30DayTrial() {
-		return createTrial(30);
-	}
-
-	public static MockPlanPhase createTrial(int days) {
-		return new MockPlanPhase(BillingPeriod.NO_BILLING_PERIOD,
-				PhaseType.TRIAL,
-				new DefaultDuration().setUnit(TimeUnit.DAYS).setNumber(days),
-				null,
-				MockInternationalPrice.create1USD()
-				);
-	}
+
+    public static MockPlanPhase create1USDMonthlyEvergreen() {
+        return (MockPlanPhase) new MockPlanPhase(BillingPeriod.MONTHLY,
+                                                 PhaseType.EVERGREEN,
+                                                 new DefaultDuration().setUnit(TimeUnit.UNLIMITED),
+                                                 MockInternationalPrice.create1USD(),
+                                                 null).setPlan(MockPlan.createBicycleNoTrialEvergreen1USD());
+    }
+
+    public static MockPlanPhase createUSDMonthlyEvergreen(final String reccuringUSDPrice, final String fixedPrice) {
+        return new MockPlanPhase(BillingPeriod.MONTHLY,
+                                 PhaseType.EVERGREEN,
+                                 new DefaultDuration().setUnit(TimeUnit.UNLIMITED),
+                                 (reccuringUSDPrice == null) ? null : MockInternationalPrice.createUSD(reccuringUSDPrice),
+                                 (fixedPrice == null) ? null : MockInternationalPrice.createUSD(fixedPrice));
+    }
+
+    public static MockPlanPhase createUSDMonthlyFixedTerm(final String reccuringUSDPrice, final String fixedPrice, final int durationInMonths) {
+        return new MockPlanPhase(BillingPeriod.MONTHLY,
+                                 PhaseType.FIXEDTERM,
+                                 new DefaultDuration().setUnit(TimeUnit.MONTHS).setNumber(durationInMonths),
+                                 (reccuringUSDPrice == null) ? null : MockInternationalPrice.createUSD(reccuringUSDPrice),
+                                 (fixedPrice == null) ? null : MockInternationalPrice.createUSD(fixedPrice));
+    }
+
+    public static MockPlanPhase create30DayTrial() {
+        return createTrial(30);
+    }
+
+    public static MockPlanPhase createTrial(final int days) {
+        return new MockPlanPhase(BillingPeriod.NO_BILLING_PERIOD,
+                                 PhaseType.TRIAL,
+                                 new DefaultDuration().setUnit(TimeUnit.DAYS).setNumber(days),
+                                 null,
+                                 MockInternationalPrice.create1USD()
+        );
+    }
 
     public MockPlanPhase(
-    		BillingPeriod billingPeriod, 
-    		PhaseType type, 
-    		DefaultDuration duration, 
-    		DefaultInternationalPrice recurringPrice, 
-    		DefaultInternationalPrice fixedPrice) {
-		setBillingPeriod(billingPeriod);
-		setPhaseType(type);
-		setDuration(duration);
-		setRecurringPrice(recurringPrice);
-		setFixedPrice(fixedPrice);
-	}
-    
-  
+            final BillingPeriod billingPeriod,
+            final PhaseType type,
+            final DefaultDuration duration,
+            final DefaultInternationalPrice recurringPrice,
+            final DefaultInternationalPrice fixedPrice) {
+        setBillingPeriod(billingPeriod);
+        setPhaseType(type);
+        setDuration(duration);
+        setRecurringPrice(recurringPrice);
+        setFixedPrice(fixedPrice);
+    }
+
+
     public MockPlanPhase() {
         this(new MockInternationalPrice(), null);
-	}
+    }
 
-    public MockPlanPhase(@Nullable MockInternationalPrice recurringPrice,
-                         @Nullable MockInternationalPrice fixedPrice) {
+    public MockPlanPhase(@Nullable final MockInternationalPrice recurringPrice,
+                         @Nullable final MockInternationalPrice fixedPrice) {
         this(recurringPrice, fixedPrice, BillingPeriod.MONTHLY);
-	}
-
-    public MockPlanPhase(@Nullable MockInternationalPrice recurringPrice,
-                         @Nullable MockInternationalPrice fixedPrice,
-                         BillingPeriod billingPeriod) {
-		this(recurringPrice, fixedPrice, billingPeriod, PhaseType.EVERGREEN);
-	}
-
-    public MockPlanPhase(@Nullable MockInternationalPrice recurringPrice,
-                         @Nullable MockInternationalPrice fixedPrice,
-                         BillingPeriod billingPeriod,
-                         PhaseType phaseType) {
-		setBillingPeriod(billingPeriod);
-		setPhaseType(phaseType);
-		setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
-		setRecurringPrice(recurringPrice);
-		setFixedPrice(fixedPrice);
-		setPlan(new MockPlan(this));
-	}
-
-	public MockPlanPhase(MockPlan mockPlan) {
-		setBillingPeriod(BillingPeriod.MONTHLY);
-		setPhaseType(PhaseType.EVERGREEN);
-		setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
-		setRecurringPrice(new MockInternationalPrice());
-		setFixedPrice(null);
-		setPlan(mockPlan);
-	}
-
-    public MockPlanPhase(Plan plan, PhaseType phaseType) {
-		setBillingPeriod(BillingPeriod.MONTHLY);
-		setPhaseType(phaseType);
-		setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
-		setRecurringPrice(new MockInternationalPrice());
-		setFixedPrice(null);
-		setPlan(plan);
-	}
+    }
+
+    public MockPlanPhase(@Nullable final MockInternationalPrice recurringPrice,
+                         @Nullable final MockInternationalPrice fixedPrice,
+                         final BillingPeriod billingPeriod) {
+        this(recurringPrice, fixedPrice, billingPeriod, PhaseType.EVERGREEN);
+    }
+
+    public MockPlanPhase(@Nullable final MockInternationalPrice recurringPrice,
+                         @Nullable final MockInternationalPrice fixedPrice,
+                         final BillingPeriod billingPeriod,
+                         final PhaseType phaseType) {
+        setBillingPeriod(billingPeriod);
+        setPhaseType(phaseType);
+        setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
+        setRecurringPrice(recurringPrice);
+        setFixedPrice(fixedPrice);
+        setPlan(new MockPlan(this));
+    }
+
+    public MockPlanPhase(final MockPlan mockPlan) {
+        setBillingPeriod(BillingPeriod.MONTHLY);
+        setPhaseType(PhaseType.EVERGREEN);
+        setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
+        setRecurringPrice(new MockInternationalPrice());
+        setFixedPrice(null);
+        setPlan(mockPlan);
+    }
+
+    public MockPlanPhase(final Plan plan, final PhaseType phaseType) {
+        setBillingPeriod(BillingPeriod.MONTHLY);
+        setPhaseType(phaseType);
+        setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
+        setRecurringPrice(new MockInternationalPrice());
+        setFixedPrice(null);
+        setPlan(plan);
+    }
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockPriceList.java b/catalog/src/test/java/com/ning/billing/catalog/MockPriceList.java
index 9b672ba..f482a93 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockPriceList.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockPriceList.java
@@ -20,9 +20,9 @@ import com.ning.billing.catalog.api.PriceListSet;
 
 public class MockPriceList extends DefaultPriceList {
 
-	public MockPriceList() {
-		setName(PriceListSet.DEFAULT_PRICELIST_NAME);
-		setRetired(false);
-		setPlans(MockPlan.createAll());
-	}
+    public MockPriceList() {
+        setName(PriceListSet.DEFAULT_PRICELIST_NAME);
+        setRetired(false);
+        setPlans(MockPlan.createAll());
+    }
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockProduct.java b/catalog/src/test/java/com/ning/billing/catalog/MockProduct.java
index 52ffd91..5e8f0ec 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockProduct.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockProduct.java
@@ -20,57 +20,56 @@ import com.ning.billing.catalog.api.ProductCategory;
 
 public class MockProduct extends DefaultProduct {
 
-	public MockProduct() {
-		setName("TestProduct");
-		setCatagory(ProductCategory.BASE);
-		setCatalogName("Vehcles");
-	}
-	
-	public MockProduct(String name, ProductCategory category, String catalogName) {
-		setName(name);
-		setCatagory(category);
-		setCatalogName(catalogName);
-	}
-	
-	public static MockProduct createBicycle() {
-		return new MockProduct("Bicycle", ProductCategory.BASE, "Vehcles");
-	}
-	
-	public static MockProduct createPickup() {
-		return new MockProduct("Pickup", ProductCategory.BASE, "Vehcles");
-	}
-	
-	public static MockProduct createSportsCar() {
-		return new MockProduct("SportsCar", ProductCategory.BASE, "Vehcles");
-	}
-	
-	public static MockProduct createJet() {
-		return new MockProduct("Jet", ProductCategory.BASE, "Vehcles");
-	}
-	
-	public static MockProduct createHorn() {
-		return new MockProduct("Horn", ProductCategory.ADD_ON, "Vehcles");
-	}
-	
-	public static MockProduct createSpotlight() {
-		return new MockProduct("spotlight", ProductCategory.ADD_ON, "Vehcles");
-	}
-	
-	public static MockProduct createRedPaintJob() {
-		return new MockProduct("RedPaintJob", ProductCategory.ADD_ON, "Vehcles");
-	}
+    public MockProduct() {
+        setName("TestProduct");
+        setCatagory(ProductCategory.BASE);
+        setCatalogName("Vehcles");
+    }
+
+    public MockProduct(final String name, final ProductCategory category, final String catalogName) {
+        setName(name);
+        setCatagory(category);
+        setCatalogName(catalogName);
+    }
+
+    public static MockProduct createBicycle() {
+        return new MockProduct("Bicycle", ProductCategory.BASE, "Vehcles");
+    }
+
+    public static MockProduct createPickup() {
+        return new MockProduct("Pickup", ProductCategory.BASE, "Vehcles");
+    }
+
+    public static MockProduct createSportsCar() {
+        return new MockProduct("SportsCar", ProductCategory.BASE, "Vehcles");
+    }
+
+    public static MockProduct createJet() {
+        return new MockProduct("Jet", ProductCategory.BASE, "Vehcles");
+    }
+
+    public static MockProduct createHorn() {
+        return new MockProduct("Horn", ProductCategory.ADD_ON, "Vehcles");
+    }
+
+    public static MockProduct createSpotlight() {
+        return new MockProduct("spotlight", ProductCategory.ADD_ON, "Vehcles");
+    }
+
+    public static MockProduct createRedPaintJob() {
+        return new MockProduct("RedPaintJob", ProductCategory.ADD_ON, "Vehcles");
+    }
+
+    public static DefaultProduct[] createAll() {
+        return new MockProduct[]{
+                createBicycle(),
+                createPickup(),
+                createSportsCar(),
+                createJet(),
+                createHorn(),
+                createRedPaintJob()
+        };
+    }
+
 
-	public static DefaultProduct[] createAll() {
-		return new MockProduct[]{
-				createBicycle(),
-				createPickup(),
-				createSportsCar(),
-				createJet(),
-				createHorn(),
-				createRedPaintJob()
-		};
-	}
-	
-	
-	
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/MockPlanRules.java b/catalog/src/test/java/com/ning/billing/catalog/rules/MockPlanRules.java
index 1c2eb1c..c998c9b 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/MockPlanRules.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/MockPlanRules.java
@@ -18,16 +18,16 @@ package com.ning.billing.catalog.rules;
 
 public class MockPlanRules extends PlanRules {
 
-	//For test
-	public MockPlanRules(
-			CaseChangePlanPolicy[] changeCase, CaseCancelPolicy[] cancelCase,
-			CaseChangePlanAlignment[] changeAlignmentCase,
-			CaseCreateAlignment[] createAlignmentCase) {
-		super();
-		setChangeCase(changeCase);
-		setCancelCase(cancelCase);
-		setChangeAlignmentCase(changeAlignmentCase);
-		setCreateAlignmentCase(createAlignmentCase);
-	}
+    //For test
+    public MockPlanRules(
+            final CaseChangePlanPolicy[] changeCase, final CaseCancelPolicy[] cancelCase,
+            final CaseChangePlanAlignment[] changeAlignmentCase,
+            final CaseCreateAlignment[] createAlignmentCase) {
+        super();
+        setChangeCase(changeCase);
+        setCancelCase(cancelCase);
+        setChangeAlignmentCase(changeAlignmentCase);
+        setCreateAlignmentCase(createAlignmentCase);
+    }
 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/Result.java b/catalog/src/test/java/com/ning/billing/catalog/rules/Result.java
index ff98d83..0df62d9 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/Result.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/Result.java
@@ -17,5 +17,5 @@
 package com.ning.billing.catalog.rules;
 
 enum Result {
-	FOO, BAR, TINKYWINKY,DIPSY,LALA, PO
-}
\ No newline at end of file
+    FOO, BAR, TINKYWINKY, DIPSY, LALA, PO
+}
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java
index 10229ef..5ae3793 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java
@@ -16,9 +16,6 @@
 
 package com.ning.billing.catalog.rules;
 
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNull;
-
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlIDREF;
 
@@ -36,15 +33,18 @@ import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
 
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
+
 public class TestCase {
 
-    protected class CaseResult extends Case<Result>  {
+    protected class CaseResult extends Case<Result> {
 
-        @XmlElement(required=true)
-        private Result policy;
+        @XmlElement(required = true)
+        private final Result policy;
 
-        public CaseResult(DefaultProduct product, ProductCategory productCategory, BillingPeriod billingPeriod, DefaultPriceList priceList,
-                Result policy) {
+        public CaseResult(final DefaultProduct product, final ProductCategory productCategory, final BillingPeriod billingPeriod, final DefaultPriceList priceList,
+                          final Result policy) {
             setProduct(product);
             setProductCategory(productCategory);
             setBillingPeriod(billingPeriod);
@@ -57,20 +57,20 @@ public class TestCase {
             return policy;
         }
 
-        @XmlElement(required=false, name="product")
+        @XmlElement(required = false, name = "product")
         @XmlIDREF
         protected DefaultProduct product;
-        @XmlElement(required=false, name="productCategory")
+        @XmlElement(required = false, name = "productCategory")
         protected ProductCategory productCategory;
 
-        @XmlElement(required=false, name="billingPeriod")
+        @XmlElement(required = false, name = "billingPeriod")
         protected BillingPeriod billingPeriod;
 
-        @XmlElement(required=false, name="priceList")
+        @XmlElement(required = false, name = "priceList")
         @XmlIDREF
         protected DefaultPriceList priceList;
 
-        public DefaultProduct getProduct(){
+        public DefaultProduct getProduct() {
             return product;
         }
 
@@ -86,203 +86,201 @@ public class TestCase {
             return priceList;
         }
 
-        protected CaseResult setProduct(DefaultProduct product) {
+        protected CaseResult setProduct(final DefaultProduct product) {
             this.product = product;
             return this;
         }
 
-        protected CaseResult setProductCategory(ProductCategory productCategory) {
+        protected CaseResult setProductCategory(final ProductCategory productCategory) {
             this.productCategory = productCategory;
             return this;
         }
 
-        protected CaseResult setBillingPeriod(BillingPeriod billingPeriod) {
+        protected CaseResult setBillingPeriod(final BillingPeriod billingPeriod) {
             this.billingPeriod = billingPeriod;
             return this;
         }
 
-        protected CaseResult setPriceList(DefaultPriceList priceList) {
+        protected CaseResult setPriceList(final DefaultPriceList priceList) {
             this.priceList = priceList;
             return this;
         }
     }
 
-    @Test(enabled=true)
-    public void testBasic() throws CatalogApiException{
-        MockCatalog cat = new MockCatalog();
+    @Test(enabled = true)
+    public void testBasic() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
 
-        DefaultProduct product = cat.getCurrentProducts()[0];
-        DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
-        CaseResult cr = new CaseResult(
-                product, 
+        final CaseResult cr = new CaseResult(
+                product,
                 ProductCategory.BASE,
-                BillingPeriod.MONTHLY, 
+                BillingPeriod.MONTHLY,
                 priceList,
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
         assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
-        assertionException(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
+        assertionNull(cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), cat);
+        assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", cat);
     }
 
-    @Test(enabled=true)
-    public void testWildCardProduct() throws CatalogApiException{
-        MockCatalog cat = new MockCatalog();
+    @Test(enabled = true)
+    public void testWildCardProduct() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
 
-        DefaultProduct product = cat.getCurrentProducts()[0];
-        DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
-        CaseResult cr = new CaseResult(
-                null, 
+        final CaseResult cr = new CaseResult(
+                null,
                 ProductCategory.BASE,
-                BillingPeriod.MONTHLY, 
+                BillingPeriod.MONTHLY,
                 priceList,
 
                 Result.FOO);
 
-        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertion(Result.FOO, cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
-        assertionException(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertion(Result.FOO, cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), cat);
+        assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", cat);
     }
 
-    @Test(enabled=true)
-    public void testWildCardProductCategory() throws CatalogApiException{
-        MockCatalog cat = new MockCatalog();
+    @Test(enabled = true)
+    public void testWildCardProductCategory() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
 
-        DefaultProduct product = cat.getCurrentProducts()[0];
-        DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
-        CaseResult cr = new CaseResult(
-                product, 
+        final CaseResult cr = new CaseResult(
+                product,
                 null,
-                BillingPeriod.MONTHLY, 
+                BillingPeriod.MONTHLY,
                 priceList,
 
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr,  cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertion(Result.FOO, cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
-        assertionException(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
+        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), cat);
+        assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", cat);
     }
 
-    @Test(enabled=true)
-    public void testWildCardBillingPeriod() throws CatalogApiException{
-        MockCatalog cat = new MockCatalog();
+    @Test(enabled = true)
+    public void testWildCardBillingPeriod() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
 
-        DefaultProduct product = cat.getCurrentProducts()[0];
-        DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
-        CaseResult cr = new CaseResult(
-                product, 
+        final CaseResult cr = new CaseResult(
+                product,
                 ProductCategory.BASE,
-                null, 
+                null,
                 priceList,
 
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr,  cat.getCurrentProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertion(Result.FOO,cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
-        assertionException(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
+        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), cat);
+        assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", cat);
     }
 
-    @Test(enabled=true)
-    public void testWildCardPriceList() throws CatalogApiException{
-        MockCatalog cat = new MockCatalog();
+    @Test(enabled = true)
+    public void testWildCardPriceList() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
 
-        DefaultProduct product = cat.getCurrentProducts()[0];
-        DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
-        CaseResult cr = new CaseResult(
-                product, 
+        final CaseResult cr = new CaseResult(
+                product,
                 ProductCategory.BASE,
-                BillingPeriod.MONTHLY, 
+                BillingPeriod.MONTHLY,
                 null,
 
                 Result.FOO);
 
-        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr,  cat.getCurrentProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
-        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), cat);
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", cat);
     }
 
     @Test
     public void testCaseOrder() throws CatalogApiException {
-        MockCatalog cat = new MockCatalog();
+        final MockCatalog cat = new MockCatalog();
 
-        DefaultProduct product = cat.getCurrentProducts()[0];
-        DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
-        CaseResult cr0 = new CaseResult(
-                product, 
+        final CaseResult cr0 = new CaseResult(
+                product,
                 ProductCategory.BASE,
-                BillingPeriod.MONTHLY, 
+                BillingPeriod.MONTHLY,
                 priceList,
                 Result.FOO);
 
-        CaseResult cr1 = new CaseResult(
-                product, 
+        final CaseResult cr1 = new CaseResult(
+                product,
                 ProductCategory.BASE,
-                BillingPeriod.MONTHLY, 
+                BillingPeriod.MONTHLY,
                 priceList,
                 Result.BAR);
 
-        CaseResult cr2 = new CaseResult(
-                product, 
+        final CaseResult cr2 = new CaseResult(
+                product,
                 ProductCategory.BASE,
-                BillingPeriod.ANNUAL, 
+                BillingPeriod.ANNUAL,
                 priceList,
                 Result.DIPSY);
 
-        CaseResult cr3 = new CaseResult(
-                product, 
+        final CaseResult cr3 = new CaseResult(
+                product,
                 ProductCategory.BASE,
-                BillingPeriod.ANNUAL, 
+                BillingPeriod.ANNUAL,
                 priceList,
                 Result.LALA);
 
-        Result r1 = Case.getResult(new CaseResult[]{cr0, cr1, cr2,cr3}, 
-                new PlanSpecifier(product.getName(), product.getCategory(), BillingPeriod.MONTHLY, priceList.getName()), cat);
+        final Result r1 = Case.getResult(new CaseResult[]{cr0, cr1, cr2, cr3},
+                                   new PlanSpecifier(product.getName(), product.getCategory(), BillingPeriod.MONTHLY, priceList.getName()), cat);
         assertEquals(Result.FOO, r1);
 
-        Result r2 = Case.getResult(new CaseResult[]{cr0, cr1, cr2}, 
-                new PlanSpecifier(product.getName(), product.getCategory(), BillingPeriod.ANNUAL, priceList.getName()), cat);
+        final Result r2 = Case.getResult(new CaseResult[]{cr0, cr1, cr2},
+                                   new PlanSpecifier(product.getName(), product.getCategory(), BillingPeriod.ANNUAL, priceList.getName()), cat);
         assertEquals(Result.DIPSY, r2);
     }
 
 
-
-
-    protected void assertionNull(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, StandaloneCatalog cat) throws CatalogApiException{
+    protected void assertionNull(final CaseResult cr, final String productName, final ProductCategory productCategory, final BillingPeriod bp, final String priceListName, final StandaloneCatalog cat) throws CatalogApiException {
         assertNull(cr.getResult(new PlanSpecifier(productName, productCategory, bp, priceListName), cat));
     }
 
-    protected void assertionException(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, StandaloneCatalog cat) {
-        try{
-        	cr.getResult(new PlanSpecifier(productName, productCategory, bp, priceListName), cat);  	
-        	Assert.fail("Expecting an exception");
+    protected void assertionException(final CaseResult cr, final String productName, final ProductCategory productCategory, final BillingPeriod bp, final String priceListName, final StandaloneCatalog cat) {
+        try {
+            cr.getResult(new PlanSpecifier(productName, productCategory, bp, priceListName), cat);
+            Assert.fail("Expecting an exception");
         } catch (CatalogApiException e) {
-        	Assert.assertEquals(e.getCode(), ErrorCode.CAT_PRICE_LIST_NOT_FOUND.getCode());
+            Assert.assertEquals(e.getCode(), ErrorCode.CAT_PRICE_LIST_NOT_FOUND.getCode());
         }
     }
 
-    protected void assertion(Result result, CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName,StandaloneCatalog cat) throws CatalogApiException{
+    protected void assertion(final Result result, final CaseResult cr, final String productName, final ProductCategory productCategory, final BillingPeriod bp, final String priceListName, final StandaloneCatalog cat) throws CatalogApiException {
         assertEquals(result, cr.getResult(new PlanSpecifier(productName, productCategory, bp, priceListName), cat));
     }
 
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java
index ef1eb17..a52b02c 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java
@@ -16,12 +16,16 @@
 
 package com.ning.billing.catalog.rules;
 
+import javax.xml.bind.annotation.XmlElement;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.DefaultPriceList;
 import com.ning.billing.catalog.DefaultProduct;
 import com.ning.billing.catalog.MockCatalog;
 import com.ning.billing.catalog.StandaloneCatalog;
-
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PhaseType;
@@ -29,1044 +33,1043 @@ import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import javax.xml.bind.annotation.XmlElement;
 
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 
 public class TestCaseChange {
-	protected static class CaseChangeResult extends CaseChange<Result>  {
-
-		@XmlElement(required=true)
-		private Result result;
-
-		public CaseChangeResult(DefaultProduct from, DefaultProduct to, 
-				ProductCategory fromProductCategory, ProductCategory toProductCategory,
-				BillingPeriod fromBP, BillingPeriod toBP,
-				DefaultPriceList fromPriceList, DefaultPriceList toPriceList,
-				PhaseType fromType,
-				Result result) {
-			setFromProduct(from);
-			setToProduct(to);
-			setFromProductCategory(fromProductCategory);
-			setToProductCategory(toProductCategory);
-			setFromPriceList(fromPriceList);
-			setToPriceList(toPriceList);
-			setFromBillingPeriod(fromBP);
-			setToBillingPeriod(toBP);
-			setPhaseType(fromType);
-			
-			this.result = result;
-		}
-
-		@Override
-		protected Result getResult() {
-			return result;
-		}
-	}
-	@Test(enabled=true)
-	public void testBasic() throws CatalogApiException {
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.FOO);
-
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				 cat.getCurrentProducts()[1].getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.ADD_ON, ProductCategory.BASE,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.ADD_ON,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				 cat.getCurrentProducts()[1].getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.TRIAL, cat);	
-	}
-	
-	@Test(enabled=true)
-	public void testWildcardFromProduct()throws CatalogApiException{
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr = new CaseChangeResult(
-				null, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.FOO);
-
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertion(Result.FOO,cr, 
-				 cat.getCurrentProducts()[1].getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-			
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.ADD_ON, ProductCategory.BASE,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.ADD_ON,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-
-		assertionNull(cr, 
-				product1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				 cat.getCurrentProducts()[1].getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.TRIAL, cat);	
-	}
-	
-	@Test(enabled=true)
-	public void testWildcardToProduct() throws CatalogApiException{
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr = new CaseChangeResult(
-				product1, null,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.FOO);
-
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				 cat.getCurrentProducts()[1].getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.ADD_ON, ProductCategory.BASE,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.ADD_ON,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertion(Result.FOO, cr, 
-				product1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				 cat.getCurrentProducts()[1].getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.TRIAL, cat);	
-	}
-	
-	@Test(enabled=true)
-	public void testWildcardFromProductCategory() throws CatalogApiException{
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr = new CaseChangeResult(
-				product1, product2,
-				null, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.FOO);
-
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				 cat.getCurrentProducts()[1].getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.ADD_ON, ProductCategory.BASE,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.ADD_ON,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				 cat.getCurrentProducts()[1].getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.TRIAL, cat);	
-	}
-	
-	@Test(enabled=true)
-	public void testWildcardToProductCategory() throws CatalogApiException{
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, null,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.FOO);
-
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				 cat.getCurrentProducts()[1].getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.ADD_ON, ProductCategory.BASE,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.ADD_ON,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				 cat.getCurrentProducts()[1].getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.TRIAL, cat);	
-	}
-	
-	@Test(enabled=true)
-	public void testWildcardFromBillingPeriod() throws CatalogApiException{
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				null, BillingPeriod.MONTHLY, 
-				priceList1, priceList2,
-				PhaseType.EVERGREEN,
-				Result.FOO);
-
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				 cat.getCurrentProducts()[1].getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.ADD_ON, ProductCategory.BASE,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.ADD_ON,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertion(Result.FOO,cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				 cat.getCurrentProducts()[1].getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.TRIAL, cat);	
-	}
-	
-	
-	@Test(enabled=true)
-	public void testWildCardToBillingPeriod() throws CatalogApiException{
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, null, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.FOO);
-
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				 cat.getCurrentProducts()[1].getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.ADD_ON, ProductCategory.BASE,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.ADD_ON,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertion(Result.FOO,cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				 cat.getCurrentProducts()[1].getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.TRIAL, cat);	
-	}
-	
-	@Test(enabled=true)
-	public void testWildCardFromPriceList() throws CatalogApiException{
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				null,priceList2,
-				PhaseType.EVERGREEN,
-				Result.FOO);
-
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				 cat.getCurrentProducts()[1].getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.ADD_ON, ProductCategory.BASE,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.ADD_ON,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertion(Result.FOO,cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				 cat.getCurrentProducts()[1].getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.TRIAL, cat);	
-	}
-	
-	@Test(enabled=true)
-	public void testWildcardToPriceList() throws CatalogApiException{
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1,null,
-				PhaseType.EVERGREEN,
-				Result.FOO);
-
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				 cat.getCurrentProducts()[1].getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.ADD_ON, ProductCategory.BASE,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.ADD_ON,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				 cat.getCurrentProducts()[1].getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertion(Result.FOO,cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.TRIAL, cat);	
-	}
-	
-	@Test(enabled=true)
-	public void testWildcardPlanPhase() throws CatalogApiException{
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1,priceList2,
-				null,
-				Result.FOO);
-
-		assertion(Result.FOO, cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				 cat.getCurrentProducts()[1].getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.ADD_ON, ProductCategory.BASE,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull( cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.ADD_ON,				
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionNull(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				 cat.getCurrentProducts()[1].getName(), priceList2.getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertionException(cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(),  cat.getCurrentProducts()[1].getName(), 
-				PhaseType.EVERGREEN, cat);
-		
-		assertion(Result.FOO,cr, 
-				product1.getName(), product2.getName(), 
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), priceList2.getName(), 
-				PhaseType.TRIAL, cat);	
-	}
-	
-	
-	@Test(enabled=true)
-	public void testOrder() throws CatalogApiException{
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-		DefaultProduct product2 = cat.getCurrentProducts()[2];
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
-
-
-		CaseChangeResult cr0 = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.FOO);
-
-		CaseChangeResult cr1 = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.BAR);
-
-		CaseChangeResult cr2 = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.TINKYWINKY);
-
-		CaseChangeResult cr3 = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.DIPSY);
-
-		CaseChangeResult cr4 = new CaseChangeResult(
-				product1, product2,
-				ProductCategory.BASE, ProductCategory.BASE,
-				BillingPeriod.MONTHLY, BillingPeriod.ANNUAL, 
-				priceList1,priceList2,
-				PhaseType.EVERGREEN,
-				Result.LALA);
-		
-		Result r1 = CaseChange.getResult(new CaseChangeResult[]{ cr0, cr1, cr2, cr3, cr4 }, 
-				new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN), 
-				new PlanSpecifier(product2.getName(), product2.getCategory(), BillingPeriod.MONTHLY, priceList2.getName()), cat);
-
-		assertEquals(Result.FOO,r1);
-		
-		Result r2 = CaseChange.getResult(new CaseChangeResult[]{ cr0, cr1, cr2, cr3, cr4 }, 
-				new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN), 
-				new PlanSpecifier(product2.getName(), product2.getCategory(), BillingPeriod.ANNUAL, priceList2.getName()), cat);
-
-		assertEquals(Result.DIPSY,r2);
-		
-	}
-	
-	
-	protected void assertionNull(CaseChangeResult cr, 
-			String fromProductName, String toProductName,
-			ProductCategory fromProductCategory, ProductCategory toProductCategory, 
-			BillingPeriod fromBp, BillingPeriod toBp,
-			String fromPriceListName, String toPriceListName,
-			PhaseType phaseType, StandaloneCatalog cat){
-		try {
-			assertNull(cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory, fromBp, fromPriceListName, phaseType), 
-									new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat));
-		} catch (CatalogApiException e) {
-			Assert.fail("", e);
-		}
-	}
-	   protected void assertionException(CaseChangeResult cr, 
-				String fromProductName, String toProductName,
-				ProductCategory fromProductCategory, ProductCategory toProductCategory, 
-				BillingPeriod fromBp, BillingPeriod toBp,
-				String fromPriceListName, String toPriceListName,
-				PhaseType phaseType, StandaloneCatalog cat){
-	        try{
-	        	cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory, fromBp, fromPriceListName, phaseType),
-						new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat);
-	        	Assert.fail("Expecting an exception");
-	        } catch (CatalogApiException e) {
-	        	Assert.assertEquals(e.getCode(), ErrorCode.CAT_PRICE_LIST_NOT_FOUND.getCode());
-	        }
-	    }
-	protected void assertion(Result result, CaseChangeResult cr, 
-			String fromProductName, String toProductName,
-			ProductCategory fromProductCategory, ProductCategory toProductCategory, 
-			BillingPeriod fromBp, BillingPeriod toBp,
-			String fromPriceListName, String toPriceListName,
-			PhaseType phaseType, StandaloneCatalog cat){
-		try {
-			assertEquals(result, cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory,fromBp, fromPriceListName, phaseType), 
-					new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat));
-		} catch (CatalogApiException e) {
-			Assert.fail("", e);
-		}
-	}
+    protected static class CaseChangeResult extends CaseChange<Result> {
+
+        @XmlElement(required = true)
+        private final Result result;
+
+        public CaseChangeResult(final DefaultProduct from, final DefaultProduct to,
+                                final ProductCategory fromProductCategory, final ProductCategory toProductCategory,
+                                final BillingPeriod fromBP, final BillingPeriod toBP,
+                                final DefaultPriceList fromPriceList, final DefaultPriceList toPriceList,
+                                final PhaseType fromType,
+                                final Result result) {
+            setFromProduct(from);
+            setToProduct(to);
+            setFromProductCategory(fromProductCategory);
+            setToProductCategory(toProductCategory);
+            setFromPriceList(fromPriceList);
+            setToPriceList(toPriceList);
+            setFromBillingPeriod(fromBP);
+            setToBillingPeriod(toBP);
+            setPhaseType(fromType);
+
+            this.result = result;
+        }
+
+        @Override
+        protected Result getResult() {
+            return result;
+        }
+    }
+
+    @Test(enabled = true)
+    public void testBasic() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.ADD_ON, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.ADD_ON,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildcardFromProduct() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr = new CaseChangeResult(
+                null, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertion(Result.FOO, cr,
+                  cat.getCurrentProducts()[1].getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.ADD_ON, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.ADD_ON,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildcardToProduct() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr = new CaseChangeResult(
+                product1, null,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.ADD_ON, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.ADD_ON,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), cat.getCurrentProducts()[1].getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildcardFromProductCategory() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr = new CaseChangeResult(
+                product1, product2,
+                null, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.ADD_ON, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.ADD_ON,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildcardToProductCategory() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, null,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.ADD_ON, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.ADD_ON,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildcardFromBillingPeriod() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                null, BillingPeriod.MONTHLY,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.ADD_ON, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.ADD_ON,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.TRIAL, cat);
+    }
+
+
+    @Test(enabled = true)
+    public void testWildCardToBillingPeriod() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, null,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.ADD_ON, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.ADD_ON,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildCardFromPriceList() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                null, priceList2,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.ADD_ON, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.ADD_ON,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildcardToPriceList() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                priceList1, null,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.ADD_ON, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.ADD_ON,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildcardPlanPhase() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                priceList1, priceList2,
+                null,
+                Result.FOO);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.ADD_ON, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.ADD_ON,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionNull(cr,
+                      product1.getName(), product2.getName(),
+                      ProductCategory.BASE, ProductCategory.BASE,
+                      BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                      priceList1.getName(), priceList2.getName(),
+                      PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertionException(cr,
+                           product1.getName(), product2.getName(),
+                           ProductCategory.BASE, ProductCategory.BASE,
+                           BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           PhaseType.EVERGREEN, cat);
+
+        assertion(Result.FOO, cr,
+                  product1.getName(), product2.getName(),
+                  ProductCategory.BASE, ProductCategory.BASE,
+                  BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                  priceList1.getName(), priceList2.getName(),
+                  PhaseType.TRIAL, cat);
+    }
+
+
+    @Test(enabled = true)
+    public void testOrder() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+
+
+        final CaseChangeResult cr0 = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        final CaseChangeResult cr1 = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.BAR);
+
+        final CaseChangeResult cr2 = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.TINKYWINKY);
+
+        final CaseChangeResult cr3 = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.DIPSY);
+
+        final CaseChangeResult cr4 = new CaseChangeResult(
+                product1, product2,
+                ProductCategory.BASE, ProductCategory.BASE,
+                BillingPeriod.MONTHLY, BillingPeriod.ANNUAL,
+                priceList1, priceList2,
+                PhaseType.EVERGREEN,
+                Result.LALA);
+
+        final Result r1 = CaseChange.getResult(new CaseChangeResult[]{cr0, cr1, cr2, cr3, cr4},
+                                         new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN),
+                                         new PlanSpecifier(product2.getName(), product2.getCategory(), BillingPeriod.MONTHLY, priceList2.getName()), cat);
+
+        assertEquals(Result.FOO, r1);
+
+        final Result r2 = CaseChange.getResult(new CaseChangeResult[]{cr0, cr1, cr2, cr3, cr4},
+                                         new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN),
+                                         new PlanSpecifier(product2.getName(), product2.getCategory(), BillingPeriod.ANNUAL, priceList2.getName()), cat);
+
+        assertEquals(Result.DIPSY, r2);
+
+    }
+
+
+    protected void assertionNull(final CaseChangeResult cr,
+                                 final String fromProductName, final String toProductName,
+                                 final ProductCategory fromProductCategory, final ProductCategory toProductCategory,
+                                 final BillingPeriod fromBp, final BillingPeriod toBp,
+                                 final String fromPriceListName, final String toPriceListName,
+                                 final PhaseType phaseType, final StandaloneCatalog cat) {
+        try {
+            assertNull(cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory, fromBp, fromPriceListName, phaseType),
+                                    new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName), cat));
+        } catch (CatalogApiException e) {
+            Assert.fail("", e);
+        }
+    }
+
+    protected void assertionException(final CaseChangeResult cr,
+                                      final String fromProductName, final String toProductName,
+                                      final ProductCategory fromProductCategory, final ProductCategory toProductCategory,
+                                      final BillingPeriod fromBp, final BillingPeriod toBp,
+                                      final String fromPriceListName, final String toPriceListName,
+                                      final PhaseType phaseType, final StandaloneCatalog cat) {
+        try {
+            cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory, fromBp, fromPriceListName, phaseType),
+                         new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName), cat);
+            Assert.fail("Expecting an exception");
+        } catch (CatalogApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.CAT_PRICE_LIST_NOT_FOUND.getCode());
+        }
+    }
+
+    protected void assertion(final Result result, final CaseChangeResult cr,
+                             final String fromProductName, final String toProductName,
+                             final ProductCategory fromProductCategory, final ProductCategory toProductCategory,
+                             final BillingPeriod fromBp, final BillingPeriod toBp,
+                             final String fromPriceListName, final String toPriceListName,
+                             final PhaseType phaseType, final StandaloneCatalog cat) {
+        try {
+            assertEquals(result, cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory, fromBp, fromPriceListName, phaseType),
+                                              new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName), cat));
+        } catch (CatalogApiException e) {
+            Assert.fail("", e);
+        }
+    }
 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java
index 1b28da7..26dfc5c 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java
@@ -16,6 +16,11 @@
 
 package com.ning.billing.catalog.rules;
 
+import javax.xml.bind.annotation.XmlElement;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.DefaultPriceList;
 import com.ning.billing.catalog.DefaultProduct;
@@ -26,264 +31,260 @@ import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import javax.xml.bind.annotation.XmlElement;
 
 public class TestCasePhase {
-	protected class CaseResult extends CasePhase<Result>  {
-
-		@XmlElement(required=true)
-		private Result policy;
-
-		public CaseResult(DefaultProduct product, ProductCategory productCategory, BillingPeriod billingPeriod, DefaultPriceList priceList,
-				PhaseType phaseType, Result policy) {
-			setProduct(product);
-			setProductCategory(productCategory);
-			setBillingPeriod(billingPeriod);
-			setPriceList(priceList);
-			setPhaseType(phaseType);
-			
-			this.policy = policy;
-		}
-
-		@Override
-		protected Result getResult() {
-			return policy;
-		}
-	}
-
-	@Test(enabled=true)
-	public void testBasic(){
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
-
-
-		CaseResult cr = new CaseResult(
-				product, 
-				ProductCategory.BASE,
-				BillingPeriod.MONTHLY, 
-				priceList,
-				PhaseType.EVERGREEN, 
-				Result.FOO);
-
-		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr,  cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionException(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
-	}
-
-	@Test(enabled=true)
-	public void testWildCardProduct(){
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
-
-
-		CaseResult cr = new CaseResult(
-				null, 
-				ProductCategory.BASE,
-				BillingPeriod.MONTHLY, 
-				priceList,
-				PhaseType.EVERGREEN, 
-				Result.FOO);
-
-		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertion(Result.FOO, cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionException(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
-	}
-	
-	@Test(enabled=true)
-	public void testWildCardProductCategory(){
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
-
-
-		CaseResult cr = new CaseResult(
-				product, 
-				null,
-				BillingPeriod.MONTHLY, 
-				priceList,
-				PhaseType.EVERGREEN, 
-				Result.FOO);
-
-		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr,  cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertion(Result.FOO, cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionException(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
-	}
-	
-	@Test(enabled=true)
-	public void testWildCardBillingPeriod(){
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
-
-
-		CaseResult cr = new CaseResult(
-				product, 
-				ProductCategory.BASE,
-				null, 
-				priceList,
-				PhaseType.EVERGREEN, 
-				Result.FOO);
-
-		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr,  cat.getCurrentProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertion(Result.FOO,cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionException(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
-	}
-
-	@Test(enabled=true)
-	public void testWildCardPriceList(){
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
-
-
-		CaseResult cr = new CaseResult(
-				product, 
-				ProductCategory.BASE,
-				BillingPeriod.MONTHLY, 
-				null,
-				PhaseType.EVERGREEN, 
-				Result.FOO);
-
-		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr,  cat.getCurrentProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
-	}
-
-	@Test(enabled=true)
-	public void testWildCardPhaseType(){
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
-
-
-		CaseResult cr = new CaseResult(
-				product, 
-				ProductCategory.BASE,
-				BillingPeriod.MONTHLY, 
-				priceList,
-				null, 
-				Result.FOO);
-
-		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr,  cat.getCurrentProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
-		assertion(Result.FOO,cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
-	}
-	
-	@Test(enabled=true)
-	public void testOrder() throws CatalogApiException {
-		MockCatalog cat = new MockCatalog();
-
-		DefaultProduct product = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
-
-
-		CaseResult cr0 = new CaseResult(
-				product, 
-				ProductCategory.BASE,
-				BillingPeriod.MONTHLY, 
-				priceList,
-				PhaseType.EVERGREEN, 
-				Result.FOO);
-
-		CaseResult cr1 = new CaseResult(
-				product, 
-				ProductCategory.BASE,
-				BillingPeriod.MONTHLY, 
-				priceList,
-				PhaseType.EVERGREEN, 
-				Result.BAR);
-
-		CaseResult cr2 = new CaseResult(
-				product, 
-				ProductCategory.BASE,
-				BillingPeriod.MONTHLY, 
-				priceList,
-				PhaseType.EVERGREEN, 
-				Result.TINKYWINKY);
-
-		CaseResult cr3 = new CaseResult(
-				product, 
-				ProductCategory.BASE,
-				BillingPeriod.ANNUAL, 
-				priceList,
-				PhaseType.EVERGREEN, 
-				Result.DIPSY);
-
-		CaseResult cr4 = new CaseResult(
-				product, 
-				ProductCategory.BASE,
-				BillingPeriod.ANNUAL, 
-				priceList,
-				PhaseType.EVERGREEN, 
-				Result.LALA);
-		
-		Result r1 = CasePhase.getResult(new CaseResult[]{cr0, cr1, cr2,cr3,cr4}, 
-				new PlanPhaseSpecifier(product.getName(), product.getCategory(), BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN), cat);
-		
-		Assert.assertEquals(Result.FOO, r1);
-
-		Result r2 = CasePhase.getResult(new CaseResult[]{cr0, cr1, cr2,cr3,cr4}, 
-				new PlanPhaseSpecifier(product.getName(), product.getCategory(), BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN), cat);
-		
-		Assert.assertEquals(Result.DIPSY, r2);
-
-	}
-
-
-	protected void assertionNull(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, PhaseType phaseType, StandaloneCatalog cat){
-		try {
-			Assert.assertNull(cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
-		} catch (CatalogApiException e) {
-			Assert.fail("", e);
-		}
-	}
-
-
-	protected void assertionException(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, PhaseType phaseType, StandaloneCatalog cat){
-		try {
-			Assert.assertNull(cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
-			Assert.fail("Exception expected");
-		} catch (CatalogApiException e) {
-			Assert.assertEquals(e.getCode(), ErrorCode.CAT_PRICE_LIST_NOT_FOUND.getCode());
-		}
-	}
-
-	protected void assertion(Result result, CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, PhaseType phaseType, StandaloneCatalog cat){
-		try {
-			Assert.assertEquals(result, cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
-		} catch (CatalogApiException e) {
-			Assert.fail("", e);
-		}
-	}
+    protected class CaseResult extends CasePhase<Result> {
+
+        @XmlElement(required = true)
+        private final Result policy;
+
+        public CaseResult(final DefaultProduct product, final ProductCategory productCategory, final BillingPeriod billingPeriod, final DefaultPriceList priceList,
+                          final PhaseType phaseType, final Result policy) {
+            setProduct(product);
+            setProductCategory(productCategory);
+            setBillingPeriod(billingPeriod);
+            setPriceList(priceList);
+            setPhaseType(phaseType);
+
+            this.policy = policy;
+        }
+
+        @Override
+        protected Result getResult() {
+            return policy;
+        }
+    }
+
+    @Test(enabled = true)
+    public void testBasic() {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
+
+
+        final CaseResult cr = new CaseResult(
+                product,
+                ProductCategory.BASE,
+                BillingPeriod.MONTHLY,
+                priceList,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildCardProduct() {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
+
+
+        final CaseResult cr = new CaseResult(
+                null,
+                ProductCategory.BASE,
+                BillingPeriod.MONTHLY,
+                priceList,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertion(Result.FOO, cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildCardProductCategory() {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
+
+
+        final CaseResult cr = new CaseResult(
+                product,
+                null,
+                BillingPeriod.MONTHLY,
+                priceList,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildCardBillingPeriod() {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
+
+
+        final CaseResult cr = new CaseResult(
+                product,
+                ProductCategory.BASE,
+                null,
+                priceList,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildCardPriceList() {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
+
+
+        final CaseResult cr = new CaseResult(
+                product,
+                ProductCategory.BASE,
+                BillingPeriod.MONTHLY,
+                null,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testWildCardPhaseType() {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
+
+
+        final CaseResult cr = new CaseResult(
+                product,
+                ProductCategory.BASE,
+                BillingPeriod.MONTHLY,
+                priceList,
+                null,
+                Result.FOO);
+
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.ADD_ON, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
+        assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
+    }
+
+    @Test(enabled = true)
+    public void testOrder() throws CatalogApiException {
+        final MockCatalog cat = new MockCatalog();
+
+        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
+
+
+        final CaseResult cr0 = new CaseResult(
+                product,
+                ProductCategory.BASE,
+                BillingPeriod.MONTHLY,
+                priceList,
+                PhaseType.EVERGREEN,
+                Result.FOO);
+
+        final CaseResult cr1 = new CaseResult(
+                product,
+                ProductCategory.BASE,
+                BillingPeriod.MONTHLY,
+                priceList,
+                PhaseType.EVERGREEN,
+                Result.BAR);
+
+        final CaseResult cr2 = new CaseResult(
+                product,
+                ProductCategory.BASE,
+                BillingPeriod.MONTHLY,
+                priceList,
+                PhaseType.EVERGREEN,
+                Result.TINKYWINKY);
+
+        final CaseResult cr3 = new CaseResult(
+                product,
+                ProductCategory.BASE,
+                BillingPeriod.ANNUAL,
+                priceList,
+                PhaseType.EVERGREEN,
+                Result.DIPSY);
+
+        final CaseResult cr4 = new CaseResult(
+                product,
+                ProductCategory.BASE,
+                BillingPeriod.ANNUAL,
+                priceList,
+                PhaseType.EVERGREEN,
+                Result.LALA);
+
+        final Result r1 = CasePhase.getResult(new CaseResult[]{cr0, cr1, cr2, cr3, cr4},
+                                        new PlanPhaseSpecifier(product.getName(), product.getCategory(), BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN), cat);
+
+        Assert.assertEquals(Result.FOO, r1);
+
+        final Result r2 = CasePhase.getResult(new CaseResult[]{cr0, cr1, cr2, cr3, cr4},
+                                        new PlanPhaseSpecifier(product.getName(), product.getCategory(), BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN), cat);
+
+        Assert.assertEquals(Result.DIPSY, r2);
+
+    }
+
+
+    protected void assertionNull(final CaseResult cr, final String productName, final ProductCategory productCategory, final BillingPeriod bp, final String priceListName, final PhaseType phaseType, final StandaloneCatalog cat) {
+        try {
+            Assert.assertNull(cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+        } catch (CatalogApiException e) {
+            Assert.fail("", e);
+        }
+    }
+
+
+    protected void assertionException(final CaseResult cr, final String productName, final ProductCategory productCategory, final BillingPeriod bp, final String priceListName, final PhaseType phaseType, final StandaloneCatalog cat) {
+        try {
+            Assert.assertNull(cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+            Assert.fail("Exception expected");
+        } catch (CatalogApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.CAT_PRICE_LIST_NOT_FOUND.getCode());
+        }
+    }
+
+    protected void assertion(final Result result, final CaseResult cr, final String productName, final ProductCategory productCategory, final BillingPeriod bp, final String priceListName, final PhaseType phaseType, final StandaloneCatalog cat) {
+        try {
+            Assert.assertEquals(result, cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+        } catch (CatalogApiException e) {
+            Assert.fail("", e);
+        }
+    }
 
 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestLoadRules.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestLoadRules.java
index 6f1d9e2..0e8b04e 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestLoadRules.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestLoadRules.java
@@ -23,7 +23,6 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.StandaloneCatalog;
 import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanAlignmentCreate;
 import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
@@ -33,20 +32,20 @@ public class TestLoadRules {
 
     @Test
     public void test() throws Exception {
-        StandaloneCatalog catalog = XMLLoader.getObjectFromUri(new File("src/test/resources/WeaponsHireSmall.xml").toURI(), StandaloneCatalog.class);
+        final StandaloneCatalog catalog = XMLLoader.getObjectFromUri(new File("src/test/resources/WeaponsHireSmall.xml").toURI(), StandaloneCatalog.class);
         Assert.assertNotNull(catalog);
-        PlanRules rules = catalog.getPlanRules();
-        
-        PlanSpecifier specifier = new PlanSpecifier("Laser-Scope", ProductCategory.ADD_ON , BillingPeriod.MONTHLY,
-                "DEFAULT");
-        
-        PlanAlignmentCreate alignment=  rules.getPlanCreateAlignment(specifier, catalog);
+        final PlanRules rules = catalog.getPlanRules();
+
+        final PlanSpecifier specifier = new PlanSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY,
+                                                    "DEFAULT");
+
+        final PlanAlignmentCreate alignment = rules.getPlanCreateAlignment(specifier, catalog);
         Assert.assertEquals(alignment, PlanAlignmentCreate.START_OF_SUBSCRIPTION);
-        
-        PlanSpecifier specifier2 = new PlanSpecifier("Extra-Ammo", ProductCategory.ADD_ON , BillingPeriod.MONTHLY,
-                "DEFAULT");
-        
-        PlanAlignmentCreate alignment2 = rules.getPlanCreateAlignment(specifier2, catalog);
+
+        final PlanSpecifier specifier2 = new PlanSpecifier("Extra-Ammo", ProductCategory.ADD_ON, BillingPeriod.MONTHLY,
+                                                     "DEFAULT");
+
+        final PlanAlignmentCreate alignment2 = rules.getPlanCreateAlignment(specifier2, catalog);
         Assert.assertEquals(alignment2, PlanAlignmentCreate.START_OF_BUNDLE);
     }
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java
index e9617ea..bc876d3 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java
@@ -16,10 +16,15 @@
 
 package com.ning.billing.catalog.rules;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
 import com.ning.billing.catalog.DefaultPriceList;
 import com.ning.billing.catalog.DefaultProduct;
 import com.ning.billing.catalog.MockCatalog;
-
 import com.ning.billing.catalog.api.ActionPolicy;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -30,103 +35,97 @@ import com.ning.billing.catalog.api.PlanChangeResult;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.api.PriceListSet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.BeforeTest;
-import org.testng.annotations.Test;
 
 public class TestPlanRules {
-	Logger log = LoggerFactory.getLogger(TestPlanRules.class);
-
-	private MockCatalog cat = null;
-
-	@BeforeTest
-	public void setup() {
-		cat = new MockCatalog();
-
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[0];
-
-		CaseChangePlanPolicy casePolicy = new CaseChangePlanPolicy().setPolicy(ActionPolicy.END_OF_TERM);
-		CaseChangePlanAlignment caseAlignment = new CaseChangePlanAlignment().setAlignment(PlanAlignmentChange.START_OF_SUBSCRIPTION);
-		CasePriceList casePriceList = new CasePriceList().setToPriceList(priceList2);
-
-		cat.getPlanRules().
-		setChangeCase(new CaseChangePlanPolicy[]{casePolicy}).
-		setChangeAlignmentCase(new CaseChangePlanAlignment[]{caseAlignment}).
-		setPriceListCase(new CasePriceList[]{casePriceList});
-	}
-
-	@Test
-	public void testCannotChangeToSamePlan() throws CatalogApiException {
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-		
-		PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
-		PlanSpecifier to = new PlanSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName());
-
-		try {
-			cat.getPlanRules().planChange(from, to, cat);
-			Assert.fail("We did not see an exception when  trying to change plan to the same plan");
-		} catch (IllegalPlanChange e) {
-			log.info("Correct - cannot change to the same plan:", e);
-		} catch (CatalogApiException e) {
-			Assert.fail("", e);
-		}
-
-	}
-	
-	@Test
-	public void testExistingPriceListIsKept() throws CatalogApiException {
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-		
-		PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
-		PlanSpecifier to = new PlanSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.ANNUAL, priceList1.getName());
-
-		PlanChangeResult result = null;
-		try {
-			result = cat.getPlanRules().planChange(from, to, cat);		
-		} catch (IllegalPlanChange e) {
-			log.info("Correct - cannot change to the same plan:", e);
-			Assert.fail("We should not have triggered this error");
-		} catch (CatalogApiException e) {
-			Assert.fail("", e);
-		}
-		
-		Assert.assertEquals(result.getPolicy(), ActionPolicy.END_OF_TERM);
-		Assert.assertEquals(result.getAlignment(), PlanAlignmentChange.START_OF_SUBSCRIPTION);
-		Assert.assertEquals(result.getNewPriceList(), priceList1);
-
-	}
-	
-	
-	@Test
-	public void testBaseCase() throws CatalogApiException {
-		DefaultProduct product1 = cat.getCurrentProducts()[0];
-		DefaultProduct product2 = cat.getCurrentProducts()[1];
-		DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[0];
-		
-		PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
-		PlanSpecifier to = new PlanSpecifier(product2.getName(), product2.getCategory(), BillingPeriod.MONTHLY, null);
-
-		PlanChangeResult result = null;
-		try {
-			result = cat.getPlanRules().planChange(from, to, cat);	
-		} catch (IllegalPlanChange e) {
-			log.info("Correct - cannot change to the same plan:", e);
-			Assert.fail("We should not have triggered this error");
-		} catch (CatalogApiException e) {
-			Assert.fail("", e);
-		}
-		
-		Assert.assertEquals(result.getPolicy(), ActionPolicy.END_OF_TERM);
-		Assert.assertEquals(result.getAlignment(), PlanAlignmentChange.START_OF_SUBSCRIPTION);
-		Assert.assertEquals(result.getNewPriceList(), priceList2);
-
-	}
-	
-	
-	
+    Logger log = LoggerFactory.getLogger(TestPlanRules.class);
+
+    private MockCatalog cat = null;
+
+    @BeforeTest
+    public void setup() {
+        cat = new MockCatalog();
+
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[0];
+
+        final CaseChangePlanPolicy casePolicy = new CaseChangePlanPolicy().setPolicy(ActionPolicy.END_OF_TERM);
+        final CaseChangePlanAlignment caseAlignment = new CaseChangePlanAlignment().setAlignment(PlanAlignmentChange.START_OF_SUBSCRIPTION);
+        final CasePriceList casePriceList = new CasePriceList().setToPriceList(priceList2);
+
+        cat.getPlanRules().
+                setChangeCase(new CaseChangePlanPolicy[]{casePolicy}).
+                setChangeAlignmentCase(new CaseChangePlanAlignment[]{caseAlignment}).
+                setPriceListCase(new CasePriceList[]{casePriceList});
+    }
+
+    @Test
+    public void testCannotChangeToSamePlan() throws CatalogApiException {
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
+        final PlanSpecifier to = new PlanSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName());
+
+        try {
+            cat.getPlanRules().planChange(from, to, cat);
+            Assert.fail("We did not see an exception when  trying to change plan to the same plan");
+        } catch (IllegalPlanChange e) {
+            log.info("Correct - cannot change to the same plan:", e);
+        } catch (CatalogApiException e) {
+            Assert.fail("", e);
+        }
+
+    }
+
+    @Test
+    public void testExistingPriceListIsKept() throws CatalogApiException {
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
+        final PlanSpecifier to = new PlanSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.ANNUAL, priceList1.getName());
+
+        PlanChangeResult result = null;
+        try {
+            result = cat.getPlanRules().planChange(from, to, cat);
+        } catch (IllegalPlanChange e) {
+            log.info("Correct - cannot change to the same plan:", e);
+            Assert.fail("We should not have triggered this error");
+        } catch (CatalogApiException e) {
+            Assert.fail("", e);
+        }
+
+        Assert.assertEquals(result.getPolicy(), ActionPolicy.END_OF_TERM);
+        Assert.assertEquals(result.getAlignment(), PlanAlignmentChange.START_OF_SUBSCRIPTION);
+        Assert.assertEquals(result.getNewPriceList(), priceList1);
+
+    }
+
+
+    @Test
+    public void testBaseCase() throws CatalogApiException {
+        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product2 = cat.getCurrentProducts()[1];
+        final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
+        final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[0];
+
+        final PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
+        final PlanSpecifier to = new PlanSpecifier(product2.getName(), product2.getCategory(), BillingPeriod.MONTHLY, null);
+
+        PlanChangeResult result = null;
+        try {
+            result = cat.getPlanRules().planChange(from, to, cat);
+        } catch (IllegalPlanChange e) {
+            log.info("Correct - cannot change to the same plan:", e);
+            Assert.fail("We should not have triggered this error");
+        } catch (CatalogApiException e) {
+            Assert.fail("", e);
+        }
+
+        Assert.assertEquals(result.getPolicy(), ActionPolicy.END_OF_TERM);
+        Assert.assertEquals(result.getAlignment(), PlanAlignmentChange.START_OF_SUBSCRIPTION);
+        Assert.assertEquals(result.getNewPriceList(), priceList2);
+
+    }
+
+
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestCatalogService.java b/catalog/src/test/java/com/ning/billing/catalog/TestCatalogService.java
index 7bb45a6..38c21e2 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestCatalogService.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestCatalogService.java
@@ -16,40 +16,41 @@
 
 package com.ning.billing.catalog;
 
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
 import com.ning.billing.catalog.io.VersionedCatalogLoader;
 import com.ning.billing.config.CatalogConfig;
 import com.ning.billing.lifecycle.KillbillService.ServiceException;
 import com.ning.billing.util.clock.DefaultClock;
-import org.testng.Assert;
-import org.testng.annotations.Test;
 
 public class TestCatalogService {
 
-	@Test
-	public void testCatalogServiceDirectory() throws ServiceException {
-		DefaultCatalogService service = new DefaultCatalogService(new CatalogConfig() {
-			@Override
-			public String getCatalogURI() {
-				return "file:src/test/resources/versionedCatalog";
-			}
-			
-		}, new VersionedCatalogLoader(new DefaultClock()));
-		service.loadCatalog();
-		Assert.assertNotNull(service.getFullCatalog());
-		Assert.assertEquals(service.getFullCatalog().getCatalogName(), "WeaponsHireSmall");
-	}
-	
-	@Test
-	public void testCatalogServiceFile() throws ServiceException {
-		DefaultCatalogService service = new DefaultCatalogService(new CatalogConfig() {
-			@Override
-			public String getCatalogURI() {
-				return "file:src/test/resources/WeaponsHire.xml";
-			}
-			
-		}, new VersionedCatalogLoader(new DefaultClock()));
-		service.loadCatalog();
-		Assert.assertNotNull(service.getFullCatalog());
-		Assert.assertEquals(service.getFullCatalog().getCatalogName(), "Firearms");
-	}
+    @Test
+    public void testCatalogServiceDirectory() throws ServiceException {
+        final DefaultCatalogService service = new DefaultCatalogService(new CatalogConfig() {
+            @Override
+            public String getCatalogURI() {
+                return "file:src/test/resources/versionedCatalog";
+            }
+
+        }, new VersionedCatalogLoader(new DefaultClock()));
+        service.loadCatalog();
+        Assert.assertNotNull(service.getFullCatalog());
+        Assert.assertEquals(service.getFullCatalog().getCatalogName(), "WeaponsHireSmall");
+    }
+
+    @Test
+    public void testCatalogServiceFile() throws ServiceException {
+        final DefaultCatalogService service = new DefaultCatalogService(new CatalogConfig() {
+            @Override
+            public String getCatalogURI() {
+                return "file:src/test/resources/WeaponsHire.xml";
+            }
+
+        }, new VersionedCatalogLoader(new DefaultClock()));
+        service.loadCatalog();
+        Assert.assertNotNull(service.getFullCatalog());
+        Assert.assertEquals(service.getFullCatalog().getCatalogName(), "Firearms");
+    }
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java b/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
index 2772fc4..62fbe6c 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
@@ -15,82 +15,80 @@
  */
 package com.ning.billing.catalog;
 
-import com.ning.billing.catalog.api.CatalogApiException;
-import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.config.ValidationErrors;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.net.URISyntaxException;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import java.math.BigDecimal;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Date;
+import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.config.ValidationErrors;
 
 public class TestInternationalPrice {
-	private static final Logger log = LoggerFactory.getLogger(TestInternationalPrice.class);
-	
-  @Test
-  public void testZeroValue() throws URISyntaxException, CatalogApiException {
-	  StandaloneCatalog c = new MockCatalog();
-	  c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
-	  DefaultInternationalPrice p0 =  new MockInternationalPrice();
-	  p0.setPrices(null);
-	  p0.initialize(c, new URI("foo:bar"));
-	  DefaultInternationalPrice p1 =  new MockInternationalPrice();
-	  p1.setPrices(new DefaultPrice[] {
-			  new DefaultPrice().setCurrency(Currency.GBP).setValue(new BigDecimal(1)),
-			  new DefaultPrice().setCurrency(Currency.EUR).setValue(new BigDecimal(1)),
-			  new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(1)),
-			  new DefaultPrice().setCurrency(Currency.BRL).setValue(new BigDecimal(1)),
-			  new DefaultPrice().setCurrency(Currency.MXN).setValue(new BigDecimal(1)),		  
-	  });
-	  p1.initialize(c, new URI("foo:bar"));
+    private static final Logger log = LoggerFactory.getLogger(TestInternationalPrice.class);
+
+    @Test
+    public void testZeroValue() throws URISyntaxException, CatalogApiException {
+        final StandaloneCatalog c = new MockCatalog();
+        c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+        final DefaultInternationalPrice p0 = new MockInternationalPrice();
+        p0.setPrices(null);
+        p0.initialize(c, new URI("foo:bar"));
+        final DefaultInternationalPrice p1 = new MockInternationalPrice();
+        p1.setPrices(new DefaultPrice[]{
+                new DefaultPrice().setCurrency(Currency.GBP).setValue(new BigDecimal(1)),
+                new DefaultPrice().setCurrency(Currency.EUR).setValue(new BigDecimal(1)),
+                new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(1)),
+                new DefaultPrice().setCurrency(Currency.BRL).setValue(new BigDecimal(1)),
+                new DefaultPrice().setCurrency(Currency.MXN).setValue(new BigDecimal(1)),
+        });
+        p1.initialize(c, new URI("foo:bar"));
+
+        Assert.assertEquals(p0.getPrice(Currency.GBP), new BigDecimal(0));
+        Assert.assertEquals(p0.getPrice(Currency.EUR), new BigDecimal(0));
+        Assert.assertEquals(p0.getPrice(Currency.USD), new BigDecimal(0));
+        Assert.assertEquals(p0.getPrice(Currency.BRL), new BigDecimal(0));
+        Assert.assertEquals(p0.getPrice(Currency.MXN), new BigDecimal(0));
+
+        Assert.assertEquals(p1.getPrice(Currency.GBP), new BigDecimal(1));
+        Assert.assertEquals(p1.getPrice(Currency.EUR), new BigDecimal(1));
+        Assert.assertEquals(p1.getPrice(Currency.USD), new BigDecimal(1));
+        Assert.assertEquals(p1.getPrice(Currency.BRL), new BigDecimal(1));
+        Assert.assertEquals(p1.getPrice(Currency.MXN), new BigDecimal(1));
+
+    }
+
+    @Test
+    public void testPriceInitialization() throws URISyntaxException, CatalogApiException {
+        final StandaloneCatalog c = new MockCatalog();
+        c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+        c.getCurrentPlans()[0].getFinalPhase().getRecurringPrice().setPrices(null);
+        c.initialize(c, new URI("foo://bar"));
+        Assert.assertEquals(c.getCurrentPlans()[0].getFinalPhase().getRecurringPrice().getPrice(Currency.GBP), new BigDecimal(0));
+    }
+
+    @Test
+    public void testNegativeValuePrices() {
+        final StandaloneCatalog c = new MockCatalog();
+        c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+
+        final DefaultInternationalPrice p1 = new MockInternationalPrice();
+        p1.setPrices(new DefaultPrice[]{
+                new DefaultPrice().setCurrency(Currency.GBP).setValue(new BigDecimal(-1)),
+                new DefaultPrice().setCurrency(Currency.EUR).setValue(new BigDecimal(-1)),
+                new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(-1)),
+                new DefaultPrice().setCurrency(Currency.BRL).setValue(new BigDecimal(1)),
+                new DefaultPrice().setCurrency(Currency.MXN).setValue(new BigDecimal(1)),
+        });
+
+        final ValidationErrors errors = p1.validate(c, new ValidationErrors());
+        errors.log(log);
+        Assert.assertEquals(errors.size(), 3);
+    }
 
-	  Assert.assertEquals(p0.getPrice(Currency.GBP), new BigDecimal(0));
-	  Assert.assertEquals(p0.getPrice(Currency.EUR), new BigDecimal(0));
-	  Assert.assertEquals(p0.getPrice(Currency.USD), new BigDecimal(0));
-	  Assert.assertEquals(p0.getPrice(Currency.BRL), new BigDecimal(0));
-	  Assert.assertEquals(p0.getPrice(Currency.MXN), new BigDecimal(0));
-	  
-	  Assert.assertEquals(p1.getPrice(Currency.GBP), new BigDecimal(1));
-	  Assert.assertEquals(p1.getPrice(Currency.EUR), new BigDecimal(1));
-	  Assert.assertEquals(p1.getPrice(Currency.USD), new BigDecimal(1));
-	  Assert.assertEquals(p1.getPrice(Currency.BRL), new BigDecimal(1));
-	  Assert.assertEquals(p1.getPrice(Currency.MXN), new BigDecimal(1));
-	  
-  }
-  
-  @Test
-  public void testPriceInitialization() throws URISyntaxException, CatalogApiException  {
-	  StandaloneCatalog c = new MockCatalog();
-	  c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
-	  c.getCurrentPlans()[0].getFinalPhase().getRecurringPrice().setPrices(null);
-	  c.initialize(c, new URI("foo://bar"));
-	  Assert.assertEquals(c.getCurrentPlans()[0].getFinalPhase().getRecurringPrice().getPrice(Currency.GBP), new BigDecimal(0));
-  }
-  
-   @Test
-  public void testNegativeValuePrices(){
-	  StandaloneCatalog c = new MockCatalog();
-	  c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
-	
-	  DefaultInternationalPrice p1 =  new MockInternationalPrice();
-	  p1.setPrices(new DefaultPrice[] {
-			  new DefaultPrice().setCurrency(Currency.GBP).setValue(new BigDecimal(-1)),
-			  new DefaultPrice().setCurrency(Currency.EUR).setValue(new BigDecimal(-1)),
-			  new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(-1)),
-			  new DefaultPrice().setCurrency(Currency.BRL).setValue(new BigDecimal(1)),
-			  new DefaultPrice().setCurrency(Currency.MXN).setValue(new BigDecimal(1)),		  
-	  });
-	  
-	 ValidationErrors errors = p1.validate(c, new ValidationErrors());
-	 errors.log(log);
-	 Assert.assertEquals(errors.size(), 3);
-  }
 
-  
-  
-  
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestPlan.java b/catalog/src/test/java/com/ning/billing/catalog/TestPlan.java
index a8714c1..2aad0a6 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestPlan.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestPlan.java
@@ -25,38 +25,36 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.catalog.api.Duration;
-import com.ning.billing.catalog.api.InternationalPrice;
-import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.util.config.ValidationErrors;
 
 public class TestPlan {
-	private static final Logger log = LoggerFactory.getLogger(TestPlan.class);
-	@Test(groups={"fast"}, enabled = true)
-	public void testDateValidation() {
-
-		StandaloneCatalog c = new MockCatalog();
-		c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
-		DefaultPlan p1 =  MockPlan.createBicycleTrialEvergreen1USD();
-		p1.setEffectiveDateForExistingSubscriptons(new Date((new Date().getTime()) - (1000 * 60 * 60 * 24)));
-		ValidationErrors errors = p1.validate(c, new ValidationErrors());
-		Assert.assertEquals(errors.size(), 1);
-		errors.log(log);
-
-	}
-	
-	@Test(groups={"fast"}, enabled = true)
-	public void testDataCalc() {
-		DefaultPlan p0 = MockPlan.createBicycleTrialEvergreen1USD();  
-					
-		DefaultPlan p1 =  MockPlan.createBicycleTrialEvergreen1USD(100);
-		
-		DefaultPlan p2 =  MockPlan.createBicycleNoTrialEvergreen1USD(); 
-		
-		DateTime requestedDate = new DateTime();
-		Assert.assertEquals(p0.dateOfFirstRecurringNonZeroCharge(requestedDate).compareTo(requestedDate.plusDays(30)), 0);
-		Assert.assertEquals(p1.dateOfFirstRecurringNonZeroCharge(requestedDate).compareTo(requestedDate.plusDays(100)), 0);
-		Assert.assertEquals(p2.dateOfFirstRecurringNonZeroCharge(requestedDate).compareTo(requestedDate.plusDays(0)), 0);
-
-	}
+    private static final Logger log = LoggerFactory.getLogger(TestPlan.class);
+
+    @Test(groups = {"fast"}, enabled = true)
+    public void testDateValidation() {
+
+        final StandaloneCatalog c = new MockCatalog();
+        c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+        final DefaultPlan p1 = MockPlan.createBicycleTrialEvergreen1USD();
+        p1.setEffectiveDateForExistingSubscriptons(new Date((new Date().getTime()) - (1000 * 60 * 60 * 24)));
+        final ValidationErrors errors = p1.validate(c, new ValidationErrors());
+        Assert.assertEquals(errors.size(), 1);
+        errors.log(log);
+
+    }
+
+    @Test(groups = {"fast"}, enabled = true)
+    public void testDataCalc() {
+        final DefaultPlan p0 = MockPlan.createBicycleTrialEvergreen1USD();
+
+        final DefaultPlan p1 = MockPlan.createBicycleTrialEvergreen1USD(100);
+
+        final DefaultPlan p2 = MockPlan.createBicycleNoTrialEvergreen1USD();
+
+        final DateTime requestedDate = new DateTime();
+        Assert.assertEquals(p0.dateOfFirstRecurringNonZeroCharge(requestedDate).compareTo(requestedDate.plusDays(30)), 0);
+        Assert.assertEquals(p1.dateOfFirstRecurringNonZeroCharge(requestedDate).compareTo(requestedDate.plusDays(100)), 0);
+        Assert.assertEquals(p2.dateOfFirstRecurringNonZeroCharge(requestedDate).compareTo(requestedDate.plusDays(0)), 0);
+
+    }
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java b/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
index bee4e3d..ee3f11e 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
@@ -16,68 +16,67 @@
 
 package com.ning.billing.catalog;
 
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.CatalogApiException;
-import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.util.config.ValidationErrors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.util.config.ValidationErrors;
+
 public class TestPlanPhase {
-	Logger log = LoggerFactory.getLogger(TestPlanPhase.class);
-	
-	@Test(enabled=true)
-	public void testValidation() {
-		log.info("Testing Plan Phase Validation");
-		
-		DefaultPlanPhase pp = MockPlanPhase.createUSDMonthlyEvergreen(null, "1.00").setPlan(MockPlan.createBicycleNoTrialEvergreen1USD());//new MockPlanPhase().setBillCycleDuration(BillingPeriod.MONTHLY).setRecurringPrice(null).setFixedPrice(new DefaultInternationalPrice());
-		
-		ValidationErrors errors = pp.validate(new MockCatalog(), new ValidationErrors());
-		errors.log(log);
-		Assert.assertEquals(errors.size(), 1);
-
-		pp = MockPlanPhase.createUSDMonthlyEvergreen("1.00", null).setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD).setPlan(MockPlan.createBicycleNoTrialEvergreen1USD());// new MockPlanPhase().setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD).setRecurringPrice(new MockInternationalPrice());
-		errors = pp.validate(new MockCatalog(), new ValidationErrors());
-		errors.log(log);
-		Assert.assertEquals(errors.size(), 1);
-
-		pp = MockPlanPhase.createUSDMonthlyEvergreen(null, null).setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD).setPlan(MockPlan.createBicycleNoTrialEvergreen1USD());//new MockPlanPhase().setRecurringPrice(null).setFixedPrice(null).setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD);
-		errors = pp.validate(new MockCatalog(), new ValidationErrors());
-		errors.log(log);
-		Assert.assertEquals(errors.size(), 1);
-	}
-	
-	@Test
-	public void testPhaseNames() throws CatalogApiException {
-		String planName = "Foo";
-		String planNameExt = planName + "-";
-		
-		DefaultPlan p = MockPlan.createBicycleNoTrialEvergreen1USD().setName(planName);
-		DefaultPlanPhase ppDiscount = MockPlanPhase.create1USDMonthlyEvergreen().setPhaseType(PhaseType.DISCOUNT).setPlan(p);
-		DefaultPlanPhase ppTrial = MockPlanPhase.create30DayTrial().setPhaseType(PhaseType.TRIAL).setPlan(p);
-		DefaultPlanPhase ppEvergreen = MockPlanPhase.create1USDMonthlyEvergreen().setPhaseType(PhaseType.EVERGREEN).setPlan(p);
-		DefaultPlanPhase ppFixedTerm = MockPlanPhase.create1USDMonthlyEvergreen().setPhaseType(PhaseType.FIXEDTERM).setPlan(p);
-		
-		String ppnDiscount = DefaultPlanPhase.phaseName(p.getName(), ppDiscount.getPhaseType());
-		String ppnTrial = DefaultPlanPhase.phaseName(p.getName(), ppTrial.getPhaseType());
-		String ppnEvergreen = DefaultPlanPhase.phaseName(p.getName(), ppEvergreen.getPhaseType());
-		String ppnFixedTerm = DefaultPlanPhase.phaseName(p.getName(), ppFixedTerm.getPhaseType());
-		
-		Assert.assertEquals(ppnTrial, planNameExt + "trial");
-		Assert.assertEquals(ppnEvergreen, planNameExt + "evergreen");
-		Assert.assertEquals(ppnFixedTerm, planNameExt + "fixedterm");
-		Assert.assertEquals(ppnDiscount, planNameExt + "discount");
-		
-		
-		Assert.assertEquals(DefaultPlanPhase.planName(ppnDiscount),planName);
-		Assert.assertEquals(DefaultPlanPhase.planName(ppnTrial),planName);
-		Assert.assertEquals(DefaultPlanPhase.planName(ppnEvergreen), planName);
-		Assert.assertEquals(DefaultPlanPhase.planName(ppnFixedTerm), planName);
-		
-		
-		
-		
-	}
+    Logger log = LoggerFactory.getLogger(TestPlanPhase.class);
+
+    @Test(enabled = true)
+    public void testValidation() {
+        log.info("Testing Plan Phase Validation");
+
+        DefaultPlanPhase pp = MockPlanPhase.createUSDMonthlyEvergreen(null, "1.00").setPlan(MockPlan.createBicycleNoTrialEvergreen1USD());//new MockPlanPhase().setBillCycleDuration(BillingPeriod.MONTHLY).setRecurringPrice(null).setFixedPrice(new DefaultInternationalPrice());
+
+        ValidationErrors errors = pp.validate(new MockCatalog(), new ValidationErrors());
+        errors.log(log);
+        Assert.assertEquals(errors.size(), 1);
+
+        pp = MockPlanPhase.createUSDMonthlyEvergreen("1.00", null).setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD).setPlan(MockPlan.createBicycleNoTrialEvergreen1USD());// new MockPlanPhase().setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD).setRecurringPrice(new MockInternationalPrice());
+        errors = pp.validate(new MockCatalog(), new ValidationErrors());
+        errors.log(log);
+        Assert.assertEquals(errors.size(), 1);
+
+        pp = MockPlanPhase.createUSDMonthlyEvergreen(null, null).setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD).setPlan(MockPlan.createBicycleNoTrialEvergreen1USD());//new MockPlanPhase().setRecurringPrice(null).setFixedPrice(null).setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD);
+        errors = pp.validate(new MockCatalog(), new ValidationErrors());
+        errors.log(log);
+        Assert.assertEquals(errors.size(), 1);
+    }
+
+    @Test
+    public void testPhaseNames() throws CatalogApiException {
+        final String planName = "Foo";
+        final String planNameExt = planName + "-";
+
+        final DefaultPlan p = MockPlan.createBicycleNoTrialEvergreen1USD().setName(planName);
+        final DefaultPlanPhase ppDiscount = MockPlanPhase.create1USDMonthlyEvergreen().setPhaseType(PhaseType.DISCOUNT).setPlan(p);
+        final DefaultPlanPhase ppTrial = MockPlanPhase.create30DayTrial().setPhaseType(PhaseType.TRIAL).setPlan(p);
+        final DefaultPlanPhase ppEvergreen = MockPlanPhase.create1USDMonthlyEvergreen().setPhaseType(PhaseType.EVERGREEN).setPlan(p);
+        final DefaultPlanPhase ppFixedTerm = MockPlanPhase.create1USDMonthlyEvergreen().setPhaseType(PhaseType.FIXEDTERM).setPlan(p);
+
+        final String ppnDiscount = DefaultPlanPhase.phaseName(p.getName(), ppDiscount.getPhaseType());
+        final String ppnTrial = DefaultPlanPhase.phaseName(p.getName(), ppTrial.getPhaseType());
+        final String ppnEvergreen = DefaultPlanPhase.phaseName(p.getName(), ppEvergreen.getPhaseType());
+        final String ppnFixedTerm = DefaultPlanPhase.phaseName(p.getName(), ppFixedTerm.getPhaseType());
+
+        Assert.assertEquals(ppnTrial, planNameExt + "trial");
+        Assert.assertEquals(ppnEvergreen, planNameExt + "evergreen");
+        Assert.assertEquals(ppnFixedTerm, planNameExt + "fixedterm");
+        Assert.assertEquals(ppnDiscount, planNameExt + "discount");
+
+
+        Assert.assertEquals(DefaultPlanPhase.planName(ppnDiscount), planName);
+        Assert.assertEquals(DefaultPlanPhase.planName(ppnTrial), planName);
+        Assert.assertEquals(DefaultPlanPhase.planName(ppnEvergreen), planName);
+        Assert.assertEquals(DefaultPlanPhase.planName(ppnFixedTerm), planName);
+
+
+    }
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestPriceListSet.java b/catalog/src/test/java/com/ning/billing/catalog/TestPriceListSet.java
index a26ce10..107283d 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestPriceListSet.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestPriceListSet.java
@@ -16,13 +16,14 @@
 
 package com.ning.billing.catalog;
 
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
 
 import static com.ning.billing.catalog.api.BillingPeriod.ANNUAL;
 import static com.ning.billing.catalog.api.BillingPeriod.MONTHLY;
@@ -30,56 +31,56 @@ import static com.ning.billing.catalog.api.PhaseType.DISCOUNT;
 import static com.ning.billing.catalog.api.PhaseType.EVERGREEN;
 
 public class TestPriceListSet {
-	@Test(enabled=true)
-	public void testOverriding() throws CatalogApiException {
-		DefaultProduct foo = new DefaultProduct("Foo", ProductCategory.BASE);
-		DefaultProduct bar = new DefaultProduct("Bar", ProductCategory.BASE);
-		DefaultPlan[] defaultPlans = new DefaultPlan[]{ 
-				new MockPlan().setName("plan-foo-monthly").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
-				new MockPlan().setName("plan-bar-monthly").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
-				new MockPlan().setName("plan-foo-annual").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(EVERGREEN)),
-				new MockPlan().setName("plan-bar-annual").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(EVERGREEN))
-				};
-		DefaultPlan[] childPlans = new DefaultPlan[]{ 
-				new MockPlan().setName("plan-foo").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT)),
-				new MockPlan().setName("plan-bar").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT))
-				};
-		PriceListDefault defaultPriceList = new PriceListDefault(defaultPlans);
-		DefaultPriceList[] childPriceLists = new DefaultPriceList[] {
-				new DefaultPriceList(childPlans, "child")
-		};
-		DefaultPriceListSet set = new DefaultPriceListSet(defaultPriceList, childPriceLists);
-		
-		Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
-		Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
-		Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.DISCOUNT);
-		Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
-	}
-	
-	public void testForNullBillingPeriod() throws CatalogApiException {
-		DefaultProduct foo = new DefaultProduct("Foo", ProductCategory.BASE);
-		DefaultProduct bar = new DefaultProduct("Bar", ProductCategory.BASE);
-		DefaultPlan[] defaultPlans = new DefaultPlan[]{ 
-				new MockPlan().setName("plan-foo-monthly").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
-				new MockPlan().setName("plan-bar-monthly").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
-				new MockPlan().setName("plan-foo-annual").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(null).setPhaseType(EVERGREEN)),
-				new MockPlan().setName("plan-bar-annual").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(null).setPhaseType(EVERGREEN))
-				};
-		DefaultPlan[] childPlans = new DefaultPlan[]{ 
-				new MockPlan().setName("plan-foo").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT)),
-				new MockPlan().setName("plan-bar").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT))
-				};
+    @Test(enabled = true)
+    public void testOverriding() throws CatalogApiException {
+        final DefaultProduct foo = new DefaultProduct("Foo", ProductCategory.BASE);
+        final DefaultProduct bar = new DefaultProduct("Bar", ProductCategory.BASE);
+        final DefaultPlan[] defaultPlans = new DefaultPlan[]{
+                new MockPlan().setName("plan-foo-monthly").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
+                new MockPlan().setName("plan-bar-monthly").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
+                new MockPlan().setName("plan-foo-annual").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(EVERGREEN)),
+                new MockPlan().setName("plan-bar-annual").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(EVERGREEN))
+        };
+        final DefaultPlan[] childPlans = new DefaultPlan[]{
+                new MockPlan().setName("plan-foo").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT)),
+                new MockPlan().setName("plan-bar").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT))
+        };
+        final PriceListDefault defaultPriceList = new PriceListDefault(defaultPlans);
+        final DefaultPriceList[] childPriceLists = new DefaultPriceList[]{
+                new DefaultPriceList(childPlans, "child")
+        };
+        final DefaultPriceListSet set = new DefaultPriceListSet(defaultPriceList, childPriceLists);
+
+        Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+        Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+        Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.DISCOUNT);
+        Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+    }
+
+    public void testForNullBillingPeriod() throws CatalogApiException {
+        final DefaultProduct foo = new DefaultProduct("Foo", ProductCategory.BASE);
+        final DefaultProduct bar = new DefaultProduct("Bar", ProductCategory.BASE);
+        final DefaultPlan[] defaultPlans = new DefaultPlan[]{
+                new MockPlan().setName("plan-foo-monthly").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
+                new MockPlan().setName("plan-bar-monthly").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
+                new MockPlan().setName("plan-foo-annual").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(null).setPhaseType(EVERGREEN)),
+                new MockPlan().setName("plan-bar-annual").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(null).setPhaseType(EVERGREEN))
+        };
+        final DefaultPlan[] childPlans = new DefaultPlan[]{
+                new MockPlan().setName("plan-foo").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT)),
+                new MockPlan().setName("plan-bar").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT))
+        };
+
+        final PriceListDefault defaultPriceList = new PriceListDefault(defaultPlans);
+        final DefaultPriceList[] childPriceLists = new DefaultPriceList[]{
+                new DefaultPriceList(childPlans, "child")
+        };
+        final DefaultPriceListSet set = new DefaultPriceListSet(defaultPriceList, childPriceLists);
 
-		PriceListDefault defaultPriceList = new PriceListDefault(defaultPlans);
-		DefaultPriceList[] childPriceLists = new DefaultPriceList[] {
-				new DefaultPriceList(childPlans, "child")
-		};
-		DefaultPriceListSet set = new DefaultPriceListSet(defaultPriceList, childPriceLists);
-		
-		Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.DISCOUNT);
-		Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
-		Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
-		Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
-	}
+        Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.DISCOUNT);
+        Assert.assertEquals(set.getPlanFrom("child", foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+        Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+        Assert.assertEquals(set.getPlanFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+    }
 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestStandaloneCatalog.java b/catalog/src/test/java/com/ning/billing/catalog/TestStandaloneCatalog.java
index fd5d8fb..edca7f1 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestStandaloneCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestStandaloneCatalog.java
@@ -23,30 +23,30 @@ import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PhaseType;
 
 public class TestStandaloneCatalog {
-	
-		@Test
-		public void testFindPhase() throws CatalogApiException{
-			DefaultPlanPhase phaseTrial1 = new MockPlanPhase().setPhaseType(PhaseType.TRIAL);
-			DefaultPlanPhase phaseTrial2 = new MockPlanPhase().setPhaseType(PhaseType.TRIAL);
-			DefaultPlanPhase phaseDiscount1 = new MockPlanPhase().setPhaseType(PhaseType.DISCOUNT);
-			DefaultPlanPhase phaseDiscount2 = new MockPlanPhase().setPhaseType(PhaseType.DISCOUNT);
-			
-			DefaultPlan plan1 = new MockPlan().setName("TestPlan1").setFinalPhase(phaseDiscount1).setInitialPhases(new DefaultPlanPhase[]{phaseTrial1});
-			DefaultPlan plan2 = new MockPlan().setName("TestPlan2").setFinalPhase(phaseDiscount2).setInitialPhases(new DefaultPlanPhase[]{phaseTrial2});
-			phaseTrial1.setPlan(plan1);
-			phaseTrial2.setPlan(plan2);
-			phaseDiscount1.setPlan(plan1);
-			phaseDiscount2.setPlan(plan2);
-			
-			StandaloneCatalog cat = new MockCatalog().setPlans(new DefaultPlan[]{plan1, plan2});
-			
-			Assert.assertEquals(cat.findCurrentPhase("TestPlan1-discount"), phaseDiscount1);
-			Assert.assertEquals(cat.findCurrentPhase("TestPlan2-discount"), phaseDiscount2);
-			Assert.assertEquals(cat.findCurrentPhase("TestPlan1-trial"), phaseTrial1);
-			Assert.assertEquals(cat.findCurrentPhase("TestPlan2-trial"), phaseTrial2);
-			
-			
-		}
-		
-		
+
+    @Test
+    public void testFindPhase() throws CatalogApiException {
+        final DefaultPlanPhase phaseTrial1 = new MockPlanPhase().setPhaseType(PhaseType.TRIAL);
+        final DefaultPlanPhase phaseTrial2 = new MockPlanPhase().setPhaseType(PhaseType.TRIAL);
+        final DefaultPlanPhase phaseDiscount1 = new MockPlanPhase().setPhaseType(PhaseType.DISCOUNT);
+        final DefaultPlanPhase phaseDiscount2 = new MockPlanPhase().setPhaseType(PhaseType.DISCOUNT);
+
+        final DefaultPlan plan1 = new MockPlan().setName("TestPlan1").setFinalPhase(phaseDiscount1).setInitialPhases(new DefaultPlanPhase[]{phaseTrial1});
+        final DefaultPlan plan2 = new MockPlan().setName("TestPlan2").setFinalPhase(phaseDiscount2).setInitialPhases(new DefaultPlanPhase[]{phaseTrial2});
+        phaseTrial1.setPlan(plan1);
+        phaseTrial2.setPlan(plan2);
+        phaseDiscount1.setPlan(plan1);
+        phaseDiscount2.setPlan(plan2);
+
+        final StandaloneCatalog cat = new MockCatalog().setPlans(new DefaultPlan[]{plan1, plan2});
+
+        Assert.assertEquals(cat.findCurrentPhase("TestPlan1-discount"), phaseDiscount1);
+        Assert.assertEquals(cat.findCurrentPhase("TestPlan2-discount"), phaseDiscount2);
+        Assert.assertEquals(cat.findCurrentPhase("TestPlan1-trial"), phaseTrial1);
+        Assert.assertEquals(cat.findCurrentPhase("TestPlan2-trial"), phaseTrial2);
+
+
+    }
+
+
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java b/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
index fb61be7..a972fd5 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
@@ -15,17 +15,14 @@
  */
 package com.ning.billing.catalog;
 
-import static org.testng.AssertJUnit.assertEquals;
-
+import javax.xml.bind.JAXBException;
+import javax.xml.transform.TransformerException;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.util.Date;
 
-import javax.xml.bind.JAXBException;
-import javax.xml.transform.TransformerException;
-
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,72 +41,74 @@ import com.ning.billing.catalog.io.VersionedCatalogLoader;
 import com.ning.billing.lifecycle.KillbillService.ServiceException;
 import com.ning.billing.util.clock.DefaultClock;
 
+import static org.testng.AssertJUnit.assertEquals;
+
 public class TestVersionedCatalog {
-	private static final Logger log = LoggerFactory.getLogger(TestVersionedCatalog.class);
-	private final VersionedCatalogLoader loader = new VersionedCatalogLoader(new DefaultClock());
-	private VersionedCatalog vc;
-	
-	@BeforeClass(groups={"fast"})
-	public void setUp() throws ServiceException {
-		vc = loader.load(Resources.getResource("versionedCatalog").toString());
-	}
-
-	@Test(groups={"fast"},enabled=true)
-	public void testAddCatalog() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException, CatalogApiException {
-		vc.add(new StandaloneCatalog(new Date()));
-		assertEquals(4, vc.size());
-	}
-	
-		
-	@Test(groups={"fast"},enabled=true)
-	public void testFindPlanWithDates() throws Exception {
-		DateTime dt0= new DateTime("2010-01-01T00:00:00+00:00");
-		DateTime dt1 = new DateTime("2011-01-01T00:01:00+00:00");
-		DateTime dt2 = new DateTime("2011-02-02T00:01:00+00:00");
-		DateTime dt214 = new DateTime("2011-02-14T00:01:00+00:00");
-		DateTime dt3 = new DateTime("2011-03-03T00:01:00+00:00");
-		
-		// New subscription
-		try {
-			vc.findPlan("pistol-monthly", dt0, dt0);	
-			Assert.fail("Exception should have been thrown there are no plans for this date");
-		} catch (CatalogApiException e) {
-			// Expected behaviour
-			log.error("Expected exception", e);
-			
-		}
-		Plan newSubPlan1 = vc.findPlan("pistol-monthly", dt1, dt1);
-		Plan newSubPlan2 = vc.findPlan("pistol-monthly", dt2, dt2);
-		Plan newSubPlan214 = vc.findPlan("pistol-monthly", dt214, dt214);
-		Plan newSubPlan3 = vc.findPlan("pistol-monthly", dt3, dt3);
-		
-		Assert.assertEquals(newSubPlan1.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("1.0"));
-		Assert.assertEquals(newSubPlan2.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("2.0"));
-		Assert.assertEquals(newSubPlan214.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("2.0"));
-		Assert.assertEquals(newSubPlan3.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("3.0"));
-		
-		// Existing subscription
-		
-		Plan exSubPlan2 = vc.findPlan("pistol-monthly", dt2, dt1);
-		Plan exSubPlan214 = vc.findPlan("pistol-monthly", dt214, dt1);
-		Plan exSubPlan3 = vc.findPlan("pistol-monthly", dt3, dt1);
-		
-		Assert.assertEquals(exSubPlan2.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("1.0"));
-		Assert.assertEquals(exSubPlan214.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("2.0"));
-		Assert.assertEquals(exSubPlan3.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("2.0"));
-
-	}
-	
-	@Test(groups={"fast"},enabled=true)
-	public void testErrorOnDateTooEarly() {
-		DateTime dt0= new DateTime("1977-01-01T00:00:00+00:00");
-		try {
-			vc.findPlan("foo", dt0);
-			Assert.fail("Date is too early an exception should have been thrown");
-		} catch (CatalogApiException e) {
-			e.printStackTrace();
-			Assert.assertEquals(e.getCode(), ErrorCode.CAT_NO_CATALOG_FOR_GIVEN_DATE.getCode());
-
-		}
-	}
+    private static final Logger log = LoggerFactory.getLogger(TestVersionedCatalog.class);
+    private final VersionedCatalogLoader loader = new VersionedCatalogLoader(new DefaultClock());
+    private VersionedCatalog vc;
+
+    @BeforeClass(groups = {"fast"})
+    public void setUp() throws ServiceException {
+        vc = loader.load(Resources.getResource("versionedCatalog").toString());
+    }
+
+    @Test(groups = {"fast"}, enabled = true)
+    public void testAddCatalog() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException, CatalogApiException {
+        vc.add(new StandaloneCatalog(new Date()));
+        assertEquals(4, vc.size());
+    }
+
+
+    @Test(groups = {"fast"}, enabled = true)
+    public void testFindPlanWithDates() throws Exception {
+        final DateTime dt0 = new DateTime("2010-01-01T00:00:00+00:00");
+        final DateTime dt1 = new DateTime("2011-01-01T00:01:00+00:00");
+        final DateTime dt2 = new DateTime("2011-02-02T00:01:00+00:00");
+        final DateTime dt214 = new DateTime("2011-02-14T00:01:00+00:00");
+        final DateTime dt3 = new DateTime("2011-03-03T00:01:00+00:00");
+
+        // New subscription
+        try {
+            vc.findPlan("pistol-monthly", dt0, dt0);
+            Assert.fail("Exception should have been thrown there are no plans for this date");
+        } catch (CatalogApiException e) {
+            // Expected behaviour
+            log.error("Expected exception", e);
+
+        }
+        final Plan newSubPlan1 = vc.findPlan("pistol-monthly", dt1, dt1);
+        final Plan newSubPlan2 = vc.findPlan("pistol-monthly", dt2, dt2);
+        final Plan newSubPlan214 = vc.findPlan("pistol-monthly", dt214, dt214);
+        final Plan newSubPlan3 = vc.findPlan("pistol-monthly", dt3, dt3);
+
+        Assert.assertEquals(newSubPlan1.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("1.0"));
+        Assert.assertEquals(newSubPlan2.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("2.0"));
+        Assert.assertEquals(newSubPlan214.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("2.0"));
+        Assert.assertEquals(newSubPlan3.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("3.0"));
+
+        // Existing subscription
+
+        final Plan exSubPlan2 = vc.findPlan("pistol-monthly", dt2, dt1);
+        final Plan exSubPlan214 = vc.findPlan("pistol-monthly", dt214, dt1);
+        final Plan exSubPlan3 = vc.findPlan("pistol-monthly", dt3, dt1);
+
+        Assert.assertEquals(exSubPlan2.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("1.0"));
+        Assert.assertEquals(exSubPlan214.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("2.0"));
+        Assert.assertEquals(exSubPlan3.getAllPhases()[1].getRecurringPrice().getPrice(Currency.USD), new BigDecimal("2.0"));
+
+    }
+
+    @Test(groups = {"fast"}, enabled = true)
+    public void testErrorOnDateTooEarly() {
+        final DateTime dt0 = new DateTime("1977-01-01T00:00:00+00:00");
+        try {
+            vc.findPlan("foo", dt0);
+            Assert.fail("Date is too early an exception should have been thrown");
+        } catch (CatalogApiException e) {
+            e.printStackTrace();
+            Assert.assertEquals(e.getCode(), ErrorCode.CAT_NO_CATALOG_FOR_GIVEN_DATE.getCode());
+
+        }
+    }
 }
diff --git a/catalog/src/test/java/com/ning/billing/mock/catalog/MockPlan.java b/catalog/src/test/java/com/ning/billing/mock/catalog/MockPlan.java
index 2199eb9..426c690 100644
--- a/catalog/src/test/java/com/ning/billing/mock/catalog/MockPlan.java
+++ b/catalog/src/test/java/com/ning/billing/mock/catalog/MockPlan.java
@@ -29,65 +29,65 @@ import com.ning.billing.catalog.api.Product;
 
 public class MockPlan implements Plan {
 
-	@Override
-	public PlanPhase[] getInitialPhases() {
-		return null;
-	}
-
-	@Override
-	public Product getProduct() {
-		return null;
-	}
-
-	@Override
-	public String getName() {
-		return null;
-	}
-
-	@Override
-	public boolean isRetired() {
-				return false;
-	}
-
-	@Override
-	public Iterator<PlanPhase> getInitialPhaseIterator() {
-				return null;
-	}
-
-	@Override
-	public PlanPhase getFinalPhase() {
-				return null;
-	}
-
-	@Override
-	public BillingPeriod getBillingPeriod() {
-				return null;
-	}
-
-	@Override
-	public int getPlansAllowedInBundle() {
-				return 0;
-	}
-
-	@Override
-	public PlanPhase[] getAllPhases() {
-				return null;
-	}
-
-	@Override
-	public Date getEffectiveDateForExistingSubscriptons() {
-				return null;
-	}
-
-	@Override
-	public PlanPhase findPhase(String name) throws CatalogApiException {
-				return null;
-	}
-
-	@Override
-	public DateTime dateOfFirstRecurringNonZeroCharge(
-			DateTime subscriptionStartDate) {
-				return null;
-	}
+    @Override
+    public PlanPhase[] getInitialPhases() {
+        return null;
+    }
+
+    @Override
+    public Product getProduct() {
+        return null;
+    }
+
+    @Override
+    public String getName() {
+        return null;
+    }
+
+    @Override
+    public boolean isRetired() {
+        return false;
+    }
+
+    @Override
+    public Iterator<PlanPhase> getInitialPhaseIterator() {
+        return null;
+    }
+
+    @Override
+    public PlanPhase getFinalPhase() {
+        return null;
+    }
+
+    @Override
+    public BillingPeriod getBillingPeriod() {
+        return null;
+    }
+
+    @Override
+    public int getPlansAllowedInBundle() {
+        return 0;
+    }
+
+    @Override
+    public PlanPhase[] getAllPhases() {
+        return null;
+    }
+
+    @Override
+    public Date getEffectiveDateForExistingSubscriptons() {
+        return null;
+    }
+
+    @Override
+    public PlanPhase findPhase(final String name) throws CatalogApiException {
+        return null;
+    }
+
+    @Override
+    public DateTime dateOfFirstRecurringNonZeroCharge(
+            final DateTime subscriptionStartDate) {
+        return null;
+    }
 
 }

entitlement/pom.xml 18(+7 -11)

diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 1eddb80..9c5d3d2 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-entitlement</artifactId>
@@ -42,11 +42,6 @@
             <artifactId>killbill-util</artifactId>
         </dependency>
         <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <scope>test</scope>
-        </dependency>
-       <dependency>
             <groupId>joda-time</groupId>
             <artifactId>joda-time</artifactId>
         </dependency>
@@ -60,7 +55,8 @@
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.antlr</groupId>
@@ -73,7 +69,7 @@
             <artifactId>mysql-connector-mxj</artifactId>
             <scope>test</scope>
         </dependency>
-                <dependency>
+        <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-catalog</artifactId>
             <type>test-jar</type>
@@ -84,13 +80,13 @@
             <artifactId>killbill-catalog</artifactId>
             <scope>test</scope>
         </dependency>
-         <dependency>
+        <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-util</artifactId>
             <type>test-jar</type>
             <scope>test</scope>
-       </dependency> 
-         <dependency>
+        </dependency>
+        <dependency>
             <groupId>org.testng</groupId>
             <artifactId>testng</artifactId>
             <scope>test</scope>
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java
index 2965b8f..9283768 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java
@@ -27,8 +27,8 @@ import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
-import com.ning.billing.entitlement.api.migration.EntitlementMigrationApiException;
 import com.ning.billing.entitlement.api.migration.EntitlementMigrationApi.EntitlementSubscriptionMigrationCase;
+import com.ning.billing.entitlement.api.migration.EntitlementMigrationApiException;
 import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.util.clock.DefaultClock;
@@ -38,45 +38,45 @@ public class MigrationPlanAligner {
     private final CatalogService catalogService;
 
     @Inject
-    public MigrationPlanAligner(CatalogService catalogService) {
+    public MigrationPlanAligner(final CatalogService catalogService) {
         this.catalogService = catalogService;
     }
 
 
-    public TimedMigration [] getEventsMigration(EntitlementSubscriptionMigrationCase [] input, DateTime now)
-        throws EntitlementMigrationApiException {
+    public TimedMigration[] getEventsMigration(final EntitlementSubscriptionMigrationCase[] input, final DateTime now)
+            throws EntitlementMigrationApiException {
 
         try {
-            TimedMigration [] events = null;
-            Plan plan0 = catalogService.getFullCatalog().findPlan(input[0].getPlanPhaseSpecifier().getProductName(),
-                    input[0].getPlanPhaseSpecifier().getBillingPeriod(), input[0].getPlanPhaseSpecifier().getPriceListName(), now);
+            TimedMigration[] events = null;
+            final Plan plan0 = catalogService.getFullCatalog().findPlan(input[0].getPlanPhaseSpecifier().getProductName(),
+                                                                  input[0].getPlanPhaseSpecifier().getBillingPeriod(), input[0].getPlanPhaseSpecifier().getPriceListName(), now);
 
-            Plan plan1 = (input.length > 1) ? catalogService.getFullCatalog().findPlan(input[1].getPlanPhaseSpecifier().getProductName(),
-                    input[1].getPlanPhaseSpecifier().getBillingPeriod(), input[1].getPlanPhaseSpecifier().getPriceListName(), now) :
-                        null;
+            final Plan plan1 = (input.length > 1) ? catalogService.getFullCatalog().findPlan(input[1].getPlanPhaseSpecifier().getProductName(),
+                                                                                       input[1].getPlanPhaseSpecifier().getBillingPeriod(), input[1].getPlanPhaseSpecifier().getPriceListName(), now) :
+                    null;
 
             DateTime migrationStartDate = now;
 
             if (isRegularMigratedSubscription(input)) {
 
                 events = getEventsOnRegularMigration(plan0,
-                        getPlanPhase(plan0, input[0].getPlanPhaseSpecifier().getPhaseType()),
-                        input[0].getPlanPhaseSpecifier().getPriceListName(),
-                        now);
+                                                     getPlanPhase(plan0, input[0].getPlanPhaseSpecifier().getPhaseType()),
+                                                     input[0].getPlanPhaseSpecifier().getPriceListName(),
+                                                     now);
 
             } else if (isRegularFutureCancelledMigratedSubscription(input)) {
 
                 events = getEventsOnFuturePlanCancelMigration(plan0,
-                        getPlanPhase(plan0, input[0].getPlanPhaseSpecifier().getPhaseType()),
-                        input[0].getPlanPhaseSpecifier().getPriceListName(),
-                        now,
-                        input[0].getCancelledDate());
+                                                              getPlanPhase(plan0, input[0].getPlanPhaseSpecifier().getPhaseType()),
+                                                              input[0].getPlanPhaseSpecifier().getPriceListName(),
+                                                              now,
+                                                              input[0].getCancelledDate());
 
             } else if (isPhaseChangeMigratedSubscription(input)) {
 
-                PhaseType curPhaseType = input[0].getPlanPhaseSpecifier().getPhaseType();
+                final PhaseType curPhaseType = input[0].getPlanPhaseSpecifier().getPhaseType();
                 Duration curPhaseDuration = null;
-                for (PlanPhase cur : plan0.getAllPhases()) {
+                for (final PlanPhase cur : plan0.getAllPhases()) {
                     if (cur.getPhaseType() == curPhaseType) {
                         curPhaseDuration = cur.getDuration();
                         break;
@@ -84,25 +84,25 @@ public class MigrationPlanAligner {
                 }
                 if (curPhaseDuration == null) {
                     throw new EntitlementMigrationApiException(String.format("Failed to compute current phase duration for plan %s and phase %s",
-                            plan0.getName(), curPhaseType));
+                                                                             plan0.getName(), curPhaseType));
                 }
 
                 migrationStartDate = DefaultClock.removeDuration(input[1].getEffectiveDate(), curPhaseDuration);
                 events = getEventsOnFuturePhaseChangeMigration(plan0,
-                        getPlanPhase(plan0, input[0].getPlanPhaseSpecifier().getPhaseType()),
-                        input[0].getPlanPhaseSpecifier().getPriceListName(),
-                        migrationStartDate,
-                        input[1].getEffectiveDate());
+                                                               getPlanPhase(plan0, input[0].getPlanPhaseSpecifier().getPhaseType()),
+                                                               input[0].getPlanPhaseSpecifier().getPriceListName(),
+                                                               migrationStartDate,
+                                                               input[1].getEffectiveDate());
 
             } else if (isPlanChangeMigratedSubscription(input)) {
 
                 events = getEventsOnFuturePlanChangeMigration(plan0,
-                        getPlanPhase(plan0, input[0].getPlanPhaseSpecifier().getPhaseType()),
-                        plan1,
-                        getPlanPhase(plan1, input[1].getPlanPhaseSpecifier().getPhaseType()),
-                        input[0].getPlanPhaseSpecifier().getPriceListName(),
-                        now,
-                        input[1].getEffectiveDate());
+                                                              getPlanPhase(plan0, input[0].getPlanPhaseSpecifier().getPhaseType()),
+                                                              plan1,
+                                                              getPlanPhase(plan1, input[1].getPlanPhaseSpecifier().getPhaseType()),
+                                                              input[0].getPlanPhaseSpecifier().getPriceListName(),
+                                                              now,
+                                                              input[1].getEffectiveDate());
 
             } else {
                 throw new EntitlementMigrationApiException("Unknown migration type");
@@ -114,20 +114,20 @@ public class MigrationPlanAligner {
         }
     }
 
-    private TimedMigration [] getEventsOnRegularMigration(Plan plan, PlanPhase initialPhase, String priceList, DateTime effectiveDate) {
-        TimedMigration [] result = new TimedMigration[1];
+    private TimedMigration[] getEventsOnRegularMigration(final Plan plan, final PlanPhase initialPhase, final String priceList, final DateTime effectiveDate) {
+        final TimedMigration[] result = new TimedMigration[1];
         result[0] = new TimedMigration(effectiveDate, EventType.API_USER, ApiEventType.MIGRATE_ENTITLEMENT, plan, initialPhase, priceList);
         return result;
     }
 
-    private TimedMigration [] getEventsOnFuturePhaseChangeMigration(Plan plan, PlanPhase initialPhase, String priceList, DateTime effectiveDate, DateTime effectiveDateForNextPhase)
-        throws EntitlementMigrationApiException {
+    private TimedMigration[] getEventsOnFuturePhaseChangeMigration(final Plan plan, final PlanPhase initialPhase, final String priceList, final DateTime effectiveDate, final DateTime effectiveDateForNextPhase)
+            throws EntitlementMigrationApiException {
 
-        TimedMigration [] result = new TimedMigration[2];
+        final TimedMigration[] result = new TimedMigration[2];
         result[0] = new TimedMigration(effectiveDate, EventType.API_USER, ApiEventType.MIGRATE_ENTITLEMENT, plan, initialPhase, priceList);
         boolean foundCurrent = false;
         PlanPhase nextPhase = null;
-        for (PlanPhase cur : plan.getAllPhases()) {
+        for (final PlanPhase cur : plan.getAllPhases()) {
             if (cur == initialPhase) {
                 foundCurrent = true;
                 continue;
@@ -138,21 +138,21 @@ public class MigrationPlanAligner {
         }
         if (nextPhase == null) {
             throw new EntitlementMigrationApiException(String.format("Cannot find next phase for Plan %s and current Phase %s",
-                        plan.getName(), initialPhase.getName()));
+                                                                     plan.getName(), initialPhase.getName()));
         }
         result[1] = new TimedMigration(effectiveDateForNextPhase, EventType.PHASE, null, plan, nextPhase, priceList);
         return result;
     }
 
-    private TimedMigration [] getEventsOnFuturePlanChangeMigration(Plan currentPlan, PlanPhase currentPhase, Plan newPlan, PlanPhase newPhase, String priceList, DateTime effectiveDate, DateTime effectiveDateForChangePlan) {
-        TimedMigration [] result = new TimedMigration[2];
+    private TimedMigration[] getEventsOnFuturePlanChangeMigration(final Plan currentPlan, final PlanPhase currentPhase, final Plan newPlan, final PlanPhase newPhase, final String priceList, final DateTime effectiveDate, final DateTime effectiveDateForChangePlan) {
+        final TimedMigration[] result = new TimedMigration[2];
         result[0] = new TimedMigration(effectiveDate, EventType.API_USER, ApiEventType.MIGRATE_ENTITLEMENT, currentPlan, currentPhase, priceList);
         result[1] = new TimedMigration(effectiveDateForChangePlan, EventType.API_USER, ApiEventType.CHANGE, newPlan, newPhase, priceList);
         return result;
     }
 
-    private TimedMigration [] getEventsOnFuturePlanCancelMigration(Plan plan, PlanPhase initialPhase, String priceList, DateTime effectiveDate, DateTime effectiveDateForCancellation) {
-        TimedMigration [] result = new TimedMigration[2];
+    private TimedMigration[] getEventsOnFuturePlanCancelMigration(final Plan plan, final PlanPhase initialPhase, final String priceList, final DateTime effectiveDate, final DateTime effectiveDateForCancellation) {
+        final TimedMigration[] result = new TimedMigration[2];
         result[0] = new TimedMigration(effectiveDate, EventType.API_USER, ApiEventType.MIGRATE_ENTITLEMENT, plan, initialPhase, priceList);
         result[1] = new TimedMigration(effectiveDateForCancellation, EventType.API_USER, ApiEventType.CANCEL, null, null, null);
         return result;
@@ -160,8 +160,8 @@ public class MigrationPlanAligner {
 
 
     // STEPH should be in catalog
-    private PlanPhase getPlanPhase(Plan plan, PhaseType phaseType) throws EntitlementMigrationApiException {
-        for (PlanPhase cur: plan.getAllPhases()) {
+    private PlanPhase getPlanPhase(final Plan plan, final PhaseType phaseType) throws EntitlementMigrationApiException {
+        for (final PlanPhase cur : plan.getAllPhases()) {
             if (cur.getPhaseType() == phaseType) {
                 return cur;
             }
@@ -169,15 +169,15 @@ public class MigrationPlanAligner {
         throw new EntitlementMigrationApiException(String.format("Cannot find PlanPhase from Plan %s and type %s", plan.getName(), phaseType));
     }
 
-    private boolean isRegularMigratedSubscription(EntitlementSubscriptionMigrationCase [] input) {
+    private boolean isRegularMigratedSubscription(final EntitlementSubscriptionMigrationCase[] input) {
         return (input.length == 1 && input[0].getCancelledDate() == null);
     }
 
-    private boolean isRegularFutureCancelledMigratedSubscription(EntitlementSubscriptionMigrationCase [] input) {
+    private boolean isRegularFutureCancelledMigratedSubscription(final EntitlementSubscriptionMigrationCase[] input) {
         return (input.length == 1 && input[0].getCancelledDate() != null);
     }
 
-    private boolean isPhaseChangeMigratedSubscription(EntitlementSubscriptionMigrationCase [] input) {
+    private boolean isPhaseChangeMigratedSubscription(final EntitlementSubscriptionMigrationCase[] input) {
         if (input.length != 2) {
             return false;
         }
@@ -185,14 +185,14 @@ public class MigrationPlanAligner {
                 !isSamePhase(input[0].getPlanPhaseSpecifier(), input[1].getPlanPhaseSpecifier()));
     }
 
-    private boolean isPlanChangeMigratedSubscription(EntitlementSubscriptionMigrationCase [] input) {
+    private boolean isPlanChangeMigratedSubscription(final EntitlementSubscriptionMigrationCase[] input) {
         if (input.length != 2) {
             return false;
         }
-        return ! isSamePlan(input[0].getPlanPhaseSpecifier(), input[1].getPlanPhaseSpecifier());
+        return !isSamePlan(input[0].getPlanPhaseSpecifier(), input[1].getPlanPhaseSpecifier());
     }
 
-    private boolean isSamePlan(PlanPhaseSpecifier plan0, PlanPhaseSpecifier plan1) {
+    private boolean isSamePlan(final PlanPhaseSpecifier plan0, final PlanPhaseSpecifier plan1) {
         if (plan0.getPriceListName().equals(plan1.getPriceListName()) &&
                 plan0.getProductName().equals(plan1.getProductName()) &&
                 plan0.getBillingPeriod() == plan1.getBillingPeriod()) {
@@ -201,7 +201,7 @@ public class MigrationPlanAligner {
         return false;
     }
 
-    private boolean isSamePhase(PlanPhaseSpecifier plan0, PlanPhaseSpecifier plan1) {
+    private boolean isSamePhase(final PlanPhaseSpecifier plan0, final PlanPhaseSpecifier plan1) {
         if (plan0.getPhaseType() == plan1.getPhaseType()) {
             return true;
         }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
index 0e44528..d31452d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
@@ -16,32 +16,42 @@
 
 package com.ning.billing.entitlement.alignment;
 
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.joda.time.DateTime;
+
 import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
-import com.ning.billing.catalog.api.*;
+import com.ning.billing.catalog.api.Catalog;
+import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.CatalogService;
+import com.ning.billing.catalog.api.Duration;
+import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanAlignmentChange;
+import com.ning.billing.catalog.api.PlanAlignmentCreate;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.catalog.api.PlanPhaseSpecifier;
+import com.ning.billing.catalog.api.PlanSpecifier;
+import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.clock.DefaultClock;
-import org.joda.time.DateTime;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
 
 /**
- *
  * PlanAligner offers specific APIs to return the correct {@code TimedPhase} when creating, changing Plan or to compute next Phase on current Plan.
- * <p>
- *
+ * <p/>
  */
-public class PlanAligner  {
+public class PlanAligner {
 
     private final CatalogService catalogService;
 
     @Inject
-    public PlanAligner(CatalogService catalogService) {
+    public PlanAligner(final CatalogService catalogService) {
         this.catalogService = catalogService;
     }
 
@@ -52,106 +62,109 @@ public class PlanAligner  {
 
     /**
      * Returns the current and next phase for the subscription in creation
-     * <p>
-     * @param subscription the subscription in creation
-     * @param plan the current Plan
-     * @param initialPhase the initialPhase on which we should create that subscription. can be null
-     * @param priceList the priceList
+     * <p/>
+     *
+     * @param subscription  the subscription in creation
+     * @param plan          the current Plan
+     * @param initialPhase  the initialPhase on which we should create that subscription. can be null
+     * @param priceList     the priceList
      * @param effectiveDate the effective creation date
      * @return
      * @throws CatalogApiException
      * @throws EntitlementUserApiException
      */
-    public TimedPhase [] getCurrentAndNextTimedPhaseOnCreate(final SubscriptionData subscription,
-            final Plan plan, final PhaseType initialPhase, final String priceList, final DateTime requestedDate, final DateTime effectiveDate)
-        throws CatalogApiException, EntitlementUserApiException {
-        List<TimedPhase> timedPhases = getTimedPhaseOnCreate(subscription.getStartDate(),
-                subscription.getBundleStartDate(), plan, initialPhase, priceList, requestedDate);
-        TimedPhase [] result = new TimedPhase[2];
+    public TimedPhase[] getCurrentAndNextTimedPhaseOnCreate(final SubscriptionData subscription,
+                                                            final Plan plan, final PhaseType initialPhase, final String priceList, final DateTime requestedDate, final DateTime effectiveDate)
+            throws CatalogApiException, EntitlementUserApiException {
+        final List<TimedPhase> timedPhases = getTimedPhaseOnCreate(subscription.getStartDate(),
+                                                             subscription.getBundleStartDate(), plan, initialPhase, priceList, requestedDate);
+        final TimedPhase[] result = new TimedPhase[2];
         result[0] = getTimedPhase(timedPhases, effectiveDate, WhichPhase.CURRENT);
         result[1] = getTimedPhase(timedPhases, effectiveDate, WhichPhase.NEXT);
         return result;
     }
 
     /**
-     *
      * Returns current Phase for that Plan change
-     * <p>
-     * @param subscription the subscription in creation
-     * @param plan the current Plan
-     * @param priceList the priceList on which we should change that subscription.
+     * <p/>
+     *
+     * @param subscription  the subscription in creation
+     * @param plan          the current Plan
+     * @param priceList     the priceList on which we should change that subscription.
      * @param effectiveDate the effective change date
      * @return
      * @throws CatalogApiException
      * @throws EntitlementUserApiException
      */
     public TimedPhase getCurrentTimedPhaseOnChange(final SubscriptionData subscription,
-            final Plan plan, final String priceList, final DateTime requestedDate, final DateTime effectiveDate)
-        throws CatalogApiException, EntitlementUserApiException {
+                                                   final Plan plan, final String priceList, final DateTime requestedDate, final DateTime effectiveDate)
+            throws CatalogApiException, EntitlementUserApiException {
         return getTimedPhaseOnChange(subscription, plan, priceList, requestedDate, effectiveDate, WhichPhase.CURRENT);
     }
 
     /**
      * Returns next Phase for that Plan change
-     * <p>
-     * @param subscription the subscription in creation
-     * @param plan the current Plan
-     * @param priceList the priceList on which we should change that subscription.
+     * <p/>
+     *
+     * @param subscription  the subscription in creation
+     * @param plan          the current Plan
+     * @param priceList     the priceList on which we should change that subscription.
      * @param effectiveDate the effective change date
      * @return
      * @throws CatalogApiException
      * @throws EntitlementUserApiException
      */
     public TimedPhase getNextTimedPhaseOnChange(final SubscriptionData subscription,
-            final Plan plan, final String priceList, final DateTime requestedDate, final DateTime effectiveDate)
-        throws CatalogApiException, EntitlementUserApiException {
+                                                final Plan plan, final String priceList, final DateTime requestedDate, final DateTime effectiveDate)
+            throws CatalogApiException, EntitlementUserApiException {
         return getTimedPhaseOnChange(subscription, plan, priceList, requestedDate, effectiveDate, WhichPhase.NEXT);
     }
 
 
     /**
      * Returns next Phase for that Subscription at a point in time
-     * <p>
-     * @param subscription the subscription for which we need to compute the next Phase event
+     * <p/>
+     *
+     * @param subscription  the subscription for which we need to compute the next Phase event
      * @param effectiveDate the date at which we look to compute that event. effective needs to be after last Plan change or initial Plan
      * @return The PhaseEvent at the correct point in time
      */
     public TimedPhase getNextTimedPhase(final SubscriptionData subscription, final DateTime requestedDate, final DateTime effectiveDate) {
         try {
 
-            SubscriptionTransitionData lastPlanTransition = subscription.getInitialTransitionForCurrentPlan();
+            final SubscriptionTransitionData lastPlanTransition = subscription.getInitialTransitionForCurrentPlan();
             if (effectiveDate.isBefore(lastPlanTransition.getEffectiveTransitionTime())) {
                 throw new EntitlementError(String.format("Cannot specify an effectiveDate prior to last Plan Change, subscription = %s, effectiveDate = %s",
-                        subscription.getId(), effectiveDate));
+                                                         subscription.getId(), effectiveDate));
             }
 
-            switch(lastPlanTransition.getTransitionType()) {
-            // If we never had any Plan change, borrow the logics for createPlan alignment
-            case MIGRATE_ENTITLEMENT:
-            case CREATE:
-            case RE_CREATE:                
-                List<TimedPhase> timedPhases = getTimedPhaseOnCreate(subscription.getStartDate(),
-                        subscription.getBundleStartDate(),
-                        lastPlanTransition.getNextPlan(),
-                        lastPlanTransition.getNextPhase().getPhaseType(),
-                        lastPlanTransition.getNextPriceList().getName(),
-                        requestedDate);
-                return getTimedPhase(timedPhases, effectiveDate, WhichPhase.NEXT);
-            // If we went through Plan changes, borrow the logics for changePlan alignement
-            case CHANGE:
-                return getTimedPhaseOnChange(subscription.getStartDate(),
-                        subscription.getBundleStartDate(),
-                        lastPlanTransition.getPreviousPhase(),
-                        lastPlanTransition.getPreviousPlan(),
-                        lastPlanTransition.getPreviousPriceList().getName(),
-                        lastPlanTransition.getNextPlan(),
-                        lastPlanTransition.getNextPriceList().getName(),
-                        requestedDate,
-                        effectiveDate,
-                        WhichPhase.NEXT);
-            default:
-                throw new EntitlementError(String.format("Unexpectd initial transition %s for current plan %s on subscription %s",
-                        lastPlanTransition.getTransitionType(), subscription.getCurrentPlan(), subscription.getId()));
+            switch (lastPlanTransition.getTransitionType()) {
+                // If we never had any Plan change, borrow the logics for createPlan alignment
+                case MIGRATE_ENTITLEMENT:
+                case CREATE:
+                case RE_CREATE:
+                    final List<TimedPhase> timedPhases = getTimedPhaseOnCreate(subscription.getStartDate(),
+                                                                         subscription.getBundleStartDate(),
+                                                                         lastPlanTransition.getNextPlan(),
+                                                                         lastPlanTransition.getNextPhase().getPhaseType(),
+                                                                         lastPlanTransition.getNextPriceList().getName(),
+                                                                         requestedDate);
+                    return getTimedPhase(timedPhases, effectiveDate, WhichPhase.NEXT);
+                // If we went through Plan changes, borrow the logics for changePlan alignement
+                case CHANGE:
+                    return getTimedPhaseOnChange(subscription.getStartDate(),
+                                                 subscription.getBundleStartDate(),
+                                                 lastPlanTransition.getPreviousPhase(),
+                                                 lastPlanTransition.getPreviousPlan(),
+                                                 lastPlanTransition.getPreviousPriceList().getName(),
+                                                 lastPlanTransition.getNextPlan(),
+                                                 lastPlanTransition.getNextPriceList().getName(),
+                                                 requestedDate,
+                                                 effectiveDate,
+                                                 WhichPhase.NEXT);
+                default:
+                    throw new EntitlementError(String.format("Unexpectd initial transition %s for current plan %s on subscription %s",
+                                                             lastPlanTransition.getTransitionType(), subscription.getCurrentPlan(), subscription.getId()));
             }
         } catch (Exception /* EntitlementUserApiException, CatalogApiException */ e) {
             throw new EntitlementError(String.format("Could not compute next phase change for subscription %s", subscription.getId()), e);
@@ -159,102 +172,102 @@ public class PlanAligner  {
     }
 
 
-    private List<TimedPhase> getTimedPhaseOnCreate(DateTime subscriptionStartDate,
-            DateTime bundleStartDate,
-            Plan plan, PhaseType initialPhase, String priceList, DateTime requestedDate)
-        throws CatalogApiException, EntitlementUserApiException  {
+    private List<TimedPhase> getTimedPhaseOnCreate(final DateTime subscriptionStartDate,
+                                                   final DateTime bundleStartDate,
+                                                   final Plan plan, final PhaseType initialPhase, final String priceList, final DateTime requestedDate)
+            throws CatalogApiException, EntitlementUserApiException {
 
-        Catalog catalog = catalogService.getFullCatalog();
+        final Catalog catalog = catalogService.getFullCatalog();
 
-        PlanSpecifier planSpecifier = new PlanSpecifier(plan.getProduct().getName(),
-                plan.getProduct().getCategory(),
-                plan.getBillingPeriod(),
-                priceList);
+        final PlanSpecifier planSpecifier = new PlanSpecifier(plan.getProduct().getName(),
+                                                        plan.getProduct().getCategory(),
+                                                        plan.getBillingPeriod(),
+                                                        priceList);
 
         DateTime planStartDate = null;
-        PlanAlignmentCreate alignement = catalog.planCreateAlignment(planSpecifier, requestedDate);
-        switch(alignement) {
-        case START_OF_SUBSCRIPTION:
-            planStartDate = subscriptionStartDate;
-            break;
-        case START_OF_BUNDLE:
-            planStartDate = bundleStartDate;
-            break;
-        default:
-            throw new EntitlementError(String.format("Unknwon PlanAlignmentCreate %s", alignement));
+        final PlanAlignmentCreate alignement = catalog.planCreateAlignment(planSpecifier, requestedDate);
+        switch (alignement) {
+            case START_OF_SUBSCRIPTION:
+                planStartDate = subscriptionStartDate;
+                break;
+            case START_OF_BUNDLE:
+                planStartDate = bundleStartDate;
+                break;
+            default:
+                throw new EntitlementError(String.format("Unknwon PlanAlignmentCreate %s", alignement));
         }
         return getPhaseAlignments(plan, initialPhase, planStartDate);
     }
 
-    private TimedPhase getTimedPhaseOnChange(SubscriptionData subscription,
-            Plan nextPlan, String nextPriceList, DateTime requestedDate, DateTime effectiveDate, WhichPhase which)
-        throws CatalogApiException, EntitlementUserApiException {
+    private TimedPhase getTimedPhaseOnChange(final SubscriptionData subscription,
+                                             final Plan nextPlan, final String nextPriceList, final DateTime requestedDate, final DateTime effectiveDate, final WhichPhase which)
+            throws CatalogApiException, EntitlementUserApiException {
         return getTimedPhaseOnChange(subscription.getStartDate(),
-                subscription.getBundleStartDate(),
-                subscription.getCurrentPhase(),
-                subscription.getCurrentPlan(),
-                subscription.getCurrentPriceList().getName(),
-                nextPlan,
-                nextPriceList,
-                requestedDate,
-                effectiveDate,
-                which);
+                                     subscription.getBundleStartDate(),
+                                     subscription.getCurrentPhase(),
+                                     subscription.getCurrentPlan(),
+                                     subscription.getCurrentPriceList().getName(),
+                                     nextPlan,
+                                     nextPriceList,
+                                     requestedDate,
+                                     effectiveDate,
+                                     which);
     }
 
 
-    private TimedPhase getTimedPhaseOnChange(DateTime subscriptionStartDate,
-            DateTime bundleStartDate,
-            PlanPhase currentPhase,
-            Plan currentPlan,
-            String currentPriceList,
-            Plan nextPlan, String priceList, DateTime requestedDate, DateTime effectiveDate, WhichPhase which)
-        throws CatalogApiException, EntitlementUserApiException {
+    private TimedPhase getTimedPhaseOnChange(final DateTime subscriptionStartDate,
+                                             final DateTime bundleStartDate,
+                                             final PlanPhase currentPhase,
+                                             final Plan currentPlan,
+                                             final String currentPriceList,
+                                             final Plan nextPlan, final String priceList, final DateTime requestedDate, final DateTime effectiveDate, final WhichPhase which)
+            throws CatalogApiException, EntitlementUserApiException {
 
-        Catalog catalog = catalogService.getFullCatalog();
-        ProductCategory currentCategory = currentPlan.getProduct().getCategory();
-        PlanPhaseSpecifier fromPlanPhaseSpecifier = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
-                currentCategory,
-                currentPlan.getBillingPeriod(),
-                currentPriceList,
-                currentPhase.getPhaseType());
+        final Catalog catalog = catalogService.getFullCatalog();
+        final ProductCategory currentCategory = currentPlan.getProduct().getCategory();
+        final PlanPhaseSpecifier fromPlanPhaseSpecifier = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
+                                                                           currentCategory,
+                                                                           currentPlan.getBillingPeriod(),
+                                                                           currentPriceList,
+                                                                           currentPhase.getPhaseType());
 
-        PlanSpecifier toPlanSpecifier = new PlanSpecifier(nextPlan.getProduct().getName(),
-                nextPlan.getProduct().getCategory(),
-                nextPlan.getBillingPeriod(),
-                priceList);
+        final PlanSpecifier toPlanSpecifier = new PlanSpecifier(nextPlan.getProduct().getName(),
+                                                          nextPlan.getProduct().getCategory(),
+                                                          nextPlan.getBillingPeriod(),
+                                                          priceList);
 
         DateTime planStartDate = null;
-        PlanAlignmentChange alignment = catalog.planChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier, requestedDate);
-        switch(alignment) {
-        case START_OF_SUBSCRIPTION:
-            planStartDate = subscriptionStartDate;
-            break;
-        case START_OF_BUNDLE:
-            planStartDate = bundleStartDate;
-            break;
-        case CHANGE_OF_PLAN:
-            planStartDate = requestedDate;
-            break;
-        case CHANGE_OF_PRICELIST:
-            throw new EntitlementError(String.format("Not implemented yet %s", alignment));
-        default:
-            throw new EntitlementError(String.format("Unknwon PlanAlignmentChange %s", alignment));
+        final PlanAlignmentChange alignment = catalog.planChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier, requestedDate);
+        switch (alignment) {
+            case START_OF_SUBSCRIPTION:
+                planStartDate = subscriptionStartDate;
+                break;
+            case START_OF_BUNDLE:
+                planStartDate = bundleStartDate;
+                break;
+            case CHANGE_OF_PLAN:
+                planStartDate = requestedDate;
+                break;
+            case CHANGE_OF_PRICELIST:
+                throw new EntitlementError(String.format("Not implemented yet %s", alignment));
+            default:
+                throw new EntitlementError(String.format("Unknwon PlanAlignmentChange %s", alignment));
         }
-        List<TimedPhase> timedPhases = getPhaseAlignments(nextPlan, null, planStartDate);
+        final List<TimedPhase> timedPhases = getPhaseAlignments(nextPlan, null, planStartDate);
         return getTimedPhase(timedPhases, effectiveDate, which);
     }
 
 
-    private List<TimedPhase> getPhaseAlignments(Plan plan, PhaseType initialPhase, DateTime initialPhaseStartDate)
-        throws EntitlementUserApiException {
+    private List<TimedPhase> getPhaseAlignments(final Plan plan, final PhaseType initialPhase, final DateTime initialPhaseStartDate)
+            throws EntitlementUserApiException {
         if (plan == null) {
             return Collections.emptyList();
         }
 
-        List<TimedPhase> result = new LinkedList<TimedPhase>();
+        final List<TimedPhase> result = new LinkedList<TimedPhase>();
         DateTime curPhaseStart = (initialPhase == null) ? initialPhaseStartDate : null;
         DateTime nextPhaseStart = null;
-        for (PlanPhase cur : plan.getAllPhases()) {
+        for (final PlanPhase cur : plan.getAllPhases()) {
             // For create we can specify the phase so skip any phase until we reach initialPhase
             if (curPhaseStart == null) {
                 if (initialPhase != cur.getPhaseType()) {
@@ -267,11 +280,11 @@ public class PlanAligner  {
 
             // STEPH check for duration null instead TimeUnit UNLIMITED
             if (cur.getPhaseType() != PhaseType.EVERGREEN) {
-                Duration curPhaseDuration = cur.getDuration();
+                final Duration curPhaseDuration = cur.getDuration();
                 nextPhaseStart = DefaultClock.addDuration(curPhaseStart, curPhaseDuration);
                 if (nextPhaseStart == null) {
                     throw new EntitlementError(String.format("Unexpected non ending UNLIMITED phase for plan %s",
-                            plan.getName()));
+                                                             plan.getName()));
                 }
                 curPhaseStart = nextPhaseStart;
             }
@@ -283,23 +296,23 @@ public class PlanAligner  {
     }
 
     // STEPH check for non evergreen Plans and what happens
-    private TimedPhase getTimedPhase(List<TimedPhase> timedPhases, DateTime effectiveDate, WhichPhase which) {
+    private TimedPhase getTimedPhase(final List<TimedPhase> timedPhases, final DateTime effectiveDate, final WhichPhase which) {
         TimedPhase cur = null;
         TimedPhase next = null;
-        for (TimedPhase phase : timedPhases) {
+        for (final TimedPhase phase : timedPhases) {
             if (phase.getStartPhase().isAfter(effectiveDate)) {
                 next = phase;
                 break;
             }
             cur = phase;
         }
-        switch(which) {
-        case CURRENT:
-            return cur;
-        case NEXT:
-            return next;
-        default:
-            throw new EntitlementError(String.format("Unexpected %s TimedPhase", which));
+        switch (which) {
+            case CURRENT:
+                return cur;
+            case NEXT:
+                return next;
+            default:
+                throw new EntitlementError(String.format("Unexpected %s TimedPhase", which));
         }
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/TimedMigration.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/TimedMigration.java
index e1ad564..c692ca5 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/TimedMigration.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/TimedMigration.java
@@ -34,8 +34,8 @@ public class TimedMigration {
     private final String priceList;
 
 
-    public TimedMigration(DateTime eventTime, EventType eventType,
-            ApiEventType apiEventType, Plan plan, PlanPhase phase, String priceList) {
+    public TimedMigration(final DateTime eventTime, final EventType eventType,
+                          final ApiEventType apiEventType, final Plan plan, final PlanPhase phase, final String priceList) {
         super();
         this.eventTime = eventTime;
         this.eventType = eventType;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/TimedPhase.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/TimedPhase.java
index 889d0ac..fb7bc1b 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/TimedPhase.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/TimedPhase.java
@@ -16,16 +16,17 @@
 
 package com.ning.billing.entitlement.alignment;
 
-import com.ning.billing.catalog.api.PlanPhase;
 import org.joda.time.DateTime;
 
+import com.ning.billing.catalog.api.PlanPhase;
+
 
 public final class TimedPhase {
 
     private final PlanPhase phase;
     private final DateTime startPhase;
 
-    public TimedPhase(PlanPhase phase, DateTime startPhase) {
+    public TimedPhase(final PlanPhase phase, final DateTime startPhase) {
         super();
         this.phase = phase;
         this.startPhase = startPhase;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultChargeThruApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultChargeThruApi.java
index 21b97f8..8468183 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultChargeThruApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultChargeThruApi.java
@@ -30,26 +30,26 @@ import com.ning.billing.util.callcontext.CallContext;
 public class DefaultChargeThruApi implements ChargeThruApi {
     private final EntitlementDao entitlementDao;
     private final SubscriptionFactory subscriptionFactory;
-  
+
     @Inject
     public DefaultChargeThruApi(final SubscriptionFactory subscriptionFactory, final EntitlementDao dao) {
         super();
         this.subscriptionFactory = subscriptionFactory;
         this.entitlementDao = dao;
     }
-    
+
     @Override
     public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) {
         return entitlementDao.getAccountIdFromSubscriptionId(subscriptionId);
     }
 
     @Override
-    public void setChargedThroughDate(final UUID subscriptionId, final DateTime ctd, CallContext context) {
-        SubscriptionData subscription = (SubscriptionData) entitlementDao.getSubscriptionFromId(subscriptionFactory, subscriptionId);
+    public void setChargedThroughDate(final UUID subscriptionId, final DateTime ctd, final CallContext context) {
+        final SubscriptionData subscription = (SubscriptionData) entitlementDao.getSubscriptionFromId(subscriptionFactory, subscriptionId);
 
-        SubscriptionBuilder builder = new SubscriptionBuilder(subscription)
-            .setChargedThroughDate(ctd)
-            .setPaidThroughDate(subscription.getPaidThroughDate());
+        final SubscriptionBuilder builder = new SubscriptionBuilder(subscription)
+                .setChargedThroughDate(ctd)
+                .setPaidThroughDate(subscription.getPaidThroughDate());
         entitlementDao.updateChargedThroughDate(new SubscriptionData(builder), context);
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/AccountMigrationData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/AccountMigrationData.java
index 07a0034..560516e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/AccountMigrationData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/AccountMigrationData.java
@@ -18,9 +18,9 @@ package com.ning.billing.entitlement.api.migration;
 
 import java.util.List;
 
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.user.ApiEventMigrateBilling;
 
@@ -28,7 +28,7 @@ public class AccountMigrationData {
 
     private final List<BundleMigrationData> data;
 
-    public AccountMigrationData(List<BundleMigrationData> data) {
+    public AccountMigrationData(final List<BundleMigrationData> data) {
         super();
         this.data = data;
     }
@@ -42,8 +42,8 @@ public class AccountMigrationData {
         private final SubscriptionBundleData data;
         private final List<SubscriptionMigrationData> subscriptions;
 
-        public BundleMigrationData(SubscriptionBundleData data,
-                List<SubscriptionMigrationData> subscriptions) {
+        public BundleMigrationData(final SubscriptionBundleData data,
+                                   final List<SubscriptionMigrationData> subscriptions) {
             super();
             this.data = data;
             this.subscriptions = subscriptions;
@@ -63,12 +63,12 @@ public class AccountMigrationData {
         private final SubscriptionData data;
         private final List<EntitlementEvent> initialEvents;
 
-        public SubscriptionMigrationData(SubscriptionData data,
-                    List<EntitlementEvent> initialEvents) {
+        public SubscriptionMigrationData(final SubscriptionData data,
+                                         final List<EntitlementEvent> initialEvents) {
             super();
             // Set CTD to subscription object from MIGRATION_BILLING event
-            SubscriptionBuilder builder = new SubscriptionBuilder(data);
-            for (EntitlementEvent cur : initialEvents) {
+            final SubscriptionBuilder builder = new SubscriptionBuilder(data);
+            for (final EntitlementEvent cur : initialEvents) {
                 if (cur instanceof ApiEventMigrateBilling) {
                     builder.setChargedThroughDate(cur.getEffectiveDate());
                 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java
index b09fc17..e0f2860 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/migration/DefaultEntitlementMigrationApi.java
@@ -23,7 +23,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.callcontext.CallContext;
 import org.joda.time.DateTime;
 
 import com.google.common.collect.Lists;
@@ -34,9 +33,9 @@ import com.ning.billing.entitlement.alignment.TimedMigration;
 import com.ning.billing.entitlement.api.SubscriptionFactory;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.BundleMigrationData;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.SubscriptionMigrationData;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
@@ -50,6 +49,7 @@ import com.ning.billing.entitlement.events.user.ApiEventMigrateBilling;
 import com.ning.billing.entitlement.events.user.ApiEventMigrateEntitlement;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.clock.Clock;
 
 public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
@@ -59,10 +59,10 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
     private final Clock clock;
 
     @Inject
-    public DefaultEntitlementMigrationApi(MigrationPlanAligner migrationAligner,
-            SubscriptionFactory factory,
-            EntitlementDao dao,
-            Clock clock) {
+    public DefaultEntitlementMigrationApi(final MigrationPlanAligner migrationAligner,
+                                          final SubscriptionFactory factory,
+                                          final EntitlementDao dao,
+                                          final Clock clock) {
         this.dao = dao;
         this.migrationAligner = migrationAligner;
         this.factory = factory;
@@ -70,43 +70,39 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
     }
 
     @Override
-    public void migrate(EntitlementAccountMigration toBeMigrated, CallContext context)
-    throws EntitlementMigrationApiException {
-        AccountMigrationData accountMigrationData = createAccountMigrationData(toBeMigrated, context);
+    public void migrate(final EntitlementAccountMigration toBeMigrated, final CallContext context)
+            throws EntitlementMigrationApiException {
+        final AccountMigrationData accountMigrationData = createAccountMigrationData(toBeMigrated, context);
         dao.migrate(toBeMigrated.getAccountKey(), accountMigrationData, context);
     }
 
-    private AccountMigrationData createAccountMigrationData(EntitlementAccountMigration toBeMigrated, CallContext context)
-    throws EntitlementMigrationApiException  {
+    private AccountMigrationData createAccountMigrationData(final EntitlementAccountMigration toBeMigrated, final CallContext context)
+            throws EntitlementMigrationApiException {
 
         final UUID accountId = toBeMigrated.getAccountKey();
         final DateTime now = clock.getUTCNow();
 
-        List<BundleMigrationData> accountBundleData = new LinkedList<BundleMigrationData>();
+        final List<BundleMigrationData> accountBundleData = new LinkedList<BundleMigrationData>();
 
         for (final EntitlementBundleMigration curBundle : toBeMigrated.getBundles()) {
 
-            SubscriptionBundleData bundleData = new SubscriptionBundleData(curBundle.getBundleKey(), accountId, clock.getUTCNow());
-            List<SubscriptionMigrationData> bundleSubscriptionData = new LinkedList<AccountMigrationData.SubscriptionMigrationData>();
+            final SubscriptionBundleData bundleData = new SubscriptionBundleData(curBundle.getBundleKey(), accountId, clock.getUTCNow());
+            final List<SubscriptionMigrationData> bundleSubscriptionData = new LinkedList<AccountMigrationData.SubscriptionMigrationData>();
 
 
-            List<EntitlementSubscriptionMigration> sortedSubscriptions = Lists.newArrayList(curBundle.getSubscriptions());
-            // Make sure we have first mpp or legacy, then addon and for each category order by CED
+            final List<EntitlementSubscriptionMigration> sortedSubscriptions = Lists.newArrayList(curBundle.getSubscriptions());
+            // Make sure we have first BASE or STANDALONE, then ADDON and for each category order by CED
             Collections.sort(sortedSubscriptions, new Comparator<EntitlementSubscriptionMigration>() {
                 @Override
-                public int compare(EntitlementSubscriptionMigration o1,
-                        EntitlementSubscriptionMigration o2) {
+                public int compare(final EntitlementSubscriptionMigration o1,
+                                   final EntitlementSubscriptionMigration o2) {
                     if (o1.getCategory().equals(o2.getCategory())) {
                         return o1.getSubscriptionCases()[0].getEffectiveDate().compareTo(o2.getSubscriptionCases()[0].getEffectiveDate());
                     } else {
-                        if (o1.getCategory().equals("mpp")) {
-                            return -1;
-                        } else if (o2.getCategory().equals("mpp")) {
-                            return 1;
-                        } else if (o1.getCategory().equals("legacy")) {
+                    	if (!o1.getCategory().name().equalsIgnoreCase("ADD_ON")) {
                             return -1;
-                        } else if (o2.getCategory().equals("legacy")) {
-                            return 1;
+                        } else if (o1.getCategory().name().equalsIgnoreCase("ADD_ON")) {
+                            return 1;                    
                         } else {
                             return 0;
                         }
@@ -115,98 +111,98 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
             });
 
             DateTime bundleStartDate = null;
-            for (EntitlementSubscriptionMigration curSub : sortedSubscriptions) {
+            for (final EntitlementSubscriptionMigration curSub : sortedSubscriptions) {
                 SubscriptionMigrationData data = null;
                 if (bundleStartDate == null) {
                     data = createInitialSubscription(bundleData.getId(), curSub.getCategory(), curSub.getSubscriptionCases(), now, curSub.getChargedThroughDate(), context);
                     bundleStartDate = data.getInitialEvents().get(0).getEffectiveDate();
                 } else {
                     data = createSubscriptionMigrationDataWithBundleDate(bundleData.getId(), curSub.getCategory(), curSub.getSubscriptionCases(), now,
-                    		bundleStartDate, curSub.getChargedThroughDate(), context);
+                                                                         bundleStartDate, curSub.getChargedThroughDate(), context);
                 }
                 if (data != null) {
                     bundleSubscriptionData.add(data);
                 }
             }
-            BundleMigrationData bundleMigrationData = new BundleMigrationData(bundleData, bundleSubscriptionData);
+            final BundleMigrationData bundleMigrationData = new BundleMigrationData(bundleData, bundleSubscriptionData);
             accountBundleData.add(bundleMigrationData);
         }
-        AccountMigrationData accountMigrationData = new AccountMigrationData(accountBundleData);
+        final AccountMigrationData accountMigrationData = new AccountMigrationData(accountBundleData);
         return accountMigrationData;
     }
 
-    private SubscriptionMigrationData createInitialSubscription(UUID bundleId, ProductCategory productCategory,
-            EntitlementSubscriptionMigrationCase [] input, DateTime now, DateTime ctd, CallContext context)
-        throws EntitlementMigrationApiException {
-
-        TimedMigration [] events = migrationAligner.getEventsMigration(input, now);
-        DateTime migrationStartDate= events[0].getEventTime();
-        List<EntitlementEvent> emptyEvents =  Collections.emptyList();
-        SubscriptionData subscriptionData = factory.createSubscription(new SubscriptionBuilder()
-            .setId(UUID.randomUUID())
-            .setBundleId(bundleId)
-            .setCategory(productCategory)
-            .setBundleStartDate(migrationStartDate)
-            .setStartDate(migrationStartDate),
-            emptyEvents);
+    private SubscriptionMigrationData createInitialSubscription(final UUID bundleId, final ProductCategory productCategory,
+                                                                final EntitlementSubscriptionMigrationCase[] input, final DateTime now, final DateTime ctd, final CallContext context)
+            throws EntitlementMigrationApiException {
+
+        final TimedMigration[] events = migrationAligner.getEventsMigration(input, now);
+        final DateTime migrationStartDate = events[0].getEventTime();
+        final List<EntitlementEvent> emptyEvents = Collections.emptyList();
+        final SubscriptionData subscriptionData = factory.createSubscription(new SubscriptionBuilder()
+                                                                               .setId(UUID.randomUUID())
+                                                                               .setBundleId(bundleId)
+                                                                               .setCategory(productCategory)
+                                                                               .setBundleStartDate(migrationStartDate)
+                                                                               .setStartDate(migrationStartDate),
+                                                                       emptyEvents);
         return new SubscriptionMigrationData(subscriptionData, toEvents(subscriptionData, now, ctd, events, context));
     }
 
-    private SubscriptionMigrationData createSubscriptionMigrationDataWithBundleDate(UUID bundleId, ProductCategory productCategory,
-            EntitlementSubscriptionMigrationCase [] input, DateTime now, DateTime bundleStartDate, DateTime ctd, CallContext context)
-    throws EntitlementMigrationApiException {
-        TimedMigration [] events = migrationAligner.getEventsMigration(input, now);
-        DateTime migrationStartDate= events[0].getEventTime();
-        List<EntitlementEvent> emptyEvents =  Collections.emptyList();
-        SubscriptionData subscriptionData = factory.createSubscription(new SubscriptionBuilder()
-            .setId(UUID.randomUUID())
-            .setBundleId(bundleId)
-            .setCategory(productCategory)
-            .setBundleStartDate(bundleStartDate)
-            .setStartDate(migrationStartDate),
-            emptyEvents);
+    private SubscriptionMigrationData createSubscriptionMigrationDataWithBundleDate(final UUID bundleId, final ProductCategory productCategory,
+                                                                                    final EntitlementSubscriptionMigrationCase[] input, final DateTime now, final DateTime bundleStartDate, final DateTime ctd, final CallContext context)
+            throws EntitlementMigrationApiException {
+        final TimedMigration[] events = migrationAligner.getEventsMigration(input, now);
+        final DateTime migrationStartDate = events[0].getEventTime();
+        final List<EntitlementEvent> emptyEvents = Collections.emptyList();
+        final SubscriptionData subscriptionData = factory.createSubscription(new SubscriptionBuilder()
+                                                                               .setId(UUID.randomUUID())
+                                                                               .setBundleId(bundleId)
+                                                                               .setCategory(productCategory)
+                                                                               .setBundleStartDate(bundleStartDate)
+                                                                               .setStartDate(migrationStartDate),
+                                                                       emptyEvents);
         return new SubscriptionMigrationData(subscriptionData, toEvents(subscriptionData, now, ctd, events, context));
     }
 
-    private List<EntitlementEvent> toEvents(SubscriptionData subscriptionData, DateTime now, DateTime ctd, TimedMigration [] migrationEvents, CallContext context) {
+    private List<EntitlementEvent> toEvents(final SubscriptionData subscriptionData, final DateTime now, final DateTime ctd, final TimedMigration[] migrationEvents, final CallContext context) {
 
 
         ApiEventMigrateEntitlement creationEvent = null;
-        List<EntitlementEvent> events = new ArrayList<EntitlementEvent>(migrationEvents.length);
-        for (TimedMigration cur : migrationEvents) {
+        final List<EntitlementEvent> events = new ArrayList<EntitlementEvent>(migrationEvents.length);
+        for (final TimedMigration cur : migrationEvents) {
 
             if (cur.getEventType() == EventType.PHASE) {
-                PhaseEvent nextPhaseEvent = PhaseEventData.createNextPhaseEvent(cur.getPhase().getName(), subscriptionData, now, cur.getEventTime());
+                final PhaseEvent nextPhaseEvent = PhaseEventData.createNextPhaseEvent(cur.getPhase().getName(), subscriptionData, now, cur.getEventTime());
                 events.add(nextPhaseEvent);
 
             } else if (cur.getEventType() == EventType.API_USER) {
 
-                ApiEventBuilder builder = new ApiEventBuilder()
-                .setSubscriptionId(subscriptionData.getId())
-                .setEventPlan((cur.getPlan() != null) ? cur.getPlan().getName() : null)
-                .setEventPlanPhase((cur.getPhase() != null) ? cur.getPhase().getName() : null)
-                .setEventPriceList(cur.getPriceList())
-                .setActiveVersion(subscriptionData.getActiveVersion())
-                .setEffectiveDate(cur.getEventTime())
-                .setProcessedDate(now)
-                .setRequestedDate(now)
-                .setUserToken(context.getUserToken())
-                .setFromDisk(true);
-
-                switch(cur.getApiEventType()) {
-                case MIGRATE_ENTITLEMENT:
-                    creationEvent = new ApiEventMigrateEntitlement(builder);
-                    events.add(creationEvent);
-                    break;
-
-                case CHANGE:
-                    events.add(new ApiEventChange(builder));
-                    break;
-                case CANCEL:
-                    events.add(new ApiEventCancel(builder));
-                    break;
-                default:
-                    throw new EntitlementError(String.format("Unexpected type of api migration event %s", cur.getApiEventType()));
+                final ApiEventBuilder builder = new ApiEventBuilder()
+                        .setSubscriptionId(subscriptionData.getId())
+                        .setEventPlan((cur.getPlan() != null) ? cur.getPlan().getName() : null)
+                        .setEventPlanPhase((cur.getPhase() != null) ? cur.getPhase().getName() : null)
+                        .setEventPriceList(cur.getPriceList())
+                        .setActiveVersion(subscriptionData.getActiveVersion())
+                        .setEffectiveDate(cur.getEventTime())
+                        .setProcessedDate(now)
+                        .setRequestedDate(now)
+                        .setUserToken(context.getUserToken())
+                        .setFromDisk(true);
+
+                switch (cur.getApiEventType()) {
+                    case MIGRATE_ENTITLEMENT:
+                        creationEvent = new ApiEventMigrateEntitlement(builder);
+                        events.add(creationEvent);
+                        break;
+
+                    case CHANGE:
+                        events.add(new ApiEventChange(builder));
+                        break;
+                    case CANCEL:
+                        events.add(new ApiEventCancel(builder));
+                        break;
+                    default:
+                        throw new EntitlementError(String.format("Unexpected type of api migration event %s", cur.getApiEventType()));
                 }
             } else {
                 throw new EntitlementError(String.format("Unexpected type of migration event %s", cur.getEventType()));
@@ -218,7 +214,7 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
         events.add(new ApiEventMigrateBilling(creationEvent, ctd));
         Collections.sort(events, new Comparator<EntitlementEvent>() {
 
-            int compForApiType(EntitlementEvent o1, EntitlementEvent o2, ApiEventType type) {
+            int compForApiType(final EntitlementEvent o1, final EntitlementEvent o2, final ApiEventType type) {
 
                 ApiEventType apiO1 = null;
                 if (o1.getType() == EventType.API_USER) {
@@ -238,7 +234,7 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
             }
 
             @Override
-            public int compare(EntitlementEvent o1, EntitlementEvent o2) {
+            public int compare(final EntitlementEvent o1, final EntitlementEvent o2) {
 
                 int comp = o1.getEffectiveDate().compareTo(o2.getEffectiveDate());
                 if (comp == 0) {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/SubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/SubscriptionApiService.java
index b5a3a1e..8d216a2 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/SubscriptionApiService.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/SubscriptionApiService.java
@@ -15,37 +15,34 @@
  */
 package com.ning.billing.entitlement.api;
 
-import java.util.List;
-
 import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.SubscriptionStatusDryRun;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.util.callcontext.CallContext;
 
 public interface SubscriptionApiService {
 
     public SubscriptionData createPlan(SubscriptionBuilder builder, Plan plan, PhaseType initialPhase,
-            String realPriceList, DateTime requestedDate, DateTime effectiveDate, DateTime processedDate,
-            CallContext context)
-        throws EntitlementUserApiException;
+                                       String realPriceList, DateTime requestedDate, DateTime effectiveDate, DateTime processedDate,
+                                       CallContext context)
+            throws EntitlementUserApiException;
 
     public boolean recreatePlan(SubscriptionData subscription, PlanPhaseSpecifier spec, DateTime requestedDate, CallContext context)
-        throws EntitlementUserApiException;
+            throws EntitlementUserApiException;
 
     public boolean cancel(SubscriptionData subscription, DateTime requestedDate, boolean eot, CallContext context)
-        throws EntitlementUserApiException;
+            throws EntitlementUserApiException;
 
     public boolean uncancel(SubscriptionData subscription, CallContext context)
-        throws EntitlementUserApiException;
+            throws EntitlementUserApiException;
 
     public boolean changePlan(SubscriptionData subscription, String productName, BillingPeriod term,
-            String priceList, DateTime requestedDate, CallContext context)
-        throws EntitlementUserApiException;
+                              String priceList, DateTime requestedDate, CallContext context)
+            throws EntitlementUserApiException;
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/SubscriptionFactory.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/SubscriptionFactory.java
index 2b12487..c0ccc17 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/SubscriptionFactory.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/SubscriptionFactory.java
@@ -17,11 +17,11 @@ package com.ning.billing.entitlement.api;
 
 import java.util.List;
 
-import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
+import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 
 public interface SubscriptionFactory {
-    
+
     public SubscriptionData createSubscription(SubscriptionBuilder builder, List<EntitlementEvent> events);
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultDeletedEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultDeletedEvent.java
index 14b1e9e..fcfc82d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultDeletedEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultDeletedEvent.java
@@ -25,17 +25,17 @@ public class DefaultDeletedEvent implements DeletedEvent {
 
     private final UUID id;
     private final DateTime effectiveDate;
-    
-    public DefaultDeletedEvent(UUID id, DateTime effectiveDate) {
+
+    public DefaultDeletedEvent(final UUID id, final DateTime effectiveDate) {
         this.id = id;
         this.effectiveDate = effectiveDate;
     }
-    
+
     @Override
     public UUID getEventId() {
         return id;
     }
-    
+
     public DateTime getEffectiveDate() {
         return effectiveDate;
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
index 9f73725..3162a75 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
@@ -36,11 +36,11 @@ import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.SubscriptionFactory;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.NewEvent;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.events.EntitlementEvent;
@@ -55,7 +55,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     private final CatalogService catalogService;
 
 
-    private enum RepairType  {
+    private enum RepairType {
         BASE_REPAIR,
         ADD_ON_REPAIR,
         STANDALONE_REPAIR
@@ -64,7 +64,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
 
     @Inject
     public DefaultEntitlementTimelineApi(@Named(DefaultEntitlementModule.REPAIR_NAMED) final SubscriptionFactory factory, final CatalogService catalogService,
-            @Named(DefaultEntitlementModule.REPAIR_NAMED) final RepairEntitlementLifecycleDao repairDao, final EntitlementDao dao) {
+                                         @Named(DefaultEntitlementModule.REPAIR_NAMED) final RepairEntitlementLifecycleDao repairDao, final EntitlementDao dao) {
         this.catalogService = catalogService;
         this.dao = dao;
         this.repairDao = repairDao;
@@ -73,11 +73,11 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
 
 
     @Override
-    public BundleTimeline getBundleRepair(final UUID bundleId) 
-    throws EntitlementRepairException {
+    public BundleTimeline getBundleRepair(final UUID bundleId)
+            throws EntitlementRepairException {
 
         try {
-            SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(bundleId);
+            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(bundleId);
             if (bundle == null) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_BUNDLE, bundleId);
             }
@@ -86,7 +86,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NO_ACTIVE_SUBSCRIPTIONS, bundleId);
             }
             final String viewId = getViewId(((SubscriptionBundleData) bundle).getLastSysUpdateTime(), subscriptions);
-            final List<SubscriptionTimeline> repairs = createGetSubscriptionRepairList(subscriptions, Collections.<SubscriptionTimeline>emptyList()); 
+            final List<SubscriptionTimeline> repairs = createGetSubscriptionRepairList(subscriptions, Collections.<SubscriptionTimeline>emptyList());
             return createGetBundleRepair(bundleId, bundle.getKey(), viewId, repairs);
         } catch (CatalogApiException e) {
             throw new EntitlementRepairException(e);
@@ -94,18 +94,17 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     }
 
 
-
     @Override
     public BundleTimeline repairBundle(final BundleTimeline input, final boolean dryRun, final CallContext context)
-    throws EntitlementRepairException {
+            throws EntitlementRepairException {
 
         try {
 
-            SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(input.getBundleId());
+            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(input.getBundleId());
             if (bundle == null) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_BUNDLE, input.getBundleId());
             }
-            
+
 
             // Subscriptions are ordered with BASE subscription first-- if exists
             final List<Subscription> subscriptions = dao.getSubscriptions(factory, input.getBundleId());
@@ -115,7 +114,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
 
             final String viewId = getViewId(((SubscriptionBundleData) bundle).getLastSysUpdateTime(), subscriptions);
             if (!viewId.equals(input.getViewId())) {
-                throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_VIEW_CHANGED,input.getBundleId(), input.getViewId(), viewId);
+                throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_VIEW_CHANGED, input.getBundleId(), input.getViewId(), viewId);
             }
 
             DateTime firstDeletedBPEventTime = null;
@@ -125,19 +124,19 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             DateTime newBundleStartDate = null;
 
             SubscriptionDataRepair baseSubscriptionRepair = null;
-            List<SubscriptionDataRepair> addOnSubscriptionInRepair = new LinkedList<SubscriptionDataRepair>();
-            List<SubscriptionDataRepair> inRepair =  new LinkedList<SubscriptionDataRepair>();
-            for (Subscription cur : subscriptions) {
+            final List<SubscriptionDataRepair> addOnSubscriptionInRepair = new LinkedList<SubscriptionDataRepair>();
+            final List<SubscriptionDataRepair> inRepair = new LinkedList<SubscriptionDataRepair>();
+            for (final Subscription cur : subscriptions) {
 
                 //
-                SubscriptionTimeline curRepair = findAndCreateSubscriptionRepair(cur.getId(), input.getSubscriptions());
+                final SubscriptionTimeline curRepair = findAndCreateSubscriptionRepair(cur.getId(), input.getSubscriptions());
                 if (curRepair != null) {
-                    SubscriptionDataRepair curInputRepair = ((SubscriptionDataRepair) cur);
+                    final SubscriptionDataRepair curInputRepair = ((SubscriptionDataRepair) cur);
                     final List<EntitlementEvent> remaining = getRemainingEventsAndValidateDeletedEvents(curInputRepair, firstDeletedBPEventTime, curRepair.getDeletedEvents());
 
-                    final boolean isPlanRecreate = (curRepair.getNewEvents().size() > 0 
-                            && (curRepair.getNewEvents().get(0).getSubscriptionTransitionType() == SubscriptionTransitionType.CREATE 
-                                    || curRepair.getNewEvents().get(0).getSubscriptionTransitionType() == SubscriptionTransitionType.RE_CREATE));
+                    final boolean isPlanRecreate = (curRepair.getNewEvents().size() > 0
+                            && (curRepair.getNewEvents().get(0).getSubscriptionTransitionType() == SubscriptionTransitionType.CREATE
+                            || curRepair.getNewEvents().get(0).getSubscriptionTransitionType() == SubscriptionTransitionType.RE_CREATE));
 
                     final DateTime newSubscriptionStartDate = isPlanRecreate ? curRepair.getNewEvents().get(0).getRequestedDate() : null;
 
@@ -151,27 +150,27 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
 
                     if (cur.getCategory() == ProductCategory.BASE) {
 
-                        int bpTransitionSize =((SubscriptionData) cur).getAllTransitions().size();
+                        final int bpTransitionSize = ((SubscriptionData) cur).getAllTransitions().size();
                         lastRemainingBPEventTime = (remaining.size() > 0) ? curInputRepair.getAllTransitions().get(remaining.size() - 1).getEffectiveTransitionTime() : null;
-                        firstDeletedBPEventTime =  (remaining.size() < bpTransitionSize) ? curInputRepair.getAllTransitions().get(remaining.size()).getEffectiveTransitionTime() : null;
+                        firstDeletedBPEventTime = (remaining.size() < bpTransitionSize) ? curInputRepair.getAllTransitions().get(remaining.size()).getEffectiveTransitionTime() : null;
 
                         isBasePlanRecreate = isPlanRecreate;
                         newBundleStartDate = newSubscriptionStartDate;
                     }
 
                     if (curRepair.getNewEvents().size() > 0) {
-                        DateTime lastRemainingEventTime = (remaining.size() == 0) ? null : curInputRepair.getAllTransitions().get(remaining.size() - 1).getEffectiveTransitionTime();
+                        final DateTime lastRemainingEventTime = (remaining.size() == 0) ? null : curInputRepair.getAllTransitions().get(remaining.size() - 1).getEffectiveTransitionTime();
                         validateFirstNewEvent(curInputRepair, curRepair.getNewEvents().get(0), lastRemainingBPEventTime, lastRemainingEventTime);
                     }
 
 
-                    SubscriptionDataRepair curOutputRepair = createSubscriptionDataRepair(curInputRepair, newBundleStartDate, newSubscriptionStartDate, remaining);
+                    final SubscriptionDataRepair curOutputRepair = createSubscriptionDataRepair(curInputRepair, newBundleStartDate, newSubscriptionStartDate, remaining);
                     repairDao.initializeRepair(curInputRepair.getId(), remaining);
                     inRepair.add(curOutputRepair);
                     if (curOutputRepair.getCategory() == ProductCategory.ADD_ON) {
                         // Check if ADD_ON RE_CREATE is before BP start
                         if (isPlanRecreate && subscriptions.get(0).getStartDate().isAfter(curRepair.getNewEvents().get(0).getRequestedDate())) {
-                            throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_AO_CREATE_BEFORE_BP_START, cur.getId(), cur.getBundleId());                            
+                            throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_AO_CREATE_BEFORE_BP_START, cur.getId(), cur.getBundleId());
                         }
                         addOnSubscriptionInRepair.add(curOutputRepair);
                     } else if (curOutputRepair.getCategory() == ProductCategory.BASE) {
@@ -181,27 +180,27 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             }
 
             final RepairType repairType = getRepairType(subscriptions.get(0), (baseSubscriptionRepair != null));
-            switch(repairType) {
-            case BASE_REPAIR:
-                // We need to add any existing addon that are not in the input repair list
-                for (Subscription cur : subscriptions) {
-                    if (cur.getCategory() == ProductCategory.ADD_ON && !inRepair.contains(cur)) {
-                        SubscriptionDataRepair curOutputRepair = createSubscriptionDataRepair((SubscriptionDataRepair) cur, newBundleStartDate, null, ((SubscriptionDataRepair) cur).getEvents());
-                        repairDao.initializeRepair(curOutputRepair.getId(), ((SubscriptionDataRepair) cur).getEvents());
-                        inRepair.add(curOutputRepair);
-                        addOnSubscriptionInRepair.add(curOutputRepair);
+            switch (repairType) {
+                case BASE_REPAIR:
+                    // We need to add any existing addon that are not in the input repair list
+                    for (final Subscription cur : subscriptions) {
+                        if (cur.getCategory() == ProductCategory.ADD_ON && !inRepair.contains(cur)) {
+                            final SubscriptionDataRepair curOutputRepair = createSubscriptionDataRepair((SubscriptionDataRepair) cur, newBundleStartDate, null, ((SubscriptionDataRepair) cur).getEvents());
+                            repairDao.initializeRepair(curOutputRepair.getId(), ((SubscriptionDataRepair) cur).getEvents());
+                            inRepair.add(curOutputRepair);
+                            addOnSubscriptionInRepair.add(curOutputRepair);
+                        }
                     }
-                }
 
-                break;
-            case ADD_ON_REPAIR:
-                // We need to set the baseSubscription as it is useful to calculate addon validity
-                SubscriptionDataRepair baseSubscription =  (SubscriptionDataRepair) subscriptions.get(0);
-                baseSubscriptionRepair = createSubscriptionDataRepair(baseSubscription, baseSubscription.getBundleStartDate(), baseSubscription.getStartDate(), baseSubscription.getEvents());
-                break;
-            case STANDALONE_REPAIR:
-            default:
-                break;
+                    break;
+                case ADD_ON_REPAIR:
+                    // We need to set the baseSubscription as it is useful to calculate addon validity
+                    final SubscriptionDataRepair baseSubscription = (SubscriptionDataRepair) subscriptions.get(0);
+                    baseSubscriptionRepair = createSubscriptionDataRepair(baseSubscription, baseSubscription.getBundleStartDate(), baseSubscription.getStartDate(), baseSubscription.getEvents());
+                    break;
+                case STANDALONE_REPAIR:
+                default:
+                    break;
 
             }
 
@@ -209,22 +208,22 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             validateInputSubscriptionsKnown(subscriptions, input.getSubscriptions());
 
 
-            Collection<NewEvent> newEvents = createOrderedNewEventInput(input.getSubscriptions());
-            Iterator<NewEvent> it = newEvents.iterator();
+            final Collection<NewEvent> newEvents = createOrderedNewEventInput(input.getSubscriptions());
+            final Iterator<NewEvent> it = newEvents.iterator();
             while (it.hasNext()) {
-                DefaultNewEvent cur = (DefaultNewEvent) it.next();
-                SubscriptionDataRepair curDataRepair = findSubscriptionDataRepair(cur.getSubscriptionId(), inRepair);
+                final DefaultNewEvent cur = (DefaultNewEvent) it.next();
+                final SubscriptionDataRepair curDataRepair = findSubscriptionDataRepair(cur.getSubscriptionId(), inRepair);
                 if (curDataRepair == null) {
                     throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_SUBSCRIPTION, cur.getSubscriptionId());
                 }
                 curDataRepair.addNewRepairEvent(cur, baseSubscriptionRepair, addOnSubscriptionInRepair, context);
             }
-            
+
             if (dryRun) {
-                
+
                 baseSubscriptionRepair.addFutureAddonCancellation(addOnSubscriptionInRepair, context);
 
-                final List<SubscriptionTimeline> repairs = createGetSubscriptionRepairList(subscriptions, convertDataRepair(inRepair)); 
+                final List<SubscriptionTimeline> repairs = createGetSubscriptionRepairList(subscriptions, convertDataRepair(inRepair));
                 return createGetBundleRepair(input.getBundleId(), bundle.getKey(), input.getViewId(), repairs);
             } else {
                 dao.repair(bundle.getAccountId(), input.getBundleId(), inRepair, context);
@@ -237,9 +236,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         }
     }
 
- 
-    
-    
+
     private RepairType getRepairType(final Subscription firstSubscription, final boolean gotBaseSubscription) {
         if (firstSubscription.getCategory() == ProductCategory.BASE) {
             return gotBaseSubscription ? RepairType.BASE_REPAIR : RepairType.ADD_ON_REPAIR;
@@ -248,8 +245,8 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         }
     }
 
-    private void validateBasePlanRecreate(boolean isBasePlanRecreate, List<Subscription> subscriptions, List<SubscriptionTimeline> input) 
-    throws EntitlementRepairException  {
+    private void validateBasePlanRecreate(final boolean isBasePlanRecreate, final List<Subscription> subscriptions, final List<SubscriptionTimeline> input)
+            throws EntitlementRepairException {
 
         if (!isBasePlanRecreate) {
             return;
@@ -257,22 +254,22 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         if (subscriptions.size() != input.size()) {
             throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO, subscriptions.get(0).getBundleId());
         }
-        for (SubscriptionTimeline cur : input) {
-            if (cur.getNewEvents().size() != 0 
+        for (final SubscriptionTimeline cur : input) {
+            if (cur.getNewEvents().size() != 0
                     && (cur.getNewEvents().get(0).getSubscriptionTransitionType() != SubscriptionTransitionType.CREATE
-                            && cur.getNewEvents().get(0).getSubscriptionTransitionType() != SubscriptionTransitionType.RE_CREATE)) {
+                    && cur.getNewEvents().get(0).getSubscriptionTransitionType() != SubscriptionTransitionType.RE_CREATE)) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE, subscriptions.get(0).getBundleId());
             }
         }
     }
 
 
-    private void validateInputSubscriptionsKnown(List<Subscription> subscriptions, List<SubscriptionTimeline> input)
-    throws EntitlementRepairException {
+    private void validateInputSubscriptionsKnown(final List<Subscription> subscriptions, final List<SubscriptionTimeline> input)
+            throws EntitlementRepairException {
 
-        for (SubscriptionTimeline cur : input) {
+        for (final SubscriptionTimeline cur : input) {
             boolean found = false;
-            for (Subscription s : subscriptions) {
+            for (final Subscription s : subscriptions) {
                 if (s.getId().equals(cur.getId())) {
                     found = true;
                     break;
@@ -284,8 +281,8 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         }
     }
 
-    private void validateFirstNewEvent(final SubscriptionData data, final NewEvent firstNewEvent, final DateTime lastBPRemainingTime, final DateTime lastRemainingTime) 
-    throws EntitlementRepairException {
+    private void validateFirstNewEvent(final SubscriptionData data, final NewEvent firstNewEvent, final DateTime lastBPRemainingTime, final DateTime lastRemainingTime)
+            throws EntitlementRepairException {
         if (lastBPRemainingTime != null &&
                 firstNewEvent.getRequestedDate().isBefore(lastBPRemainingTime)) {
             throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING, firstNewEvent.getSubscriptionTransitionType(), data.getId());
@@ -297,16 +294,16 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
 
     }
 
-    private Collection<NewEvent> createOrderedNewEventInput(List<SubscriptionTimeline> subscriptionsReapir) {
-        TreeSet<NewEvent> newEventSet = new TreeSet<SubscriptionTimeline.NewEvent>(new Comparator<NewEvent>() {
+    private Collection<NewEvent> createOrderedNewEventInput(final List<SubscriptionTimeline> subscriptionsReapir) {
+        final TreeSet<NewEvent> newEventSet = new TreeSet<SubscriptionTimeline.NewEvent>(new Comparator<NewEvent>() {
             @Override
-            public int compare(NewEvent o1, NewEvent o2) {
+            public int compare(final NewEvent o1, final NewEvent o2) {
                 return o1.getRequestedDate().compareTo(o2.getRequestedDate());
             }
         });
-        for (SubscriptionTimeline cur : subscriptionsReapir) {
-            for (NewEvent e : cur.getNewEvents()) {
-                newEventSet.add(new DefaultNewEvent(cur.getId(), e.getPlanPhaseSpecifier(), e.getRequestedDate(), e.getSubscriptionTransitionType()));    
+        for (final SubscriptionTimeline cur : subscriptionsReapir) {
+            for (final NewEvent e : cur.getNewEvents()) {
+                newEventSet.add(new DefaultNewEvent(cur.getId(), e.getPlanPhaseSpecifier(), e.getRequestedDate(), e.getSubscriptionTransitionType()));
             }
         }
         return newEventSet;
@@ -314,19 +311,19 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
 
 
     private List<EntitlementEvent> getRemainingEventsAndValidateDeletedEvents(final SubscriptionDataRepair data, final DateTime firstBPDeletedTime,
-            final List<SubscriptionTimeline.DeletedEvent> deletedEvents) 
-            throws EntitlementRepairException  {
+                                                                              final List<SubscriptionTimeline.DeletedEvent> deletedEvents)
+            throws EntitlementRepairException {
 
         if (deletedEvents == null || deletedEvents.size() == 0) {
             return data.getEvents();
         }
 
         int nbDeleted = 0;
-        LinkedList<EntitlementEvent> result = new LinkedList<EntitlementEvent>();
-        for (EntitlementEvent cur : data.getEvents()) {
+        final LinkedList<EntitlementEvent> result = new LinkedList<EntitlementEvent>();
+        for (final EntitlementEvent cur : data.getEvents()) {
 
             boolean foundDeletedEvent = false;
-            for (SubscriptionTimeline.DeletedEvent d : deletedEvents) {
+            for (final SubscriptionTimeline.DeletedEvent d : deletedEvents) {
                 if (cur.getId().equals(d.getEventId())) {
                     foundDeletedEvent = true;
                     nbDeleted++;
@@ -336,9 +333,9 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             if (!foundDeletedEvent && nbDeleted > 0) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_INVALID_DELETE_SET, cur.getId(), data.getId());
             }
-            if (firstBPDeletedTime != null && 
-                    ! cur.getEffectiveDate().isBefore(firstBPDeletedTime) &&
-                    ! foundDeletedEvent) {
+            if (firstBPDeletedTime != null &&
+                    !cur.getEffectiveDate().isBefore(firstBPDeletedTime) &&
+                    !foundDeletedEvent) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_MISSING_AO_DELETE_EVENT, cur.getId(), data.getId());
             }
 
@@ -347,9 +344,9 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             }
         }
         if (nbDeleted != deletedEvents.size()) {
-            for (SubscriptionTimeline.DeletedEvent d : deletedEvents) {
+            for (final SubscriptionTimeline.DeletedEvent d : deletedEvents) {
                 boolean found = false;
-                for (SubscriptionTransitionData cur : data.getAllTransitions()) {
+                for (final SubscriptionTransitionData cur : data.getAllTransitions()) {
                     if (cur.getId().equals(d.getEventId())) {
                         found = true;
                         continue;
@@ -365,10 +362,10 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     }
 
 
-    private String getViewId(DateTime lastUpdateBundleDate, List<Subscription> subscriptions) {
-        StringBuilder tmp = new StringBuilder();
+    private String getViewId(final DateTime lastUpdateBundleDate, final List<Subscription> subscriptions) {
+        final StringBuilder tmp = new StringBuilder();
         long lastOrderedId = -1;
-        for (Subscription cur : subscriptions) {
+        for (final Subscription cur : subscriptions) {
             lastOrderedId = lastOrderedId < ((SubscriptionData) cur).getLastEventOrderedId() ? ((SubscriptionData) cur).getLastEventOrderedId() : lastOrderedId;
         }
         tmp.append(lastOrderedId);
@@ -383,14 +380,17 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             public String getViewId() {
                 return viewId;
             }
+
             @Override
             public List<SubscriptionTimeline> getSubscriptions() {
                 return repairList;
             }
+
             @Override
             public UUID getBundleId() {
                 return bundleId;
             }
+
             @Override
             public String getExternalKey() {
                 return externalKey;
@@ -402,13 +402,13 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     private List<SubscriptionTimeline> createGetSubscriptionRepairList(final List<Subscription> subscriptions, final List<SubscriptionTimeline> inRepair) throws CatalogApiException {
 
         final List<SubscriptionTimeline> result = new LinkedList<SubscriptionTimeline>();
-        Set<UUID> repairIds = new TreeSet<UUID>();
+        final Set<UUID> repairIds = new TreeSet<UUID>();
         for (final SubscriptionTimeline cur : inRepair) {
             repairIds.add(cur.getId());
             result.add(cur);
         }
         for (final Subscription cur : subscriptions) {
-            if ( !repairIds.contains(cur.getId())) { 
+            if (!repairIds.contains(cur.getId())) {
                 result.add(new DefaultSubscriptionTimeline((SubscriptionDataRepair) cur, catalogService.getFullCatalog()));
             }
         }
@@ -416,16 +416,16 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     }
 
 
-    private List<SubscriptionTimeline> convertDataRepair(List<SubscriptionDataRepair> input) throws CatalogApiException  {
-        List<SubscriptionTimeline> result = new LinkedList<SubscriptionTimeline>();
-        for (SubscriptionDataRepair cur : input) {
+    private List<SubscriptionTimeline> convertDataRepair(final List<SubscriptionDataRepair> input) throws CatalogApiException {
+        final List<SubscriptionTimeline> result = new LinkedList<SubscriptionTimeline>();
+        for (final SubscriptionDataRepair cur : input) {
             result.add(new DefaultSubscriptionTimeline(cur, catalogService.getFullCatalog()));
         }
         return result;
     }
 
     private SubscriptionDataRepair findSubscriptionDataRepair(final UUID targetId, final List<SubscriptionDataRepair> input) {
-        for (SubscriptionDataRepair cur : input) {
+        for (final SubscriptionDataRepair cur : input) {
             if (cur.getId().equals(targetId)) {
                 return cur;
             }
@@ -435,7 +435,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
 
 
     private SubscriptionDataRepair createSubscriptionDataRepair(final SubscriptionData curData, final DateTime newBundleStartDate, final DateTime newSubscriptionStartDate, final List<EntitlementEvent> initialEvents) {
-        SubscriptionBuilder builder = new SubscriptionBuilder(curData);
+        final SubscriptionBuilder builder = new SubscriptionBuilder(curData);
         builder.setActiveVersion(curData.getActiveVersion() + 1);
         if (newBundleStartDate != null) {
             builder.setBundleStartDate(newBundleStartDate);
@@ -444,17 +444,17 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             builder.setStartDate(newSubscriptionStartDate);
         }
         if (initialEvents.size() > 0) {
-            for (EntitlementEvent cur : initialEvents) {
+            for (final EntitlementEvent cur : initialEvents) {
                 cur.setActiveVersion(builder.getActiveVersion());
             }
         }
-        SubscriptionDataRepair result = (SubscriptionDataRepair) factory.createSubscription(builder, initialEvents);
+        final SubscriptionDataRepair result = (SubscriptionDataRepair) factory.createSubscription(builder, initialEvents);
         return result;
     }
 
 
     private SubscriptionTimeline findAndCreateSubscriptionRepair(final UUID target, final List<SubscriptionTimeline> input) {
-        for (SubscriptionTimeline cur : input) {
+        for (final SubscriptionTimeline cur : input) {
             if (target.equals(cur.getId())) {
                 return new DefaultSubscriptionTimeline(cur);
             }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultNewEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultNewEvent.java
index 87ece9f..db374d8 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultNewEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultNewEvent.java
@@ -29,14 +29,14 @@ public class DefaultNewEvent implements NewEvent {
     private final PlanPhaseSpecifier spec;
     private final DateTime requestedDate;
     private final SubscriptionTransitionType transitionType;
-    
+
     public DefaultNewEvent(final UUID subscriptionId, final PlanPhaseSpecifier spec, final DateTime requestedDate, final SubscriptionTransitionType transitionType) {
         this.subscriptionId = subscriptionId;
         this.spec = spec;
         this.requestedDate = requestedDate;
         this.transitionType = transitionType;
     }
-    
+
     @Override
     public PlanPhaseSpecifier getPlanPhaseSpecifier() {
         return spec;
@@ -51,7 +51,7 @@ public class DefaultNewEvent implements NewEvent {
     public SubscriptionTransitionType getSubscriptionTransitionType() {
         return transitionType;
     }
-    
+
     public UUID getSubscriptionId() {
         return subscriptionId;
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultRepairEntitlementEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultRepairEntitlementEvent.java
index b1cc31c..6496488 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultRepairEntitlementEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultRepairEntitlementEvent.java
@@ -17,10 +17,11 @@ package com.ning.billing.entitlement.api.timeline;
 
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import org.joda.time.DateTime;
 
 public class DefaultRepairEntitlementEvent implements RepairEntitlementEvent {
 
@@ -28,19 +29,19 @@ public class DefaultRepairEntitlementEvent implements RepairEntitlementEvent {
     private final UUID bundleId;
     private final UUID accountId;
     private final DateTime effectiveDate;
-    
-    
+
+
     @JsonCreator
     public DefaultRepairEntitlementEvent(@JsonProperty("userToken") final UUID userToken,
-            @JsonProperty("accountId") final UUID accountId,
-            @JsonProperty("bundleId") final UUID bundleId,
-            @JsonProperty("effectiveDate") final DateTime effectiveDate) {
+                                         @JsonProperty("accountId") final UUID accountId,
+                                         @JsonProperty("bundleId") final UUID bundleId,
+                                         @JsonProperty("effectiveDate") final DateTime effectiveDate) {
         this.userToken = userToken;
         this.bundleId = bundleId;
         this.accountId = accountId;
         this.effectiveDate = effectiveDate;
     }
-    
+
     @JsonIgnore
     @Override
     public BusEventType getBusEventType() {
@@ -83,34 +84,45 @@ public class DefaultRepairEntitlementEvent implements RepairEntitlementEvent {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        DefaultRepairEntitlementEvent other = (DefaultRepairEntitlementEvent) obj;
+        }
+        final DefaultRepairEntitlementEvent other = (DefaultRepairEntitlementEvent) obj;
         if (accountId == null) {
-            if (other.accountId != null)
+            if (other.accountId != null) {
                 return false;
-        } else if (!accountId.equals(other.accountId))
+            }
+        } else if (!accountId.equals(other.accountId)) {
             return false;
+        }
         if (bundleId == null) {
-            if (other.bundleId != null)
+            if (other.bundleId != null) {
                 return false;
-        } else if (!bundleId.equals(other.bundleId))
+            }
+        } else if (!bundleId.equals(other.bundleId)) {
             return false;
+        }
         if (effectiveDate == null) {
-            if (other.effectiveDate != null)
+            if (other.effectiveDate != null) {
                 return false;
-        } else if (effectiveDate.compareTo(other.effectiveDate) != 0)
+            }
+        } else if (effectiveDate.compareTo(other.effectiveDate) != 0) {
             return false;
+        }
         if (userToken == null) {
-            if (other.userToken != null)
+            if (other.userToken != null) {
                 return false;
-        } else if (!userToken.equals(other.userToken))
+            }
+        } else if (!userToken.equals(other.userToken)) {
             return false;
+        }
         return true;
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultSubscriptionTimeline.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultSubscriptionTimeline.java
index 4080326..f9a17f3 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultSubscriptionTimeline.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultSubscriptionTimeline.java
@@ -38,65 +38,154 @@ import com.ning.billing.entitlement.events.phase.PhaseEvent;
 import com.ning.billing.entitlement.events.user.ApiEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 
-public class DefaultSubscriptionTimeline implements SubscriptionTimeline  {
+public class DefaultSubscriptionTimeline implements SubscriptionTimeline {
 
     private final UUID id;
     private final List<ExistingEvent> existingEvents;
     private final List<NewEvent> newEvents;
-    private final List<DeletedEvent> deletedEvents;    
-    
+    private final List<DeletedEvent> deletedEvents;
+
     public DefaultSubscriptionTimeline(final UUID id) {
         this.id = id;
         this.existingEvents = Collections.<SubscriptionTimeline.ExistingEvent>emptyList();
-        this.deletedEvents =  Collections.<SubscriptionTimeline.DeletedEvent>emptyList();
+        this.deletedEvents = Collections.<SubscriptionTimeline.DeletedEvent>emptyList();
         this.newEvents = Collections.<SubscriptionTimeline.NewEvent>emptyList();
     }
-    
-    public DefaultSubscriptionTimeline(SubscriptionTimeline input) {
+
+    public DefaultSubscriptionTimeline(final SubscriptionTimeline input) {
         this.id = input.getId();
-        this.existingEvents = (input.getExistingEvents() != null) ? new ArrayList<SubscriptionTimeline.ExistingEvent>(input.getExistingEvents()) : 
-            Collections.<SubscriptionTimeline.ExistingEvent>emptyList();
+        this.existingEvents = (input.getExistingEvents() != null) ? new ArrayList<SubscriptionTimeline.ExistingEvent>(input.getExistingEvents()) :
+                Collections.<SubscriptionTimeline.ExistingEvent>emptyList();
         sortExistingEvent(this.existingEvents);
-        this.deletedEvents = (input.getDeletedEvents() != null) ? new ArrayList<SubscriptionTimeline.DeletedEvent>(input.getDeletedEvents()) : 
-            Collections.<SubscriptionTimeline.DeletedEvent>emptyList();
-        this.newEvents = (input.getNewEvents() != null) ? new ArrayList<SubscriptionTimeline.NewEvent>(input.getNewEvents()) : 
-            Collections.<SubscriptionTimeline.NewEvent>emptyList();
+        this.deletedEvents = (input.getDeletedEvents() != null) ? new ArrayList<SubscriptionTimeline.DeletedEvent>(input.getDeletedEvents()) :
+                Collections.<SubscriptionTimeline.DeletedEvent>emptyList();
+        this.newEvents = (input.getNewEvents() != null) ? new ArrayList<SubscriptionTimeline.NewEvent>(input.getNewEvents()) :
+                Collections.<SubscriptionTimeline.NewEvent>emptyList();
         sortNewEvent(this.newEvents);
     }
-    
-     // CTOR for returning events only
-    public DefaultSubscriptionTimeline(SubscriptionDataRepair input, Catalog catalog) throws CatalogApiException {
+
+    // CTOR for returning events only
+    public DefaultSubscriptionTimeline(final SubscriptionDataRepair input, final Catalog catalog) throws CatalogApiException {
         this.id = input.getId();
         this.existingEvents = toExistingEvents(catalog, input.getActiveVersion(), input.getCategory(), input.getEvents());
         this.deletedEvents = null;
         this.newEvents = null;
     }
-    
-   private List<ExistingEvent> toExistingEvents(final Catalog catalog, final long activeVersion, final ProductCategory category, final List<EntitlementEvent> events) 
-       throws CatalogApiException {
-        
-        List<ExistingEvent> result = new LinkedList<SubscriptionTimeline.ExistingEvent>();
-        
-        String prevProductName = null; 
+
+    private List<ExistingEvent> toExistingEvents(final Catalog catalog, final long activeVersion, final ProductCategory category, final List<EntitlementEvent> events)
+            throws CatalogApiException {
+
+        final List<ExistingEvent> result = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+
+        String prevProductName = null;
         BillingPeriod prevBillingPeriod = null;
         String prevPriceListName = null;
         PhaseType prevPhaseType = null;
-        
+
         DateTime startDate = null;
-        
+
         for (final EntitlementEvent cur : events) {
-            
+
             // First active event is used to figure out which catalog version to use.
             //startDate = (startDate == null && cur.getActiveVersion() == activeVersion) ?  cur.getEffectiveDate() : startDate;
-            
+
             // STEPH that needs tp be reviewed if we support mutli version events
             if (cur.getActiveVersion() != activeVersion) {
                 continue;
             }
-            startDate = (startDate == null) ?  cur.getEffectiveDate() : startDate;
-            
-            
-            String productName = null; 
+            startDate = (startDate == null) ? cur.getEffectiveDate() : startDate;
+
+
+            String productName = null;
+            BillingPeriod billingPeriod = null;
+            String priceListName = null;
+            PhaseType phaseType = null;
+
+            ApiEventType apiType = null;
+            switch (cur.getType()) {
+                case PHASE:
+                    final PhaseEvent phaseEV = (PhaseEvent) cur;
+                    phaseType = catalog.findPhase(phaseEV.getPhase(), cur.getEffectiveDate(), startDate).getPhaseType();
+                    productName = prevProductName;
+                    billingPeriod = catalog.findPhase(phaseEV.getPhase(), cur.getEffectiveDate(), startDate).getBillingPeriod();
+                    priceListName = prevPriceListName;
+                    break;
+
+                case API_USER:
+                    final ApiEvent userEV = (ApiEvent) cur;
+                    apiType = userEV.getEventType();
+                    final Plan plan = (userEV.getEventPlan() != null) ? catalog.findPlan(userEV.getEventPlan(), cur.getRequestedDate(), startDate) : null;
+                    phaseType = (userEV.getEventPlanPhase() != null) ? catalog.findPhase(userEV.getEventPlanPhase(), cur.getEffectiveDate(), startDate).getPhaseType() : prevPhaseType;
+                    productName = (plan != null) ? plan.getProduct().getName() : prevProductName;
+                    billingPeriod = (userEV.getEventPlanPhase() != null) ? catalog.findPhase(userEV.getEventPlanPhase(), cur.getEffectiveDate(), startDate).getBillingPeriod() : prevBillingPeriod;
+                    priceListName = (userEV.getPriceList() != null) ? userEV.getPriceList() : prevPriceListName;
+                    break;
+            }
+
+            final SubscriptionTransitionType transitionType = SubscriptionTransitionData.toSubscriptionTransitionType(cur.getType(), apiType);
+
+            final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, category, billingPeriod, priceListName, phaseType);
+            result.add(new ExistingEvent() {
+                @Override
+                public SubscriptionTransitionType getSubscriptionTransitionType() {
+                    return transitionType;
+                }
+
+                @Override
+                public DateTime getRequestedDate() {
+                    return cur.getRequestedDate();
+                }
+
+                @Override
+                public PlanPhaseSpecifier getPlanPhaseSpecifier() {
+                    return spec;
+                }
+
+                @Override
+                public UUID getEventId() {
+                    return cur.getId();
+                }
+
+                @Override
+                public DateTime getEffectiveDate() {
+                    return cur.getEffectiveDate();
+                }
+            });
+
+            prevProductName = productName;
+            prevBillingPeriod = billingPeriod;
+            prevPriceListName = priceListName;
+            prevPhaseType = phaseType;
+
+        }
+        sortExistingEvent(result);
+        return result;
+    }
+
+
+    /*
+
+    private List<ExistingEvent> toExistingEvents(final Catalog catalog, final long processingVersion, final ProductCategory category, final List<EntitlementEvent> events, List<ExistingEvent> result)
+        throws CatalogApiException {
+
+
+        String prevProductName = null;
+        BillingPeriod prevBillingPeriod = null;
+        String prevPriceListName = null;
+        PhaseType prevPhaseType = null;
+
+        DateTime startDate = null;
+
+        for (final EntitlementEvent cur : events) {
+
+            if (processingVersion != cur.getActiveVersion()) {
+                continue;
+            }
+
+            // First active event is used to figure out which catalog version to use.
+            startDate = (startDate == null && cur.getActiveVersion() == processingVersion) ?  cur.getEffectiveDate() : startDate;
+
+            String productName = null;
             BillingPeriod billingPeriod = null;
             String priceListName = null;
             PhaseType phaseType = null;
@@ -107,7 +196,7 @@ public class DefaultSubscriptionTimeline implements SubscriptionTimeline  {
                 PhaseEvent phaseEV = (PhaseEvent) cur;
                 phaseType = catalog.findPhase(phaseEV.getPhase(), cur.getEffectiveDate(), startDate).getPhaseType();
                 productName = prevProductName;
-                billingPeriod = catalog.findPhase(phaseEV.getPhase(), cur.getEffectiveDate(), startDate).getBillingPeriod();
+                billingPeriod = prevBillingPeriod;
                 priceListName = prevPriceListName;
                 break;
 
@@ -117,13 +206,13 @@ public class DefaultSubscriptionTimeline implements SubscriptionTimeline  {
                 Plan plan =  (userEV.getEventPlan() != null) ? catalog.findPlan(userEV.getEventPlan(), cur.getRequestedDate(), startDate) : null;
                 phaseType = (userEV.getEventPlanPhase() != null) ? catalog.findPhase(userEV.getEventPlanPhase(), cur.getEffectiveDate(), startDate).getPhaseType() : prevPhaseType;
                 productName = (plan != null) ? plan.getProduct().getName() : prevProductName;
-                billingPeriod = (userEV.getEventPlanPhase() != null) ? catalog.findPhase(userEV.getEventPlanPhase(), cur.getEffectiveDate(), startDate).getBillingPeriod() : prevBillingPeriod;
+                billingPeriod = (plan != null) ? plan.getBillingPeriod() : prevBillingPeriod;
                 priceListName = (userEV.getPriceList() != null) ? userEV.getPriceList() : prevPriceListName;
                 break;
             }
 
             final SubscriptionTransitionType transitionType = SubscriptionTransitionData.toSubscriptionTransitionType(cur.getType(), apiType);
-            
+
             final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, category, billingPeriod, priceListName, phaseType);
             result.add(new ExistingEvent() {
                 @Override
@@ -147,109 +236,20 @@ public class DefaultSubscriptionTimeline implements SubscriptionTimeline  {
                     return cur.getEffectiveDate();
                 }
             });
-            
-            prevProductName = productName; 
+            prevProductName = productName;
             prevBillingPeriod = billingPeriod;
             prevPriceListName = priceListName;
             prevPhaseType = phaseType;
-
         }
-        sortExistingEvent(result);
-        return result;
     }
-   
-   
-   /*
-   
-   private List<ExistingEvent> toExistingEvents(final Catalog catalog, final long processingVersion, final ProductCategory category, final List<EntitlementEvent> events, List<ExistingEvent> result)
-       throws CatalogApiException {
-       
-       
-       String prevProductName = null; 
-       BillingPeriod prevBillingPeriod = null;
-       String prevPriceListName = null;
-       PhaseType prevPhaseType = null;
-       
-       DateTime startDate = null;
-       
-       for (final EntitlementEvent cur : events) {
-           
-           if (processingVersion != cur.getActiveVersion()) {
-               continue;
-           }
-           
-           // First active event is used to figure out which catalog version to use.
-           startDate = (startDate == null && cur.getActiveVersion() == processingVersion) ?  cur.getEffectiveDate() : startDate;
-           
-           String productName = null; 
-           BillingPeriod billingPeriod = null;
-           String priceListName = null;
-           PhaseType phaseType = null;
-
-           ApiEventType apiType = null;
-           switch (cur.getType()) {
-           case PHASE:
-               PhaseEvent phaseEV = (PhaseEvent) cur;
-               phaseType = catalog.findPhase(phaseEV.getPhase(), cur.getEffectiveDate(), startDate).getPhaseType();
-               productName = prevProductName;
-               billingPeriod = prevBillingPeriod;
-               priceListName = prevPriceListName;
-               break;
-
-           case API_USER:
-               ApiEvent userEV = (ApiEvent) cur;
-               apiType = userEV.getEventType();
-               Plan plan =  (userEV.getEventPlan() != null) ? catalog.findPlan(userEV.getEventPlan(), cur.getRequestedDate(), startDate) : null;
-               phaseType = (userEV.getEventPlanPhase() != null) ? catalog.findPhase(userEV.getEventPlanPhase(), cur.getEffectiveDate(), startDate).getPhaseType() : prevPhaseType;
-               productName = (plan != null) ? plan.getProduct().getName() : prevProductName;
-               billingPeriod = (plan != null) ? plan.getBillingPeriod() : prevBillingPeriod;
-               priceListName = (userEV.getPriceList() != null) ? userEV.getPriceList() : prevPriceListName;
-               break;
-           }
-
-           final SubscriptionTransitionType transitionType = SubscriptionTransitionData.toSubscriptionTransitionType(cur.getType(), apiType);
-           
-           final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, category, billingPeriod, priceListName, phaseType);
-           result.add(new ExistingEvent() {
-               @Override
-               public SubscriptionTransitionType getSubscriptionTransitionType() {
-                   return transitionType;
-               }
-               @Override
-               public DateTime getRequestedDate() {
-                   return cur.getRequestedDate();
-               }
-               @Override
-               public PlanPhaseSpecifier getPlanPhaseSpecifier() {
-                   return spec;
-               }
-               @Override
-               public UUID getEventId() {
-                   return cur.getId();
-               }
-               @Override
-               public DateTime getEffectiveDate() {
-                   return cur.getEffectiveDate();
-               }
-           });
-           prevProductName = productName; 
-           prevBillingPeriod = billingPeriod;
-           prevPriceListName = priceListName;
-           prevPhaseType = phaseType;
-       }
-   }
-   */
-   
-   
-    
-    
-    
-    
+    */
+
+
     @Override
     public UUID getId() {
         return id;
     }
-    
+
     @Override
     public List<DeletedEvent> getDeletedEvents() {
         return deletedEvents;
@@ -259,27 +259,28 @@ public class DefaultSubscriptionTimeline implements SubscriptionTimeline  {
     public List<NewEvent> getNewEvents() {
         return newEvents;
     }
-    
+
     @Override
     public List<ExistingEvent> getExistingEvents() {
         return existingEvents;
     }
-    
+
     private void sortExistingEvent(final List<ExistingEvent> events) {
         if (events != null) {
             Collections.sort(events, new Comparator<ExistingEvent>() {
                 @Override
-                public int compare(ExistingEvent arg0, ExistingEvent arg1) {
+                public int compare(final ExistingEvent arg0, final ExistingEvent arg1) {
                     return arg0.getEffectiveDate().compareTo(arg1.getEffectiveDate());
                 }
             });
         }
     }
+
     private void sortNewEvent(final List<NewEvent> events) {
         if (events != null) {
             Collections.sort(events, new Comparator<NewEvent>() {
                 @Override
-                public int compare(NewEvent arg0, NewEvent arg1) {
+                public int compare(final NewEvent arg0, final NewEvent arg1) {
                     return arg0.getRequestedDate().compareTo(arg1.getRequestedDate());
                 }
             });
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementLifecycleDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementLifecycleDao.java
index dff77b3..0cc98bf 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementLifecycleDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairEntitlementLifecycleDao.java
@@ -23,6 +23,6 @@ import com.ning.billing.entitlement.events.EntitlementEvent;
 public interface RepairEntitlementLifecycleDao {
 
     public void initializeRepair(final UUID subscriptionId, final List<EntitlementEvent> initialEvents);
-    
+
     public void cleanup();
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionApiService.java
index dcc0c95..37078d5 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionApiService.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionApiService.java
@@ -29,8 +29,8 @@ import com.ning.billing.util.clock.Clock;
 public class RepairSubscriptionApiService extends DefaultSubscriptionApiService implements SubscriptionApiService {
 
     @Inject
-    public RepairSubscriptionApiService(Clock clock, @Named(DefaultEntitlementModule.REPAIR_NAMED) EntitlementDao dao,
-            CatalogService catalogService, PlanAligner planAligner) {
+    public RepairSubscriptionApiService(final Clock clock, @Named(DefaultEntitlementModule.REPAIR_NAMED) final EntitlementDao dao,
+                                        final CatalogService catalogService, final PlanAligner planAligner) {
         super(clock, dao, catalogService, planAligner);
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java
index 61933c3..e09989d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java
@@ -22,10 +22,8 @@ import com.google.inject.name.Named;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.entitlement.api.SubscriptionApiService;
 import com.ning.billing.entitlement.api.SubscriptionFactory;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionApiService;
 import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.engine.addon.AddonUtils;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.events.EntitlementEvent;
@@ -36,20 +34,20 @@ public class RepairSubscriptionFactory extends DefaultSubscriptionFactory implem
 
     private final AddonUtils addonUtils;
     private final EntitlementDao repairDao;
-    
+
     @Inject
-    public RepairSubscriptionFactory(@Named(DefaultEntitlementModule.REPAIR_NAMED) SubscriptionApiService apiService,
-            @Named(DefaultEntitlementModule.REPAIR_NAMED) EntitlementDao dao,
-            Clock clock, CatalogService catalogService, AddonUtils addonUtils) {
+    public RepairSubscriptionFactory(@Named(DefaultEntitlementModule.REPAIR_NAMED) final SubscriptionApiService apiService,
+                                     @Named(DefaultEntitlementModule.REPAIR_NAMED) final EntitlementDao dao,
+                                     final Clock clock, final CatalogService catalogService, final AddonUtils addonUtils) {
         super(apiService, clock, catalogService);
         this.addonUtils = addonUtils;
         this.repairDao = dao;
     }
-     
+
     @Override
-    public SubscriptionData createSubscription(SubscriptionBuilder builder,
-            List<EntitlementEvent> events) {
-        SubscriptionData subscription = new SubscriptionDataRepair(builder, events, apiService, repairDao, clock, addonUtils, catalogService);
+    public SubscriptionData createSubscription(final SubscriptionBuilder builder,
+                                               final List<EntitlementEvent> events) {
+        final SubscriptionData subscription = new SubscriptionDataRepair(builder, events, apiService, repairDao, clock, addonUtils, catalogService);
         subscription.rebuildTransitions(events, catalogService.getFullCatalog());
         return subscription;
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java
index 7f526d4..85c42a6 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java
@@ -33,9 +33,9 @@ import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.SubscriptionApiService;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
 import com.ning.billing.entitlement.engine.addon.AddonUtils;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
@@ -43,7 +43,6 @@ import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
 import com.ning.billing.entitlement.events.user.ApiEventBuilder;
 import com.ning.billing.entitlement.events.user.ApiEventCancel;
-
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.clock.Clock;
 
@@ -53,15 +52,15 @@ public class SubscriptionDataRepair extends SubscriptionData {
     private final Clock clock;
     private final EntitlementDao repairDao;
     private final CatalogService catalogService;
-    
+
     private final List<EntitlementEvent> initialEvents;
 
     // Low level events are ONLY used for Repair APIs
     protected List<EntitlementEvent> events;
 
 
-    public SubscriptionDataRepair(SubscriptionBuilder builder, List<EntitlementEvent> initialEvents, SubscriptionApiService apiService,
-            EntitlementDao dao, Clock clock, AddonUtils addonUtils, CatalogService catalogService) {
+    public SubscriptionDataRepair(final SubscriptionBuilder builder, final List<EntitlementEvent> initialEvents, final SubscriptionApiService apiService,
+                                  final EntitlementDao dao, final Clock clock, final AddonUtils addonUtils, final CatalogService catalogService) {
         super(builder, apiService, clock);
         this.repairDao = dao;
         this.addonUtils = addonUtils;
@@ -70,10 +69,10 @@ public class SubscriptionDataRepair extends SubscriptionData {
         this.initialEvents = initialEvents;
     }
 
-    
+
     DateTime getLastUserEventEffectiveDate() {
         DateTime res = null;
-        for (EntitlementEvent cur : events) {
+        for (final EntitlementEvent cur : events) {
             if (cur.getActiveVersion() != getActiveVersion()) {
                 break;
             }
@@ -86,29 +85,29 @@ public class SubscriptionDataRepair extends SubscriptionData {
     }
 
     public void addNewRepairEvent(final DefaultNewEvent input, final SubscriptionDataRepair baseSubscription, final List<SubscriptionDataRepair> addonSubscriptions, final CallContext context)
-    throws EntitlementRepairException {
+            throws EntitlementRepairException {
 
         try {
             final PlanPhaseSpecifier spec = input.getPlanPhaseSpecifier();
-            switch(input.getSubscriptionTransitionType()) {
-            case CREATE:
-            case RE_CREATE:
-                recreate(spec, input.getRequestedDate(), context);
-                checkAddonRights(baseSubscription);
-                break;
-            case CHANGE:
-                changePlan(spec.getProductName(), spec.getBillingPeriod(), spec.getPriceListName(), input.getRequestedDate(), context);
-                checkAddonRights(baseSubscription);
-                trickleDownBPEffectForAddon(addonSubscriptions, getLastUserEventEffectiveDate(), context);
-                break;
-            case CANCEL:
-                cancel(input.getRequestedDate(), false, context);
-                trickleDownBPEffectForAddon(addonSubscriptions, getLastUserEventEffectiveDate(), context);
-                break;
-            case PHASE:
-                break;
-            default:
-                throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_TYPE, input.getSubscriptionTransitionType(), id);
+            switch (input.getSubscriptionTransitionType()) {
+                case CREATE:
+                case RE_CREATE:
+                    recreate(spec, input.getRequestedDate(), context);
+                    checkAddonRights(baseSubscription);
+                    break;
+                case CHANGE:
+                    changePlan(spec.getProductName(), spec.getBillingPeriod(), spec.getPriceListName(), input.getRequestedDate(), context);
+                    checkAddonRights(baseSubscription);
+                    trickleDownBPEffectForAddon(addonSubscriptions, getLastUserEventEffectiveDate(), context);
+                    break;
+                case CANCEL:
+                    cancel(input.getRequestedDate(), false, context);
+                    trickleDownBPEffectForAddon(addonSubscriptions, getLastUserEventEffectiveDate(), context);
+                    break;
+                case PHASE:
+                    break;
+                default:
+                    throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_TYPE, input.getSubscriptionTransitionType(), id);
             }
         } catch (EntitlementUserApiException e) {
             throw new EntitlementRepairException(e);
@@ -118,72 +117,71 @@ public class SubscriptionDataRepair extends SubscriptionData {
     }
 
 
-    public void addFutureAddonCancellation(List<SubscriptionDataRepair> addOnSubscriptionInRepair, final CallContext context) {
+    public void addFutureAddonCancellation(final List<SubscriptionDataRepair> addOnSubscriptionInRepair, final CallContext context) {
 
         if (category != ProductCategory.BASE) {
             return;
         }
 
-        SubscriptionTransitionData pendingTransition = getPendingTransitionData();
+        final SubscriptionTransitionData pendingTransition = getPendingTransitionData();
         if (pendingTransition == null) {
             return;
         }
-        Product baseProduct = (pendingTransition.getTransitionType() == SubscriptionTransitionType.CANCEL) ? null : 
-            pendingTransition.getNextPlan().getProduct();
+        final Product baseProduct = (pendingTransition.getTransitionType() == SubscriptionTransitionType.CANCEL) ? null :
+                pendingTransition.getNextPlan().getProduct();
 
         addAddonCancellationIfRequired(addOnSubscriptionInRepair, baseProduct, pendingTransition.getEffectiveTransitionTime(), context);
     }
-    
+
     private void trickleDownBPEffectForAddon(final List<SubscriptionDataRepair> addOnSubscriptionInRepair, final DateTime effectiveDate, final CallContext context)
-     throws EntitlementUserApiException {
+            throws EntitlementUserApiException {
 
         if (category != ProductCategory.BASE) {
             return;
         }
 
-        Product baseProduct = (getState() == SubscriptionState.CANCELLED ) ?
+        final Product baseProduct = (getState() == SubscriptionState.CANCELLED) ?
                 null : getCurrentPlan().getProduct();
         addAddonCancellationIfRequired(addOnSubscriptionInRepair, baseProduct, effectiveDate, context);
     }
-    
-    
-    
-    private void addAddonCancellationIfRequired(final List<SubscriptionDataRepair> addOnSubscriptionInRepair, Product baseProduct, final DateTime effectiveDate, final CallContext context) {
 
-        DateTime now = clock.getUTCNow();
-        Iterator<SubscriptionDataRepair> it = addOnSubscriptionInRepair.iterator();
+
+    private void addAddonCancellationIfRequired(final List<SubscriptionDataRepair> addOnSubscriptionInRepair, final Product baseProduct, final DateTime effectiveDate, final CallContext context) {
+
+        final DateTime now = clock.getUTCNow();
+        final Iterator<SubscriptionDataRepair> it = addOnSubscriptionInRepair.iterator();
         while (it.hasNext()) {
-            SubscriptionDataRepair cur = it.next();
+            final SubscriptionDataRepair cur = it.next();
             if (cur.getState() == SubscriptionState.CANCELLED ||
                     cur.getCategory() != ProductCategory.ADD_ON) {
                 continue;
             }
-            Plan addonCurrentPlan = cur.getCurrentPlan();
+            final Plan addonCurrentPlan = cur.getCurrentPlan();
             if (baseProduct == null ||
                     addonUtils.isAddonIncluded(baseProduct, addonCurrentPlan) ||
-                    ! addonUtils.isAddonAvailable(baseProduct, addonCurrentPlan)) {
-
-                EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
-                .setSubscriptionId(cur.getId())
-                .setActiveVersion(cur.getActiveVersion())
-                .setProcessedDate(now)
-                .setEffectiveDate(effectiveDate)
-                .setRequestedDate(now)
-                .setUserToken(context.getUserToken())
-                .setFromDisk(true));
+                    !addonUtils.isAddonAvailable(baseProduct, addonCurrentPlan)) {
+
+                final EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
+                                                                          .setSubscriptionId(cur.getId())
+                                                                          .setActiveVersion(cur.getActiveVersion())
+                                                                          .setProcessedDate(now)
+                                                                          .setEffectiveDate(effectiveDate)
+                                                                          .setRequestedDate(now)
+                                                                          .setUserToken(context.getUserToken())
+                                                                          .setFromDisk(true));
                 repairDao.cancelSubscription(cur.getId(), cancelEvent, context, 0);
                 cur.rebuildTransitions(repairDao.getEventsForSubscription(cur.getId()), catalogService.getFullCatalog());
             }
         }
     }
 
-    private void checkAddonRights(final SubscriptionDataRepair baseSubscription) 
-        throws EntitlementUserApiException, CatalogApiException  {
+    private void checkAddonRights(final SubscriptionDataRepair baseSubscription)
+            throws EntitlementUserApiException, CatalogApiException {
         if (category == ProductCategory.ADD_ON) {
             addonUtils.checkAddonCreationRights(baseSubscription, getCurrentPlan());
         }
     }
-    
+
     public void rebuildTransitions(final List<EntitlementEvent> inputEvents, final Catalog catalog) {
         this.events = inputEvents;
         super.rebuildTransitions(inputEvents, catalog);
@@ -197,12 +195,12 @@ public class SubscriptionDataRepair extends SubscriptionData {
         return initialEvents;
     }
 
-    
+
     public Collection<EntitlementEvent> getNewEvents() {
-        Collection<EntitlementEvent> newEvents  = Collections2.filter(events, new Predicate<EntitlementEvent>() {
+        final Collection<EntitlementEvent> newEvents = Collections2.filter(events, new Predicate<EntitlementEvent>() {
             @Override
-            public boolean apply(EntitlementEvent input) {
-                return ! initialEvents.contains(input);
+            public boolean apply(final EntitlementEvent input) {
+                return !initialEvents.contains(input);
             }
         });
         return newEvents;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
index 7d92852..2b26c87 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
@@ -33,8 +33,8 @@ import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.SubscriptionFactory;
-import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
+import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionStatusDryRun.DryRunChangeReason;
 import com.ning.billing.entitlement.engine.addon.AddonUtils;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
@@ -52,8 +52,8 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     private final SubscriptionFactory subscriptionFactory;
 
     @Inject
-    public DefaultEntitlementUserApi(Clock clock, EntitlementDao dao, CatalogService catalogService,
-            DefaultSubscriptionApiService apiService, final SubscriptionFactory subscriptionFactory, AddonUtils addonUtils) {
+    public DefaultEntitlementUserApi(final Clock clock, final EntitlementDao dao, final CatalogService catalogService,
+                                     final DefaultSubscriptionApiService apiService, final SubscriptionFactory subscriptionFactory, final AddonUtils addonUtils) {
         super();
         this.clock = clock;
         this.apiService = apiService;
@@ -63,10 +63,10 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
         this.subscriptionFactory = subscriptionFactory;
     }
 
-    
+
     @Override
-    public SubscriptionBundle getBundleFromId(UUID id) throws EntitlementUserApiException {
-        SubscriptionBundle result = dao.getSubscriptionBundleFromId(id);
+    public SubscriptionBundle getBundleFromId(final UUID id) throws EntitlementUserApiException {
+        final SubscriptionBundle result = dao.getSubscriptionBundleFromId(id);
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_GET_INVALID_BUNDLE_ID, id.toString());
         }
@@ -74,8 +74,8 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public Subscription getSubscriptionFromId(UUID id) throws EntitlementUserApiException {
-        Subscription result = dao.getSubscriptionFromId(subscriptionFactory, id);
+    public Subscription getSubscriptionFromId(final UUID id) throws EntitlementUserApiException {
+        final Subscription result = dao.getSubscriptionFromId(subscriptionFactory, id);
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, id);
         }
@@ -83,8 +83,8 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public SubscriptionBundle getBundleForKey(String bundleKey) throws EntitlementUserApiException {
-        SubscriptionBundle result =  dao.getSubscriptionBundleFromKey(bundleKey);
+    public SubscriptionBundle getBundleForKey(final String bundleKey) throws EntitlementUserApiException {
+        final SubscriptionBundle result = dao.getSubscriptionBundleFromKey(bundleKey);
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_GET_INVALID_BUNDLE_KEY, bundleKey);
         }
@@ -92,106 +92,106 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     }
 
     @Override
-    public List<SubscriptionBundle> getBundlesForAccount(UUID accountId) {
+    public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId) {
         return dao.getSubscriptionBundleForAccount(accountId);
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForKey(String bundleKey) {
+    public List<Subscription> getSubscriptionsForKey(final String bundleKey) {
         return dao.getSubscriptionsForKey(subscriptionFactory, bundleKey);
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForBundle(UUID bundleId) {
+    public List<Subscription> getSubscriptionsForBundle(final UUID bundleId) {
         return dao.getSubscriptions(subscriptionFactory, bundleId);
     }
 
     @Override
-    public Subscription getBaseSubscription(UUID bundleId) throws EntitlementUserApiException {
-        Subscription result =  dao.getBaseSubscription(subscriptionFactory, bundleId);
+    public Subscription getBaseSubscription(final UUID bundleId) throws EntitlementUserApiException {
+        final Subscription result = dao.getBaseSubscription(subscriptionFactory, bundleId);
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_GET_NO_SUCH_BASE_SUBSCRIPTION, bundleId);
         }
         return result;
     }
-    
 
-    public SubscriptionBundle createBundleForAccount(UUID accountId, String bundleName, CallContext context)
-    throws EntitlementUserApiException {
-        SubscriptionBundleData bundle = new SubscriptionBundleData(bundleName, accountId, clock.getUTCNow());
+
+    public SubscriptionBundle createBundleForAccount(final UUID accountId, final String bundleName, final CallContext context)
+            throws EntitlementUserApiException {
+        final SubscriptionBundleData bundle = new SubscriptionBundleData(bundleName, accountId, clock.getUTCNow());
         return dao.createSubscriptionBundle(bundle, context);
     }
 
     @Override
-    public Subscription createSubscription(UUID bundleId, PlanPhaseSpecifier spec, DateTime requestedDate,
-                                           CallContext context) throws EntitlementUserApiException {
+    public Subscription createSubscription(final UUID bundleId, final PlanPhaseSpecifier spec, DateTime requestedDate,
+                                           final CallContext context) throws EntitlementUserApiException {
         try {
-            String realPriceList = (spec.getPriceListName() == null) ? PriceListSet.DEFAULT_PRICELIST_NAME : spec.getPriceListName();
-            DateTime now = clock.getUTCNow();
+            final String realPriceList = (spec.getPriceListName() == null) ? PriceListSet.DEFAULT_PRICELIST_NAME : spec.getPriceListName();
+            final DateTime now = clock.getUTCNow();
             requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : now;
             if (requestedDate.isAfter(now)) {
                 throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE, requestedDate.toString());
             }
-            DateTime effectiveDate = requestedDate;
+            final DateTime effectiveDate = requestedDate;
 
-            Catalog catalog = catalogService.getFullCatalog();
-            Plan plan = catalog.findPlan(spec.getProductName(), spec.getBillingPeriod(), realPriceList, requestedDate);
+            final Catalog catalog = catalogService.getFullCatalog();
+            final Plan plan = catalog.findPlan(spec.getProductName(), spec.getBillingPeriod(), realPriceList, requestedDate);
 
-            PlanPhase phase = plan.getAllPhases()[0];
+            final PlanPhase phase = plan.getAllPhases()[0];
             if (phase == null) {
                 throw new EntitlementError(String.format("No initial PlanPhase for Product %s, term %s and set %s does not exist in the catalog",
-                        spec.getProductName(), spec.getBillingPeriod().toString(), realPriceList));
+                                                         spec.getProductName(), spec.getBillingPeriod().toString(), realPriceList));
             }
 
-            SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(bundleId);
+            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(bundleId);
             if (bundle == null) {
                 throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_NO_BUNDLE, bundleId);
             }
 
             DateTime bundleStartDate = null;
-            SubscriptionData baseSubscription = (SubscriptionData) dao.getBaseSubscription(subscriptionFactory, bundleId);
-            switch(plan.getProduct().getCategory()) {
-            case BASE:
-                if (baseSubscription != null) {
-                    if (baseSubscription.getState() == SubscriptionState.ACTIVE) {
+            final SubscriptionData baseSubscription = (SubscriptionData) dao.getBaseSubscription(subscriptionFactory, bundleId);
+            switch (plan.getProduct().getCategory()) {
+                case BASE:
+                    if (baseSubscription != null) {
+                        if (baseSubscription.getState() == SubscriptionState.ACTIVE) {
+                            throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_BP_EXISTS, bundleId);
+                        } else {
+                            // If we do create on an existing CANCELLED BP, this is equivalent to call recreate on that Subscription.
+                            baseSubscription.recreate(spec, requestedDate, context);
+                            return baseSubscription;
+                        }
+                    }
+                    bundleStartDate = requestedDate;
+                    break;
+                case ADD_ON:
+                    if (baseSubscription == null) {
+                        throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_NO_BP, bundleId);
+                    }
+                    if (effectiveDate.isBefore(baseSubscription.getStartDate())) {
+                        throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE, requestedDate.toString());
+                    }
+                    addonUtils.checkAddonCreationRights(baseSubscription, plan);
+                    bundleStartDate = baseSubscription.getStartDate();
+                    break;
+                case STANDALONE:
+                    if (baseSubscription != null) {
                         throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_BP_EXISTS, bundleId);
-                    } else {
-                        // If we do create on an existing CANCELLED BP, this is equivalent to call recreate on that Subscription.
-                        baseSubscription.recreate(spec, requestedDate, context);
-                        return baseSubscription;
                     }
-                }
-                bundleStartDate = requestedDate;
-                break;
-            case ADD_ON:
-                if (baseSubscription == null) {
-                    throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_NO_BP, bundleId);
-                }
-                if (effectiveDate.isBefore(baseSubscription.getStartDate())) {
-                    throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE, requestedDate.toString());
-                }
-                addonUtils.checkAddonCreationRights(baseSubscription, plan);
-                bundleStartDate = baseSubscription.getStartDate();
-                break;
-            case STANDALONE:
-                if (baseSubscription != null) {
-                    throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_BP_EXISTS, bundleId);
-                }
-                // Not really but we don't care, there is no alignment for STANDALONE subscriptions
-                bundleStartDate = requestedDate;
-                break;
-            default:
-                throw new EntitlementError(String.format("Can't create subscription of type %s",
-                        plan.getProduct().getCategory().toString()));
+                    // Not really but we don't care, there is no alignment for STANDALONE subscriptions
+                    bundleStartDate = requestedDate;
+                    break;
+                default:
+                    throw new EntitlementError(String.format("Can't create subscription of type %s",
+                                                             plan.getProduct().getCategory().toString()));
             }
 
-            SubscriptionData subscription = apiService.createPlan(new SubscriptionBuilder()
-                 .setId(UUID.randomUUID())
-                .setBundleId(bundleId)
-                .setCategory(plan.getProduct().getCategory())
-                .setBundleStartDate(bundleStartDate)
-                .setStartDate(effectiveDate),
-            plan, spec.getPhaseType(), realPriceList, requestedDate, effectiveDate, now, context);
+            final SubscriptionData subscription = apiService.createPlan(new SubscriptionBuilder()
+                                                                          .setId(UUID.randomUUID())
+                                                                          .setBundleId(bundleId)
+                                                                          .setCategory(plan.getProduct().getCategory())
+                                                                          .setBundleStartDate(bundleStartDate)
+                                                                          .setStartDate(effectiveDate),
+                                                                  plan, spec.getPhaseType(), realPriceList, requestedDate, effectiveDate, now, context);
 
             return subscription;
         } catch (CatalogApiException e) {
@@ -201,14 +201,14 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
 
 
     @Override
-    public DateTime getNextBillingDate(UUID accountId) {
-        List<SubscriptionBundle> bundles = getBundlesForAccount(accountId);
+    public DateTime getNextBillingDate(final UUID accountId) {
+        final List<SubscriptionBundle> bundles = getBundlesForAccount(accountId);
         DateTime result = null;
-        for(SubscriptionBundle bundle : bundles) {
-            List<Subscription> subscriptions = getSubscriptionsForBundle(bundle.getId());
-            for(Subscription subscription : subscriptions) {
-                DateTime chargedThruDate = subscription.getChargedThroughDate();
-                if(result == null ||
+        for (final SubscriptionBundle bundle : bundles) {
+            final List<Subscription> subscriptions = getSubscriptionsForBundle(bundle.getId());
+            for (final Subscription subscription : subscriptions) {
+                final DateTime chargedThruDate = subscription.getChargedThroughDate();
+                if (result == null ||
                         (chargedThruDate != null && chargedThruDate.isBefore(result))) {
                     result = subscription.getChargedThroughDate();
                 }
@@ -219,25 +219,25 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
 
 
     @Override
-    public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(UUID subscriptionId, String baseProductName, DateTime requestedDate)
+    public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, final String baseProductName, final DateTime requestedDate)
             throws EntitlementUserApiException {
 
-        Subscription subscription = dao.getSubscriptionFromId(subscriptionFactory, subscriptionId);
+        final Subscription subscription = dao.getSubscriptionFromId(subscriptionFactory, subscriptionId);
         if (subscription == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, subscriptionId);
         }
         if (subscription.getCategory() != ProductCategory.BASE) {
             throw new EntitlementUserApiException(ErrorCode.ENT_CHANGE_DRY_RUN_NOT_BP);
         }
-        
-        List<SubscriptionStatusDryRun> result = new LinkedList<SubscriptionStatusDryRun>();
-        
-        List<Subscription> bundleSubscriptions = dao.getSubscriptions(subscriptionFactory, subscription.getBundleId());
-        for (Subscription cur : bundleSubscriptions) {
+
+        final List<SubscriptionStatusDryRun> result = new LinkedList<SubscriptionStatusDryRun>();
+
+        final List<Subscription> bundleSubscriptions = dao.getSubscriptions(subscriptionFactory, subscription.getBundleId());
+        for (final Subscription cur : bundleSubscriptions) {
             if (cur.getId().equals(subscriptionId)) {
                 continue;
             }
-            
+
             DryRunChangeReason reason = null;
             if (addonUtils.isAddonIncludedFromProdName(baseProductName, requestedDate, cur.getCurrentPlan())) {
                 reason = DryRunChangeReason.AO_INCLUDED_IN_NEW_PLAN;
@@ -246,10 +246,10 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
             } else {
                 reason = DryRunChangeReason.AO_NOT_AVAILABLE_IN_NEW_PLAN;
             }
-            SubscriptionStatusDryRun status = new DefaultSubscriptionStatusDryRun(cur.getId(), 
-                    cur.getCurrentPlan().getProduct().getName(), cur.getCurrentPhase().getPhaseType(),
-                    cur.getCurrentPlan().getBillingPeriod(),
-                    cur.getCurrentPriceList().getName(), reason);
+            final SubscriptionStatusDryRun status = new DefaultSubscriptionStatusDryRun(cur.getId(),
+                                                                                  cur.getCurrentPlan().getProduct().getName(), cur.getCurrentPhase().getPhaseType(),
+                                                                                  cur.getCurrentPlan().getBillingPeriod(),
+                                                                                  cur.getCurrentPriceList().getName(), reason);
             result.add(status);
         }
         return result;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java
index 7783c42..327edb4 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java
@@ -39,8 +39,8 @@ import com.ning.billing.catalog.api.Product;
 import com.ning.billing.entitlement.alignment.PlanAligner;
 import com.ning.billing.entitlement.alignment.TimedPhase;
 import com.ning.billing.entitlement.api.SubscriptionApiService;
-import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
+import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
@@ -65,48 +65,47 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
     private final PlanAligner planAligner;
 
     @Inject
-    public DefaultSubscriptionApiService(Clock clock, EntitlementDao dao, CatalogService catalogService, PlanAligner planAligner) {
+    public DefaultSubscriptionApiService(final Clock clock, final EntitlementDao dao, final CatalogService catalogService, final PlanAligner planAligner) {
         this.clock = clock;
         this.catalogService = catalogService;
         this.planAligner = planAligner;
         this.dao = dao;
     }
 
-    public SubscriptionData createPlan(SubscriptionBuilder builder, Plan plan, PhaseType initialPhase,
-            String realPriceList, DateTime requestedDate, DateTime effectiveDate, DateTime processedDate,
-            CallContext context)
-        throws EntitlementUserApiException {
-        SubscriptionData subscription = new SubscriptionData(builder, this, clock);
+    public SubscriptionData createPlan(final SubscriptionBuilder builder, final Plan plan, final PhaseType initialPhase,
+                                       final String realPriceList, final DateTime requestedDate, final DateTime effectiveDate, final DateTime processedDate,
+                                       final CallContext context)
+            throws EntitlementUserApiException {
+        final SubscriptionData subscription = new SubscriptionData(builder, this, clock);
 
 
-        
         createFromSubscription(subscription, plan, initialPhase, realPriceList, requestedDate, effectiveDate, processedDate, false, context);
         return subscription;
     }
 
 
-    public boolean recreatePlan(SubscriptionData subscription, PlanPhaseSpecifier spec, DateTime requestedDate, CallContext context)
-    throws EntitlementUserApiException {
+    public boolean recreatePlan(final SubscriptionData subscription, final PlanPhaseSpecifier spec, DateTime requestedDate, final CallContext context)
+            throws EntitlementUserApiException {
 
-        SubscriptionState currentState = subscription.getState();
+        final SubscriptionState currentState = subscription.getState();
         if (currentState != null && currentState != SubscriptionState.CANCELLED) {
             throw new EntitlementUserApiException(ErrorCode.ENT_RECREATE_BAD_STATE, subscription.getId(), currentState);
         }
-        DateTime now = clock.getUTCNow();
+        final DateTime now = clock.getUTCNow();
         requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : now;
         validateRequestedDate(subscription, now, requestedDate);
 
         try {
-            String realPriceList = (spec.getPriceListName() == null) ? PriceListSet.DEFAULT_PRICELIST_NAME : spec.getPriceListName();
-            Plan plan = catalogService.getFullCatalog().findPlan(spec.getProductName(), spec.getBillingPeriod(), realPriceList, requestedDate);
-            PlanPhase phase = plan.getAllPhases()[0];
+            final String realPriceList = (spec.getPriceListName() == null) ? PriceListSet.DEFAULT_PRICELIST_NAME : spec.getPriceListName();
+            final Plan plan = catalogService.getFullCatalog().findPlan(spec.getProductName(), spec.getBillingPeriod(), realPriceList, requestedDate);
+            final PlanPhase phase = plan.getAllPhases()[0];
             if (phase == null) {
                 throw new EntitlementError(String.format("No initial PlanPhase for Product %s, term %s and set %s does not exist in the catalog",
-                        spec.getProductName(), spec.getBillingPeriod().toString(), realPriceList));
+                                                         spec.getProductName(), spec.getBillingPeriod().toString(), realPriceList));
             }
 
-            DateTime effectiveDate = requestedDate;
-            DateTime processedDate = now;
+            final DateTime effectiveDate = requestedDate;
+            final DateTime processedDate = now;
 
             createFromSubscription(subscription, plan, spec.getPhaseType(), realPriceList, requestedDate, effectiveDate, processedDate, true, context);
             return true;
@@ -115,33 +114,33 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
         }
     }
 
-    private void createFromSubscription(SubscriptionData subscription, Plan plan, PhaseType initialPhase,
-            String realPriceList, DateTime requestedDate, DateTime effectiveDate, DateTime processedDate,
-            boolean reCreate, CallContext context)
-    throws EntitlementUserApiException {
+    private void createFromSubscription(final SubscriptionData subscription, final Plan plan, final PhaseType initialPhase,
+                                        final String realPriceList, final DateTime requestedDate, final DateTime effectiveDate, final DateTime processedDate,
+                                        final boolean reCreate, final CallContext context)
+            throws EntitlementUserApiException {
 
 
         try {
-            TimedPhase [] curAndNextPhases = planAligner.getCurrentAndNextTimedPhaseOnCreate(subscription, plan, initialPhase, realPriceList, requestedDate, effectiveDate);
-
-            ApiEventBuilder createBuilder = new ApiEventBuilder()
-            .setSubscriptionId(subscription.getId())
-            .setEventPlan(plan.getName())
-            .setEventPlanPhase(curAndNextPhases[0].getPhase().getName())
-            .setEventPriceList(realPriceList)
-            .setActiveVersion(subscription.getActiveVersion())
-            .setProcessedDate(processedDate)
-            .setEffectiveDate(effectiveDate)
-            .setRequestedDate(requestedDate)
-            .setUserToken(context.getUserToken())            
-            .setFromDisk(true);
-            ApiEvent creationEvent = (reCreate) ? new ApiEventReCreate(createBuilder) : new ApiEventCreate(createBuilder);
-
-            TimedPhase nextTimedPhase = curAndNextPhases[1];
-            PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
+            final TimedPhase[] curAndNextPhases = planAligner.getCurrentAndNextTimedPhaseOnCreate(subscription, plan, initialPhase, realPriceList, requestedDate, effectiveDate);
+
+            final ApiEventBuilder createBuilder = new ApiEventBuilder()
+                    .setSubscriptionId(subscription.getId())
+                    .setEventPlan(plan.getName())
+                    .setEventPlanPhase(curAndNextPhases[0].getPhase().getName())
+                    .setEventPriceList(realPriceList)
+                    .setActiveVersion(subscription.getActiveVersion())
+                    .setProcessedDate(processedDate)
+                    .setEffectiveDate(effectiveDate)
+                    .setRequestedDate(requestedDate)
+                    .setUserToken(context.getUserToken())
+                    .setFromDisk(true);
+            final ApiEvent creationEvent = (reCreate) ? new ApiEventReCreate(createBuilder) : new ApiEventCreate(createBuilder);
+
+            final TimedPhase nextTimedPhase = curAndNextPhases[1];
+            final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
                     PhaseEventData.createNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscription, processedDate, nextTimedPhase.getStartPhase()) :
-                        null;
-            List<EntitlementEvent> events = new ArrayList<EntitlementEvent>();
+                    null;
+            final List<EntitlementEvent> events = new ArrayList<EntitlementEvent>();
             events.add(creationEvent);
             if (nextPhaseEvent != null) {
                 events.add(nextPhaseEvent);
@@ -157,37 +156,37 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
         }
     }
 
-    public boolean cancel(SubscriptionData subscription, DateTime requestedDate, boolean eot, CallContext context)
-    throws EntitlementUserApiException {
+    public boolean cancel(final SubscriptionData subscription, DateTime requestedDate, final boolean eot, final CallContext context)
+            throws EntitlementUserApiException {
 
         try {
-            SubscriptionState currentState = subscription.getState();
+            final SubscriptionState currentState = subscription.getState();
             if (currentState != SubscriptionState.ACTIVE) {
                 throw new EntitlementUserApiException(ErrorCode.ENT_CANCEL_BAD_STATE, subscription.getId(), currentState);
             }
 
-            DateTime now = clock.getUTCNow();
+            final DateTime now = clock.getUTCNow();
             requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : now;
             validateRequestedDate(subscription, now, requestedDate);
 
-            Plan currentPlan = subscription.getCurrentPlan();
-            PlanPhaseSpecifier planPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
-                    currentPlan.getProduct().getCategory(),
-                    subscription.getCurrentPlan().getBillingPeriod(),
-                    subscription.getCurrentPriceList().getName(),
-                    subscription.getCurrentPhase().getPhaseType());
-
-            ActionPolicy policy = catalogService.getFullCatalog().planCancelPolicy(planPhase, requestedDate);
-            DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, requestedDate);
-
-            EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
-            .setSubscriptionId(subscription.getId())
-            .setActiveVersion(subscription.getActiveVersion())
-            .setProcessedDate(now)
-            .setEffectiveDate(effectiveDate)
-            .setRequestedDate(requestedDate)
-            .setUserToken(context.getUserToken())
-            .setFromDisk(true));
+            final Plan currentPlan = subscription.getCurrentPlan();
+            final PlanPhaseSpecifier planPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
+                                                                  currentPlan.getProduct().getCategory(),
+                                                                  subscription.getCurrentPlan().getBillingPeriod(),
+                                                                  subscription.getCurrentPriceList().getName(),
+                                                                  subscription.getCurrentPhase().getPhaseType());
+
+            final ActionPolicy policy = catalogService.getFullCatalog().planCancelPolicy(planPhase, requestedDate);
+            final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, requestedDate);
+
+            final EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
+                                                                      .setSubscriptionId(subscription.getId())
+                                                                      .setActiveVersion(subscription.getActiveVersion())
+                                                                      .setProcessedDate(now)
+                                                                      .setEffectiveDate(effectiveDate)
+                                                                      .setRequestedDate(requestedDate)
+                                                                      .setUserToken(context.getUserToken())
+                                                                      .setFromDisk(true));
 
             dao.cancelSubscription(subscription.getId(), cancelEvent, context, 0);
             subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getFullCatalog());
@@ -198,52 +197,52 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
     }
 
 
-    public boolean uncancel(SubscriptionData subscription, CallContext context)
-    throws EntitlementUserApiException {
+    public boolean uncancel(final SubscriptionData subscription, final CallContext context)
+            throws EntitlementUserApiException {
 
         if (!subscription.isSubscriptionFutureCancelled()) {
             throw new EntitlementUserApiException(ErrorCode.ENT_UNCANCEL_BAD_STATE, subscription.getId().toString());
         }
 
-        DateTime now = clock.getUTCNow();
-        EntitlementEvent uncancelEvent = new ApiEventUncancel(new ApiEventBuilder()
-        .setSubscriptionId(subscription.getId())
-        .setActiveVersion(subscription.getActiveVersion())
-        .setProcessedDate(now)
-        .setRequestedDate(now)
-        .setEffectiveDate(now)
-        .setUserToken(context.getUserToken())
-        .setFromDisk(true));
-
-        List<EntitlementEvent> uncancelEvents = new ArrayList<EntitlementEvent>();
+        final DateTime now = clock.getUTCNow();
+        final EntitlementEvent uncancelEvent = new ApiEventUncancel(new ApiEventBuilder()
+                                                                      .setSubscriptionId(subscription.getId())
+                                                                      .setActiveVersion(subscription.getActiveVersion())
+                                                                      .setProcessedDate(now)
+                                                                      .setRequestedDate(now)
+                                                                      .setEffectiveDate(now)
+                                                                      .setUserToken(context.getUserToken())
+                                                                      .setFromDisk(true));
+
+        final List<EntitlementEvent> uncancelEvents = new ArrayList<EntitlementEvent>();
         uncancelEvents.add(uncancelEvent);
 
-        TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, now, now);
-        PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
+        final TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, now, now);
+        final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
                 PhaseEventData.createNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscription, now, nextTimedPhase.getStartPhase()) :
-                    null;
-                if (nextPhaseEvent != null) {
-                    uncancelEvents.add(nextPhaseEvent);
-                }
-                dao.uncancelSubscription(subscription.getId(), uncancelEvents, context);
-                subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getFullCatalog());
-                return true;
+                null;
+        if (nextPhaseEvent != null) {
+            uncancelEvents.add(nextPhaseEvent);
+        }
+        dao.uncancelSubscription(subscription.getId(), uncancelEvents, context);
+        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getFullCatalog());
+        return true;
     }
-    
-    public boolean changePlan(SubscriptionData subscription, String productName, BillingPeriod term,
-            String priceList, DateTime requestedDate, CallContext context)
 
-    throws EntitlementUserApiException {
+    public boolean changePlan(final SubscriptionData subscription, final String productName, final BillingPeriod term,
+                              final String priceList, DateTime requestedDate, final CallContext context)
+
+            throws EntitlementUserApiException {
 
         try {
 
-            DateTime now = clock.getUTCNow();
+            final DateTime now = clock.getUTCNow();
             requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : now;
             validateRequestedDate(subscription, now, requestedDate);
 
-            PriceList currentPriceList = subscription.getCurrentPriceList();
+            final PriceList currentPriceList = subscription.getCurrentPriceList();
 
-            SubscriptionState currentState = subscription.getState();
+            final SubscriptionState currentState = subscription.getState();
             if (currentState != SubscriptionState.ACTIVE) {
                 throw new EntitlementUserApiException(ErrorCode.ENT_CHANGE_NON_ACTIVE, subscription.getId(), currentState);
             }
@@ -254,49 +253,49 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
             PlanChangeResult planChangeResult = null;
             try {
 
-                Product destProduct = catalogService.getFullCatalog().findProduct(productName, requestedDate);
-                Plan currentPlan = subscription.getCurrentPlan();
-                PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
-                        currentPlan.getProduct().getCategory(),
-                        currentPlan.getBillingPeriod(),
-                        currentPriceList.getName(), subscription.getCurrentPhase().getPhaseType());
-                PlanSpecifier toPlanPhase = new PlanSpecifier(productName,
-                        destProduct.getCategory(),
-                        term,
-                        priceList);
+                final Product destProduct = catalogService.getFullCatalog().findProduct(productName, requestedDate);
+                final Plan currentPlan = subscription.getCurrentPlan();
+                final PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
+                                                                          currentPlan.getProduct().getCategory(),
+                                                                          currentPlan.getBillingPeriod(),
+                                                                          currentPriceList.getName(), subscription.getCurrentPhase().getPhaseType());
+                final PlanSpecifier toPlanPhase = new PlanSpecifier(productName,
+                                                              destProduct.getCategory(),
+                                                              term,
+                                                              priceList);
 
                 planChangeResult = catalogService.getFullCatalog().planChange(fromPlanPhase, toPlanPhase, requestedDate);
             } catch (CatalogApiException e) {
                 throw new EntitlementUserApiException(e);
             }
 
-            ActionPolicy policy = planChangeResult.getPolicy();
-            PriceList newPriceList = planChangeResult.getNewPriceList();
+            final ActionPolicy policy = planChangeResult.getPolicy();
+            final PriceList newPriceList = planChangeResult.getNewPriceList();
 
-            Plan newPlan = catalogService.getFullCatalog().findPlan(productName, term, newPriceList.getName(), requestedDate, subscription.getStartDate());
-            DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, requestedDate);
+            final Plan newPlan = catalogService.getFullCatalog().findPlan(productName, term, newPriceList.getName(), requestedDate, subscription.getStartDate());
+            final DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, requestedDate);
 
-            TimedPhase currentTimedPhase = planAligner.getCurrentTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), requestedDate, effectiveDate);
+            final TimedPhase currentTimedPhase = planAligner.getCurrentTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), requestedDate, effectiveDate);
 
-            EntitlementEvent changeEvent = new ApiEventChange(new ApiEventBuilder()
-            .setSubscriptionId(subscription.getId())
-            .setEventPlan(newPlan.getName())
-            .setEventPlanPhase(currentTimedPhase.getPhase().getName())
-            .setEventPriceList(newPriceList.getName())
-            .setActiveVersion(subscription.getActiveVersion())
-            .setProcessedDate(now)
-            .setEffectiveDate(effectiveDate)
-            .setRequestedDate(requestedDate)
-            .setUserToken(context.getUserToken())            
-            .setFromDisk(true));
+            final EntitlementEvent changeEvent = new ApiEventChange(new ApiEventBuilder()
+                                                                      .setSubscriptionId(subscription.getId())
+                                                                      .setEventPlan(newPlan.getName())
+                                                                      .setEventPlanPhase(currentTimedPhase.getPhase().getName())
+                                                                      .setEventPriceList(newPriceList.getName())
+                                                                      .setActiveVersion(subscription.getActiveVersion())
+                                                                      .setProcessedDate(now)
+                                                                      .setEffectiveDate(effectiveDate)
+                                                                      .setRequestedDate(requestedDate)
+                                                                      .setUserToken(context.getUserToken())
+                                                                      .setFromDisk(true));
 
-            TimedPhase nextTimedPhase = planAligner.getNextTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), requestedDate, effectiveDate);
-            PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
+            final TimedPhase nextTimedPhase = planAligner.getNextTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), requestedDate, effectiveDate);
+            final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
                     PhaseEventData.createNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscription, now, nextTimedPhase.getStartPhase()) :
-                        null;
-            List<EntitlementEvent> changeEvents = new ArrayList<EntitlementEvent>();
+                    null;
+            final List<EntitlementEvent> changeEvents = new ArrayList<EntitlementEvent>();
             // Only add the PHASE if it does not coincide with the CHANGE, if not this is 'just' a CHANGE.
-            if (nextPhaseEvent != null && ! nextPhaseEvent.getEffectiveDate().equals(changeEvent.getEffectiveDate())) {
+            if (nextPhaseEvent != null && !nextPhaseEvent.getEffectiveDate().equals(changeEvent.getEffectiveDate())) {
                 changeEvents.add(nextPhaseEvent);
             }
             changeEvents.add(changeEvent);
@@ -308,19 +307,19 @@ public class DefaultSubscriptionApiService implements SubscriptionApiService {
         }
     }
 
-    private void validateRequestedDate(SubscriptionData subscription, DateTime now, DateTime requestedDate)
-        throws EntitlementUserApiException {
+    private void validateRequestedDate(final SubscriptionData subscription, final DateTime now, final DateTime requestedDate)
+            throws EntitlementUserApiException {
 
-        if (requestedDate.isAfter(now) ) {
+        if (requestedDate.isAfter(now)) {
             throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_FUTURE_DATE, requestedDate.toString());
         }
 
-        SubscriptionEvent previousTransition = subscription.getPreviousTransition();
+        final SubscriptionEvent previousTransition = subscription.getPreviousTransition();
         if (previousTransition != null && previousTransition.getEffectiveTransitionTime().isAfter(requestedDate)) {
             throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE,
-                    requestedDate.toString(), previousTransition.getEffectiveTransitionTime());
+                                                  requestedDate.toString(), previousTransition.getEffectiveTransitionTime());
         }
     }
-    
+
 
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java
index 333cc4e..f28ddb7 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionEvent.java
@@ -17,11 +17,11 @@ package com.ning.billing.entitlement.api.user;
 
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import org.joda.time.DateTime;
-
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 
@@ -46,47 +46,47 @@ public class DefaultSubscriptionEvent implements SubscriptionEvent {
     private final SubscriptionTransitionType transitionType;
 
     private final DateTime startDate;
-    
+
     public DefaultSubscriptionEvent(final SubscriptionTransitionData in, final DateTime startDate) {
         this(in.getId(),
-                in.getSubscriptionId(),
-                in.getBundleId(),
-                in.getRequestedTransitionTime(),
-                in.getEffectiveTransitionTime(),
-                in.getPreviousState(),
-                (in.getPreviousPlan() != null ) ? in.getPreviousPlan().getName() : null,
-                (in.getPreviousPhase() != null) ? in.getPreviousPhase().getName() : null,
-                (in.getPreviousPriceList() != null) ? in.getPreviousPriceList().getName() : null,
-                in.getNextState(),
-                (in.getNextPlan() != null) ? in.getNextPlan().getName() : null,
-                (in.getNextPhase() != null) ? in.getNextPhase().getName() : null,
-                (in.getNextPriceList() != null) ? in.getNextPriceList().getName() : null,
-                in.getTotalOrdering(),
-                in.getUserToken(),
-                in.getTransitionType(),
-                in.getRemainingEventsForUserOperation(),
-                startDate);
+             in.getSubscriptionId(),
+             in.getBundleId(),
+             in.getRequestedTransitionTime(),
+             in.getEffectiveTransitionTime(),
+             in.getPreviousState(),
+             (in.getPreviousPlan() != null) ? in.getPreviousPlan().getName() : null,
+             (in.getPreviousPhase() != null) ? in.getPreviousPhase().getName() : null,
+             (in.getPreviousPriceList() != null) ? in.getPreviousPriceList().getName() : null,
+             in.getNextState(),
+             (in.getNextPlan() != null) ? in.getNextPlan().getName() : null,
+             (in.getNextPhase() != null) ? in.getNextPhase().getName() : null,
+             (in.getNextPriceList() != null) ? in.getNextPriceList().getName() : null,
+             in.getTotalOrdering(),
+             in.getUserToken(),
+             in.getTransitionType(),
+             in.getRemainingEventsForUserOperation(),
+             startDate);
     }
-    
+
     @JsonCreator
-    public DefaultSubscriptionEvent(@JsonProperty("eventId") UUID eventId,
-            @JsonProperty("subscriptionId") UUID subscriptionId,
-            @JsonProperty("bundleId") UUID bundleId,
-            @JsonProperty("requestedTransitionTime") DateTime requestedTransitionTime,
-            @JsonProperty("effectiveTransitionTime") DateTime effectiveTransitionTime,
-            @JsonProperty("previousState") SubscriptionState previousState,
-            @JsonProperty("previousPlan") String previousPlan,
-            @JsonProperty("previousPhase") String previousPhase,
-            @JsonProperty("previousPriceList") String previousPriceList,
-            @JsonProperty("nextState") SubscriptionState nextState,
-            @JsonProperty("nextPlan") String nextPlan,
-            @JsonProperty("nextPhase") String nextPhase,
-            @JsonProperty("nextPriceList") String nextPriceList,
-            @JsonProperty("totalOrdering") Long totalOrdering,
-            @JsonProperty("userToken") UUID userToken,
-            @JsonProperty("transitionType") SubscriptionTransitionType transitionType,
-            @JsonProperty("remainingEventsForUserOperation") Integer remainingEventsForUserOperation,
-            @JsonProperty("startDate") DateTime startDate) {
+    public DefaultSubscriptionEvent(@JsonProperty("eventId") final UUID eventId,
+                                    @JsonProperty("subscriptionId") final UUID subscriptionId,
+                                    @JsonProperty("bundleId") final UUID bundleId,
+                                    @JsonProperty("requestedTransitionTime") final DateTime requestedTransitionTime,
+                                    @JsonProperty("effectiveTransitionTime") final DateTime effectiveTransitionTime,
+                                    @JsonProperty("previousState") final SubscriptionState previousState,
+                                    @JsonProperty("previousPlan") final String previousPlan,
+                                    @JsonProperty("previousPhase") final String previousPhase,
+                                    @JsonProperty("previousPriceList") final String previousPriceList,
+                                    @JsonProperty("nextState") final SubscriptionState nextState,
+                                    @JsonProperty("nextPlan") final String nextPlan,
+                                    @JsonProperty("nextPhase") final String nextPhase,
+                                    @JsonProperty("nextPriceList") final String nextPriceList,
+                                    @JsonProperty("totalOrdering") final Long totalOrdering,
+                                    @JsonProperty("userToken") final UUID userToken,
+                                    @JsonProperty("transitionType") final SubscriptionTransitionType transitionType,
+                                    @JsonProperty("remainingEventsForUserOperation") final Integer remainingEventsForUserOperation,
+                                    @JsonProperty("startDate") final DateTime startDate) {
         super();
         this.eventId = eventId;
         this.subscriptionId = subscriptionId;
@@ -107,7 +107,7 @@ public class DefaultSubscriptionEvent implements SubscriptionEvent {
         this.remainingEventsForUserOperation = remainingEventsForUserOperation;
         this.startDate = startDate;
     }
-    
+
     @JsonIgnore
     @Override
     public BusEventType getBusEventType() {
@@ -171,12 +171,12 @@ public class DefaultSubscriptionEvent implements SubscriptionEvent {
     public String getNextPriceList() {
         return nextPriceList;
     }
-    
+
     @Override
     public UUID getUserToken() {
         return userToken;
     }
-    
+
     @Override
     public Integer getRemainingEventsForUserOperation() {
         return remainingEventsForUserOperation;
@@ -202,7 +202,7 @@ public class DefaultSubscriptionEvent implements SubscriptionEvent {
     public SubscriptionTransitionType getTransitionType() {
         return transitionType;
     }
-    
+
     @JsonProperty("startDate")
     @Override
     public DateTime getSubscriptionStartDate() {
@@ -219,7 +219,7 @@ public class DefaultSubscriptionEvent implements SubscriptionEvent {
         result = prime
                 * result
                 + ((effectiveTransitionTime == null) ? 0
-                        : effectiveTransitionTime.hashCode());
+                : effectiveTransitionTime.hashCode());
         result = prime * result + ((eventId == null) ? 0 : eventId.hashCode());
         result = prime * result
                 + ((nextPhase == null) ? 0 : nextPhase.hashCode());
@@ -236,17 +236,17 @@ public class DefaultSubscriptionEvent implements SubscriptionEvent {
         result = prime
                 * result
                 + ((previousPriceList == null) ? 0 : previousPriceList
-                        .hashCode());
+                .hashCode());
         result = prime * result
                 + ((previousState == null) ? 0 : previousState.hashCode());
         result = prime
                 * result
                 + ((remainingEventsForUserOperation == null) ? 0
-                        : remainingEventsForUserOperation.hashCode());
+                : remainingEventsForUserOperation.hashCode());
         result = prime
                 * result
                 + ((requestedTransitionTime == null) ? 0
-                        : requestedTransitionTime.hashCode());
+                : requestedTransitionTime.hashCode());
         result = prime * result
                 + ((subscriptionId == null) ? 0 : subscriptionId.hashCode());
         result = prime * result
@@ -259,100 +259,134 @@ public class DefaultSubscriptionEvent implements SubscriptionEvent {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        DefaultSubscriptionEvent other = (DefaultSubscriptionEvent) obj;
+        }
+        final DefaultSubscriptionEvent other = (DefaultSubscriptionEvent) obj;
         if (bundleId == null) {
-            if (other.bundleId != null)
+            if (other.bundleId != null) {
                 return false;
-        } else if (!bundleId.equals(other.bundleId))
+            }
+        } else if (!bundleId.equals(other.bundleId)) {
             return false;
+        }
         if (effectiveTransitionTime == null) {
-            if (other.effectiveTransitionTime != null)
+            if (other.effectiveTransitionTime != null) {
                 return false;
+            }
         } else if (effectiveTransitionTime
-                .compareTo(other.effectiveTransitionTime) != 0)
+                .compareTo(other.effectiveTransitionTime) != 0) {
             return false;
+        }
         if (eventId == null) {
-            if (other.eventId != null)
+            if (other.eventId != null) {
                 return false;
-        } else if (!eventId.equals(other.eventId))
+            }
+        } else if (!eventId.equals(other.eventId)) {
             return false;
+        }
         if (nextPhase == null) {
-            if (other.nextPhase != null)
+            if (other.nextPhase != null) {
                 return false;
-        } else if (!nextPhase.equals(other.nextPhase))
+            }
+        } else if (!nextPhase.equals(other.nextPhase)) {
             return false;
+        }
         if (nextPlan == null) {
-            if (other.nextPlan != null)
+            if (other.nextPlan != null) {
                 return false;
-        } else if (!nextPlan.equals(other.nextPlan))
+            }
+        } else if (!nextPlan.equals(other.nextPlan)) {
             return false;
+        }
         if (nextPriceList == null) {
-            if (other.nextPriceList != null)
+            if (other.nextPriceList != null) {
                 return false;
-        } else if (!nextPriceList.equals(other.nextPriceList))
+            }
+        } else if (!nextPriceList.equals(other.nextPriceList)) {
             return false;
-        if (nextState != other.nextState)
+        }
+        if (nextState != other.nextState) {
             return false;
+        }
         if (previousPhase == null) {
-            if (other.previousPhase != null)
+            if (other.previousPhase != null) {
                 return false;
-        } else if (!previousPhase.equals(other.previousPhase))
+            }
+        } else if (!previousPhase.equals(other.previousPhase)) {
             return false;
+        }
         if (previousPlan == null) {
-            if (other.previousPlan != null)
+            if (other.previousPlan != null) {
                 return false;
-        } else if (!previousPlan.equals(other.previousPlan))
+            }
+        } else if (!previousPlan.equals(other.previousPlan)) {
             return false;
+        }
         if (previousPriceList == null) {
-            if (other.previousPriceList != null)
+            if (other.previousPriceList != null) {
                 return false;
-        } else if (!previousPriceList.equals(other.previousPriceList))
+            }
+        } else if (!previousPriceList.equals(other.previousPriceList)) {
             return false;
-        if (previousState != other.previousState)
+        }
+        if (previousState != other.previousState) {
             return false;
+        }
         if (remainingEventsForUserOperation == null) {
-            if (other.remainingEventsForUserOperation != null)
+            if (other.remainingEventsForUserOperation != null) {
                 return false;
+            }
         } else if (!remainingEventsForUserOperation
-                .equals(other.remainingEventsForUserOperation))
+                .equals(other.remainingEventsForUserOperation)) {
             return false;
+        }
         if (requestedTransitionTime == null) {
-            if (other.requestedTransitionTime != null)
+            if (other.requestedTransitionTime != null) {
                 return false;
+            }
         } else if (requestedTransitionTime
-                .compareTo(other.requestedTransitionTime) != 0)
+                .compareTo(other.requestedTransitionTime) != 0) {
             return false;
+        }
         if (subscriptionId == null) {
-            if (other.subscriptionId != null)
+            if (other.subscriptionId != null) {
                 return false;
-        } else if (!subscriptionId.equals(other.subscriptionId))
+            }
+        } else if (!subscriptionId.equals(other.subscriptionId)) {
             return false;
+        }
         if (totalOrdering == null) {
-            if (other.totalOrdering != null)
+            if (other.totalOrdering != null) {
                 return false;
-        } else if (!totalOrdering.equals(other.totalOrdering))
+            }
+        } else if (!totalOrdering.equals(other.totalOrdering)) {
             return false;
-        if (transitionType != other.transitionType)
+        }
+        if (transitionType != other.transitionType) {
             return false;
+        }
         if (userToken == null) {
-            if (other.userToken != null)
+            if (other.userToken != null) {
                 return false;
-        } else if (!userToken.equals(other.userToken))
+            }
+        } else if (!userToken.equals(other.userToken)) {
             return false;
+        }
         return true;
     }
 
     @Override
     public String toString() {
         return "DefaultSubscriptionEvent [transitionType=" + transitionType
-                + ", effectiveTransitionTime=" + effectiveTransitionTime        
+                + ", effectiveTransitionTime=" + effectiveTransitionTime
                 + ", totalOrdering=" + totalOrdering
                 + ", subscriptionId=" + subscriptionId + ", bundleId="
                 + bundleId + ", eventId=" + eventId
@@ -365,7 +399,7 @@ public class DefaultSubscriptionEvent implements SubscriptionEvent {
                 + ", remainingEventsForUserOperation="
                 + remainingEventsForUserOperation + ", userToken=" + userToken
                 + ", startDate=" + startDate + "]";
-                
+
     }
-    
+
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionFactory.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionFactory.java
index 37a94f6..bb2188f 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionFactory.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionFactory.java
@@ -16,6 +16,12 @@
 
 package com.ning.billing.entitlement.api.user;
 
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
 import com.google.inject.Inject;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.ProductCategory;
@@ -24,11 +30,6 @@ import com.ning.billing.entitlement.api.SubscriptionFactory;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.util.clock.Clock;
-import org.joda.time.DateTime;
-
-import java.lang.reflect.Field;
-import java.util.List;
-import java.util.UUID;
 
 public class DefaultSubscriptionFactory implements SubscriptionFactory {
 
@@ -37,15 +38,15 @@ public class DefaultSubscriptionFactory implements SubscriptionFactory {
     protected final CatalogService catalogService;
 
     @Inject
-    public DefaultSubscriptionFactory(SubscriptionApiService apiService, Clock clock, CatalogService catalogService) {
+    public DefaultSubscriptionFactory(final SubscriptionApiService apiService, final Clock clock, final CatalogService catalogService) {
         this.apiService = apiService;
         this.clock = clock;
         this.catalogService = catalogService;
     }
 
 
-    public SubscriptionData createSubscription(SubscriptionBuilder builder, List<EntitlementEvent> events) {
-        SubscriptionData subscription = new SubscriptionData(builder, apiService, clock);
+    public SubscriptionData createSubscription(final SubscriptionBuilder builder, final List<EntitlementEvent> events) {
+        final SubscriptionData subscription = new SubscriptionData(builder, apiService, clock);
         if (events.size() > 0) {
             subscription.rebuildTransitions(events, catalogService.getFullCatalog());
         }
@@ -55,20 +56,20 @@ public class DefaultSubscriptionFactory implements SubscriptionFactory {
 
     public static class SubscriptionBuilder {
 
-        private  UUID id;
-        private  UUID bundleId;
-        private  DateTime startDate;
-        private  DateTime bundleStartDate;
-        private  Long activeVersion;
-        private  ProductCategory category;
-        private  DateTime chargedThroughDate;
-        private  DateTime paidThroughDate;
+        private UUID id;
+        private UUID bundleId;
+        private DateTime startDate;
+        private DateTime bundleStartDate;
+        private Long activeVersion;
+        private ProductCategory category;
+        private DateTime chargedThroughDate;
+        private DateTime paidThroughDate;
 
         public SubscriptionBuilder() {
             this.activeVersion = SubscriptionEvents.INITIAL_VERSION;
         }
 
-        public SubscriptionBuilder(SubscriptionData original) {
+        public SubscriptionBuilder(final SubscriptionData original) {
             this.id = original.getId();
             this.bundleId = original.getBundleId();
             this.startDate = original.getStartDate();
@@ -80,35 +81,42 @@ public class DefaultSubscriptionFactory implements SubscriptionFactory {
         }
 
 
-        public SubscriptionBuilder setId(UUID id) {
+        public SubscriptionBuilder setId(final UUID id) {
             this.id = id;
             return this;
         }
-        public SubscriptionBuilder setBundleId(UUID bundleId) {
+
+        public SubscriptionBuilder setBundleId(final UUID bundleId) {
             this.bundleId = bundleId;
             return this;
         }
-        public SubscriptionBuilder setStartDate(DateTime startDate) {
+
+        public SubscriptionBuilder setStartDate(final DateTime startDate) {
             this.startDate = startDate;
             return this;
         }
-        public SubscriptionBuilder setBundleStartDate(DateTime bundleStartDate) {
+
+        public SubscriptionBuilder setBundleStartDate(final DateTime bundleStartDate) {
             this.bundleStartDate = bundleStartDate;
             return this;
         }
-        public SubscriptionBuilder setActiveVersion(long activeVersion) {
+
+        public SubscriptionBuilder setActiveVersion(final long activeVersion) {
             this.activeVersion = activeVersion;
             return this;
         }
-        public SubscriptionBuilder setChargedThroughDate(DateTime chargedThroughDate) {
+
+        public SubscriptionBuilder setChargedThroughDate(final DateTime chargedThroughDate) {
             this.chargedThroughDate = chargedThroughDate;
             return this;
         }
-        public SubscriptionBuilder setPaidThroughDate(DateTime paidThroughDate) {
+
+        public SubscriptionBuilder setPaidThroughDate(final DateTime paidThroughDate) {
             this.paidThroughDate = paidThroughDate;
             return this;
         }
-        public SubscriptionBuilder setCategory(ProductCategory category) {
+
+        public SubscriptionBuilder setCategory(final ProductCategory category) {
             this.category = category;
             return this;
         }
@@ -116,38 +124,46 @@ public class DefaultSubscriptionFactory implements SubscriptionFactory {
         public UUID getId() {
             return id;
         }
+
         public UUID getBundleId() {
             return bundleId;
         }
+
         public DateTime getStartDate() {
             return startDate;
         }
+
         public DateTime getBundleStartDate() {
             return bundleStartDate;
         }
+
         public Long getActiveVersion() {
             return activeVersion;
         }
+
         public ProductCategory getCategory() {
             return category;
         }
+
         public DateTime getChargedThroughDate() {
             return chargedThroughDate;
         }
+
         public DateTime getPaidThroughDate() {
             return paidThroughDate;
         }
+
         private void checkAllFieldsSet() {
-            for (Field cur : SubscriptionBuilder.class.getDeclaredFields()) {
+            for (final Field cur : SubscriptionBuilder.class.getDeclaredFields()) {
                 try {
-                    Object value = cur.get(this);
+                    final Object value = cur.get(this);
                     if (value == null) {
                         throw new EntitlementError(String.format("Field %s has not been set for Subscription",
-                                cur.getName()));
+                                                                 cur.getName()));
                     }
                 } catch (IllegalAccessException e) {
                     throw new EntitlementError(String.format("Failed to access value for field %s for Subscription",
-                            cur.getName()), e);
+                                                             cur.getName()), e);
                 }
             }
         }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionStatusDryRun.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionStatusDryRun.java
index 9971f41..3cdc83f 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionStatusDryRun.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionStatusDryRun.java
@@ -21,18 +21,18 @@ import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PhaseType;
 
 public class DefaultSubscriptionStatusDryRun implements SubscriptionStatusDryRun {
-        
+
     private final UUID id;
     private final String productName;
     private final PhaseType phaseType;
     private final BillingPeriod billingPeriod;
     private final String priceList;
     private final DryRunChangeReason reason;
-    
-    
+
+
     public DefaultSubscriptionStatusDryRun(final UUID id, final String productName,
-            final PhaseType phaseType, final BillingPeriod billingPeriod, final String priceList,
-            final DryRunChangeReason reason) {
+                                           final PhaseType phaseType, final BillingPeriod billingPeriod, final String priceList,
+                                           final DryRunChangeReason reason) {
         super();
         this.id = id;
         this.productName = productName;
@@ -57,7 +57,7 @@ public class DefaultSubscriptionStatusDryRun implements SubscriptionStatusDryRun
         return phaseType;
     }
 
-    
+
     @Override
     public BillingPeriod getBillingPeriod() {
         return billingPeriod;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
index 4da1fe0..be076ba 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
@@ -29,18 +29,18 @@ public class SubscriptionBundleData implements SubscriptionBundle {
     private final String key;
     private final UUID accountId;
     private final DateTime startDate;
-    private final DateTime lastSysTimeUpdate; 
+    private final DateTime lastSysTimeUpdate;
     private final OverdueState<SubscriptionBundle> overdueState;
-    
-    public SubscriptionBundleData(String name, UUID accountId, DateTime startDate) {
+
+    public SubscriptionBundleData(final String name, final UUID accountId, final DateTime startDate) {
         this(UUID.randomUUID(), name, accountId, startDate, startDate);
     }
 
-    public SubscriptionBundleData(UUID id, String key, UUID accountId, DateTime startDate, DateTime lastSysUpdate) {
+    public SubscriptionBundleData(final UUID id, final String key, final UUID accountId, final DateTime startDate, final DateTime lastSysUpdate) {
         this(id, key, accountId, startDate, lastSysUpdate, null);
     }
 
-    public SubscriptionBundleData(UUID id, String key, UUID accountId, DateTime startDate, DateTime lastSysUpdate, OverdueState<SubscriptionBundle> overdueState) {
+    public SubscriptionBundleData(final UUID id, final String key, final UUID accountId, final DateTime startDate, final DateTime lastSysUpdate, final OverdueState<SubscriptionBundle> overdueState) {
         super();
         this.id = id;
         this.key = key;
@@ -70,11 +70,11 @@ public class SubscriptionBundleData implements SubscriptionBundle {
     public DateTime getStartDate() {
         return startDate;
     }
-    
+
     public DateTime getLastSysUpdateTime() {
         return lastSysTimeUpdate;
     }
-    
+
     @Override
     public OverdueState<SubscriptionBundle> getOverdueState() {
         return overdueState;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
index b03ea32..e162011 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
@@ -16,14 +16,13 @@
 
 package com.ning.billing.entitlement.api.user;
 
+import javax.annotation.Nullable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
-import javax.annotation.Nullable;
-
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -56,7 +55,7 @@ import com.ning.billing.util.entity.EntityBase;
 
 public class SubscriptionData extends EntityBase implements Subscription {
 
-    private final static Logger log = LoggerFactory.getLogger(SubscriptionData.class);
+    private static final Logger log = LoggerFactory.getLogger(SubscriptionData.class);
 
 
     protected final Clock clock;
@@ -77,7 +76,7 @@ public class SubscriptionData extends EntityBase implements Subscription {
     protected final DateTime chargedThroughDate;
     protected final DateTime paidThroughDate;
 
-    
+
     //
     // User APIs (create, change, cancel,...) will recompute those each time,
     // so the user holding that subscription object get the correct state when
@@ -86,12 +85,12 @@ public class SubscriptionData extends EntityBase implements Subscription {
     protected LinkedList<SubscriptionTransitionData> transitions;
 
     // Transient object never returned at the API
-    public SubscriptionData(SubscriptionBuilder builder) {
+    public SubscriptionData(final SubscriptionBuilder builder) {
         this(builder, null, null);
     }
 
-    public SubscriptionData(SubscriptionBuilder builder,
-            @Nullable SubscriptionApiService apiService, @Nullable Clock clock) {
+    public SubscriptionData(final SubscriptionBuilder builder,
+                            @Nullable final SubscriptionApiService apiService, @Nullable final Clock clock) {
         super(builder.getId());
         this.apiService = apiService;
         this.clock = clock;
@@ -135,13 +134,13 @@ public class SubscriptionData extends EntityBase implements Subscription {
     @Override
     public PriceList getCurrentPriceList() {
         return (getPreviousTransitionData() == null) ? null :
-            getPreviousTransitionData().getNextPriceList();
+                getPreviousTransitionData().getNextPriceList();
 
     }
 
     @Override
     public DateTime getEndDate() {
-        SubscriptionEvent latestTransition = getPreviousTransition();
+        final SubscriptionEvent latestTransition = getPreviousTransition();
         if (latestTransition.getNextState() == SubscriptionState.CANCELLED) {
             return latestTransition.getEffectiveTransitionTime();
         }
@@ -149,40 +148,40 @@ public class SubscriptionData extends EntityBase implements Subscription {
     }
 
     @Override
-    public boolean cancel(DateTime requestedDate, boolean eot,
-            CallContext context) throws EntitlementUserApiException {
+    public boolean cancel(final DateTime requestedDate, final boolean eot,
+                          final CallContext context) throws EntitlementUserApiException {
         return apiService.cancel(this, requestedDate, eot, context);
     }
 
     @Override
-    public boolean uncancel(CallContext context)
+    public boolean uncancel(final CallContext context)
             throws EntitlementUserApiException {
         return apiService.uncancel(this, context);
     }
 
     @Override
-    public boolean changePlan(String productName, BillingPeriod term,
-            String priceList, DateTime requestedDate, CallContext context)
+    public boolean changePlan(final String productName, final BillingPeriod term,
+                              final String priceList, final DateTime requestedDate, final CallContext context)
             throws EntitlementUserApiException {
         return apiService.changePlan(this, productName, term, priceList,
-                requestedDate, context);
+                                     requestedDate, context);
     }
 
     @Override
-    public boolean recreate(PlanPhaseSpecifier spec, DateTime requestedDate,
-            CallContext context) throws EntitlementUserApiException {
+    public boolean recreate(final PlanPhaseSpecifier spec, final DateTime requestedDate,
+                            final CallContext context) throws EntitlementUserApiException {
         return apiService.recreatePlan(this, spec, requestedDate, context);
     }
 
     @Override
     public SubscriptionEvent getPendingTransition() {
-        SubscriptionTransitionData data = getPendingTransitionData();
+        final SubscriptionTransitionData data = getPendingTransitionData();
         if (data == null) {
             return null;
         }
         return new DefaultSubscriptionEvent(data, startDate);
     }
-    
+
     @Override
     public BlockingState getBlockingState() {
         throw new UnsupportedOperationException();
@@ -192,15 +191,15 @@ public class SubscriptionData extends EntityBase implements Subscription {
         if (transitions == null) {
             return null;
         }
-        SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
+        final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
                 clock, transitions, Order.ASC_FROM_PAST, Kind.ENTITLEMENT,
                 Visibility.ALL, TimeLimit.FUTURE_ONLY);
         return it.hasNext() ? it.next() : null;
     }
-    
+
     @Override
     public SubscriptionEvent getPreviousTransition() {
-        SubscriptionTransitionData data = getPreviousTransitionData();
+        final SubscriptionTransitionData data = getPreviousTransitionData();
         if (data == null) {
             return null;
         }
@@ -211,7 +210,7 @@ public class SubscriptionData extends EntityBase implements Subscription {
         if (transitions == null) {
             return null;
         }
-        SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
+        final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
                 clock, transitions, Order.DESC_FROM_FUTURE, Kind.ENTITLEMENT,
                 Visibility.FROM_DISK_ONLY, TimeLimit.PAST_OR_PRESENT_ONLY);
         return it.hasNext() ? it.next() : null;
@@ -246,19 +245,24 @@ public class SubscriptionData extends EntityBase implements Subscription {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        SubscriptionData other = (SubscriptionData) obj;
+        }
+        final SubscriptionData other = (SubscriptionData) obj;
         if (id == null) {
-            if (other.id != null)
+            if (other.id != null) {
                 return false;
-        } else if (!id.equals(other.id))
+            }
+        } else if (!id.equals(other.id)) {
             return false;
+        }
         return true;
     }
 
@@ -267,8 +271,8 @@ public class SubscriptionData extends EntityBase implements Subscription {
         if (transitions == null) {
             return Collections.emptyList();
         }
-        List<SubscriptionEvent> result = new ArrayList<SubscriptionEvent>();
-        SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
+        final List<SubscriptionEvent> result = new ArrayList<SubscriptionEvent>();
+        final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
                 clock, transitions, Order.ASC_FROM_PAST, Kind.BILLING,
                 Visibility.ALL, TimeLimit.ALL);
         while (it.hasNext()) {
@@ -282,9 +286,9 @@ public class SubscriptionData extends EntityBase implements Subscription {
         if (transitions == null || event == null) {
             return null;
         }
-        for (SubscriptionTransitionData  cur : transitions) {
+        for (final SubscriptionTransitionData cur : transitions) {
             if (cur.getId().equals(event.getId())) {
-                SubscriptionTransitionData withSeq = new SubscriptionTransitionData(cur, seqId);
+                final SubscriptionTransitionData withSeq = new SubscriptionTransitionData(cur, seqId);
                 return new DefaultSubscriptionEvent(withSeq, startDate);
             }
         }
@@ -292,12 +296,12 @@ public class SubscriptionData extends EntityBase implements Subscription {
     }
 
     public long getLastEventOrderedId() {
-        SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
+        final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
                 clock, transitions, Order.DESC_FROM_FUTURE, Kind.ENTITLEMENT,
                 Visibility.FROM_DISK_ONLY, TimeLimit.ALL);
-        return it.hasNext() ? it.next().getTotalOrdering() :  -1L;
+        return it.hasNext() ? it.next().getTotalOrdering() : -1L;
     }
-    
+
     public long getActiveVersion() {
         return activeVersion;
     }
@@ -313,11 +317,11 @@ public class SubscriptionData extends EntityBase implements Subscription {
                     "No transitions for subscription %s", getId()));
         }
 
-        SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
+        final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
                 clock, transitions, Order.DESC_FROM_FUTURE, Kind.ENTITLEMENT,
                 Visibility.ALL, TimeLimit.PAST_OR_PRESENT_ONLY);
         while (it.hasNext()) {
-            SubscriptionTransitionData cur = it.next();
+            final SubscriptionTransitionData cur = it.next();
             if (cur.getTransitionType() == SubscriptionTransitionType.CREATE
                     || cur.getTransitionType() == SubscriptionTransitionType.RE_CREATE
                     || cur.getTransitionType() == SubscriptionTransitionType.CHANGE
@@ -334,11 +338,11 @@ public class SubscriptionData extends EntityBase implements Subscription {
         if (transitions == null) {
             return false;
         }
-        SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
+        final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
                 clock, transitions, Order.ASC_FROM_PAST, Kind.ENTITLEMENT,
                 Visibility.ALL, TimeLimit.FUTURE_ONLY);
         while (it.hasNext()) {
-            SubscriptionTransitionData cur = it.next();
+            final SubscriptionTransitionData cur = it.next();
             if (cur.getTransitionType() == SubscriptionTransitionType.CANCEL) {
                 return true;
             }
@@ -346,8 +350,8 @@ public class SubscriptionData extends EntityBase implements Subscription {
         return false;
     }
 
-    public DateTime getPlanChangeEffectiveDate(ActionPolicy policy,
-            DateTime requestedDate) {
+    public DateTime getPlanChangeEffectiveDate(final ActionPolicy policy,
+                                               final DateTime requestedDate) {
 
         if (policy == ActionPolicy.IMMEDIATE) {
             return requestedDate;
@@ -371,11 +375,11 @@ public class SubscriptionData extends EntityBase implements Subscription {
             throw new EntitlementError(String.format(
                     "No transitions for subscription %s", getId()));
         }
-        SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
+        final SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(
                 clock, transitions, Order.DESC_FROM_FUTURE, Kind.ENTITLEMENT,
                 Visibility.ALL, TimeLimit.PAST_OR_PRESENT_ONLY);
         while (it.hasNext()) {
-            SubscriptionTransitionData cur = it.next();
+            final SubscriptionTransitionData cur = it.next();
 
             if (cur.getTransitionType() == SubscriptionTransitionType.PHASE
                     || cur.getTransitionType() == SubscriptionTransitionType.CREATE
@@ -390,7 +394,7 @@ public class SubscriptionData extends EntityBase implements Subscription {
     }
 
     public void rebuildTransitions(final List<EntitlementEvent> inputEvents,
-            final Catalog catalog) {
+                                   final Catalog catalog) {
 
         if (inputEvents == null) {
             return;
@@ -399,7 +403,7 @@ public class SubscriptionData extends EntityBase implements Subscription {
         SubscriptionState nextState = null;
         String nextPlanName = null;
         String nextPhaseName = null;
-        String nextPriceListName = null; 
+        String nextPriceListName = null;
         UUID nextUserToken = null;
 
         SubscriptionState previousState = null;
@@ -421,52 +425,52 @@ public class SubscriptionData extends EntityBase implements Subscription {
 
             switch (cur.getType()) {
 
-            case PHASE:
-                PhaseEvent phaseEV = (PhaseEvent) cur;
-                nextPhaseName = phaseEV.getPhase();
-                break;
-
-            case API_USER:
-                ApiEvent userEV = (ApiEvent) cur;
-                apiEventType = userEV.getEventType();
-                isFromDisk = userEV.isFromDisk();
-                nextUserToken = userEV.getUserToken();
-
-                switch (apiEventType) {
-                case MIGRATE_BILLING:
-                case MIGRATE_ENTITLEMENT:
-                case CREATE:
-                case RE_CREATE:
-                    previousState = null;
-                    previousPlan = null;
-                    previousPhase = null;
-                    previousPriceList = null;
-                    nextState = SubscriptionState.ACTIVE;
-                    nextPlanName = userEV.getEventPlan();
-                    nextPhaseName = userEV.getEventPlanPhase();
-                    nextPriceListName = userEV.getPriceList();
-                    break;
-                case CHANGE:
-                    nextPlanName = userEV.getEventPlan();
-                    nextPhaseName = userEV.getEventPlanPhase();
-                    nextPriceListName = userEV.getPriceList();
+                case PHASE:
+                    final PhaseEvent phaseEV = (PhaseEvent) cur;
+                    nextPhaseName = phaseEV.getPhase();
                     break;
-                case CANCEL:
-                    nextState = SubscriptionState.CANCELLED;
-                    nextPlanName = null;
-                    nextPhaseName = null;
-                    break;
-                case UNCANCEL:
+
+                case API_USER:
+                    final ApiEvent userEV = (ApiEvent) cur;
+                    apiEventType = userEV.getEventType();
+                    isFromDisk = userEV.isFromDisk();
+                    nextUserToken = userEV.getUserToken();
+
+                    switch (apiEventType) {
+                        case MIGRATE_BILLING:
+                        case MIGRATE_ENTITLEMENT:
+                        case CREATE:
+                        case RE_CREATE:
+                            previousState = null;
+                            previousPlan = null;
+                            previousPhase = null;
+                            previousPriceList = null;
+                            nextState = SubscriptionState.ACTIVE;
+                            nextPlanName = userEV.getEventPlan();
+                            nextPhaseName = userEV.getEventPlanPhase();
+                            nextPriceListName = userEV.getPriceList();
+                            break;
+                        case CHANGE:
+                            nextPlanName = userEV.getEventPlan();
+                            nextPhaseName = userEV.getEventPlanPhase();
+                            nextPriceListName = userEV.getPriceList();
+                            break;
+                        case CANCEL:
+                            nextState = SubscriptionState.CANCELLED;
+                            nextPlanName = null;
+                            nextPhaseName = null;
+                            break;
+                        case UNCANCEL:
+                            break;
+                        default:
+                            throw new EntitlementError(String.format(
+                                    "Unexpected UserEvent type = %s", userEV
+                                    .getEventType().toString()));
+                    }
                     break;
                 default:
                     throw new EntitlementError(String.format(
-                            "Unexpected UserEvent type = %s", userEV
-                                    .getEventType().toString()));
-                }
-                break;
-            default:
-                throw new EntitlementError(String.format(
-                        "Unexpected Event type = %s", cur.getType()));
+                            "Unexpected Event type = %s", cur.getType()));
             }
 
             Plan nextPlan = null;
@@ -480,9 +484,9 @@ public class SubscriptionData extends EntityBase implements Subscription {
             } catch (CatalogApiException e) {
                 log.error(String.format(
                         "Failed to build transition for subscription %s", id),
-                        e);
+                          e);
             }
-            SubscriptionTransitionData transition = new SubscriptionTransitionData(
+            final SubscriptionTransitionData transition = new SubscriptionTransitionData(
                     cur.getId(), id, bundleId, cur.getType(), apiEventType,
                     cur.getRequestedDate(), cur.getEffectiveDate(),
                     previousState, previousPlan, previousPhase,
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java
index 66dfb88..31d664d 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java
@@ -16,28 +16,27 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import com.ning.billing.entitlement.events.EntitlementEvent;
-
 import java.util.LinkedList;
 import java.util.UUID;
 
+import com.ning.billing.entitlement.events.EntitlementEvent;
+
 public class SubscriptionEvents {
 
     public static final long INITIAL_VERSION = 1;
 
-    private final UUID subscriptionId;
     private final LinkedList<EntitlementEvent> events;
 
     private long activeVersion;
 
-    public SubscriptionEvents(UUID subscriptionId) {
+    public SubscriptionEvents(final UUID subscriptionId) {
         super();
-        this.subscriptionId = subscriptionId;
+        final UUID subscriptionId1 = subscriptionId;
         this.events = new LinkedList<EntitlementEvent>();
         this.activeVersion = INITIAL_VERSION;
     }
 
-    public void addEvent(EntitlementEvent ev) {
+    public void addEvent(final EntitlementEvent ev) {
         events.add(ev);
     }
 
@@ -47,8 +46,8 @@ public class SubscriptionEvents {
 
     public LinkedList<EntitlementEvent> getViewForVersion(final long version) {
 
-        LinkedList<EntitlementEvent> result = new LinkedList<EntitlementEvent>();
-        for (EntitlementEvent cur : events) {
+        final LinkedList<EntitlementEvent> result = new LinkedList<EntitlementEvent>();
+        for (final EntitlementEvent cur : events) {
             if (cur.getActiveVersion() == version) {
                 result.add(cur);
             }
@@ -61,7 +60,7 @@ public class SubscriptionEvents {
         return activeVersion;
     }
 
-    public void setActiveVersion(long activeVersion) {
+    public void setActiveVersion(final long activeVersion) {
         this.activeVersion = activeVersion;
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionData.java
index 4a8d90b..ac54ea3 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionData.java
@@ -22,8 +22,8 @@ import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
-import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.catalog.api.PriceList;
+import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
 import com.ning.billing.entitlement.events.user.ApiEventType;
@@ -53,24 +53,24 @@ public class SubscriptionTransitionData /* implements SubscriptionEvent */ {
     private final UUID userToken;
 
 
-    public SubscriptionTransitionData(UUID eventId,
-            UUID subscriptionId,
-            UUID bundleId,
-            EventType eventType,
-            ApiEventType apiEventType,
-            DateTime requestedTransitionTime,
-            DateTime effectiveTransitionTime,
-            SubscriptionState previousState,
-            Plan previousPlan,
-            PlanPhase previousPhase,
-            PriceList previousPriceList,
-            SubscriptionState nextState,
-            Plan nextPlan,
-            PlanPhase nextPhase,
-            PriceList nextPriceList,
-            Long totalOrdering,
-            UUID userToken,
-            Boolean isFromDisk) {
+    public SubscriptionTransitionData(final UUID eventId,
+                                      final UUID subscriptionId,
+                                      final UUID bundleId,
+                                      final EventType eventType,
+                                      final ApiEventType apiEventType,
+                                      final DateTime requestedTransitionTime,
+                                      final DateTime effectiveTransitionTime,
+                                      final SubscriptionState previousState,
+                                      final Plan previousPlan,
+                                      final PlanPhase previousPhase,
+                                      final PriceList previousPriceList,
+                                      final SubscriptionState nextState,
+                                      final Plan nextPlan,
+                                      final PlanPhase nextPhase,
+                                      final PriceList nextPriceList,
+                                      final Long totalOrdering,
+                                      final UUID userToken,
+                                      final Boolean isFromDisk) {
         super();
         this.eventId = eventId;
         this.subscriptionId = subscriptionId;
@@ -92,7 +92,7 @@ public class SubscriptionTransitionData /* implements SubscriptionEvent */ {
         this.userToken = userToken;
         this.remainingEventsForUserOperation = 0;
     }
-    
+
     public SubscriptionTransitionData(final SubscriptionTransitionData input, final int remainingEventsForUserOperation) {
         super();
         this.eventId = input.getId();
@@ -161,28 +161,28 @@ public class SubscriptionTransitionData /* implements SubscriptionEvent */ {
     public PriceList getNextPriceList() {
         return nextPriceList;
     }
-    
-	public UUID getUserToken() {
-		return userToken;
-	}
-	
-	public Integer getRemainingEventsForUserOperation() {
-		return remainingEventsForUserOperation;
-	}
+
+    public UUID getUserToken() {
+        return userToken;
+    }
+
+    public Integer getRemainingEventsForUserOperation() {
+        return remainingEventsForUserOperation;
+    }
 
 
     public SubscriptionTransitionType getTransitionType() {
         return toSubscriptionTransitionType(eventType, apiEventType);
     }
-    
-    public static SubscriptionTransitionType toSubscriptionTransitionType(EventType eventType, ApiEventType apiEventType) {
-        switch(eventType) {
-        case API_USER:
-            return apiEventType.getSubscriptionTransitionType();
-        case PHASE:
-            return SubscriptionTransitionType.PHASE;
-        default:
-            throw new EntitlementError("Unexpected event type " + eventType);
+
+    public static SubscriptionTransitionType toSubscriptionTransitionType(final EventType eventType, final ApiEventType apiEventType) {
+        switch (eventType) {
+            case API_USER:
+                return apiEventType.getSubscriptionTransitionType();
+            case PHASE:
+                return SubscriptionTransitionType.PHASE;
+            default:
+                throw new EntitlementError("Unexpected event type " + eventType);
         }
     }
 
@@ -215,17 +215,17 @@ public class SubscriptionTransitionData /* implements SubscriptionEvent */ {
     @Override
     public String toString() {
         return "SubscriptionTransition [eventId=" + eventId
-            + ", subscriptionId=" + subscriptionId
-            + ", eventType=" + eventType + ", apiEventType="
-            + apiEventType + ", requestedTransitionTime=" + requestedTransitionTime
-            + ", effectiveTransitionTime=" + effectiveTransitionTime
-            + ", previousState=" + previousState + ", previousPlan="
-            + ((previousPlan != null) ? previousPlan.getName()  : null)
-            + ", previousPhase=" + ((previousPhase != null) ? previousPhase.getName() : null)
-            + ", previousPriceList " + previousPriceList
-            + ", nextState=" + nextState
-            + ", nextPlan=" + ((nextPlan != null) ? nextPlan.getName() : null)
-            + ", nextPriceList " + nextPriceList
-            + ", nextPhase=" + ((nextPhase != null) ? nextPhase.getName() : null) + "]";
+                + ", subscriptionId=" + subscriptionId
+                + ", eventType=" + eventType + ", apiEventType="
+                + apiEventType + ", requestedTransitionTime=" + requestedTransitionTime
+                + ", effectiveTransitionTime=" + effectiveTransitionTime
+                + ", previousState=" + previousState + ", previousPlan="
+                + ((previousPlan != null) ? previousPlan.getName() : null)
+                + ", previousPhase=" + ((previousPhase != null) ? previousPhase.getName() : null)
+                + ", previousPriceList " + previousPriceList
+                + ", nextState=" + nextState
+                + ", nextPlan=" + ((nextPlan != null) ? nextPlan.getName() : null)
+                + ", nextPriceList " + nextPriceList
+                + ", nextPhase=" + ((nextPhase != null) ? nextPhase.getName() : null) + "]";
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionDataIterator.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionDataIterator.java
index 355628d..bd9ec62 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionDataIterator.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionDataIterator.java
@@ -55,10 +55,10 @@ public class SubscriptionTransitionDataIterator implements Iterator<Subscription
         ALL
     }
 
-    public SubscriptionTransitionDataIterator(Clock clock, LinkedList<SubscriptionTransitionData> transitions,
-            Order order, Kind kind, Visibility visibility, TimeLimit timeLimit) {
+    public SubscriptionTransitionDataIterator(final Clock clock, final LinkedList<SubscriptionTransitionData> transitions,
+                                              final Order order, final Kind kind, final Visibility visibility, final TimeLimit timeLimit) {
         this.it = (order == Order.DESC_FROM_FUTURE) ? transitions.descendingIterator() : transitions.iterator();
-        this. clock = clock;
+        this.clock = clock;
         this.kind = kind;
         this.timeLimit = timeLimit;
         this.visibility = visibility;
@@ -68,16 +68,16 @@ public class SubscriptionTransitionDataIterator implements Iterator<Subscription
     @Override
     public boolean hasNext() {
         do {
-            boolean hasNext = it.hasNext();
+            final boolean hasNext = it.hasNext();
             if (!hasNext) {
                 return false;
             }
             next = it.next();
-        }  while (shouldSkip(next));
+        } while (shouldSkip(next));
         return true;
     }
 
-    private boolean shouldSkip(SubscriptionTransitionData input) {
+    private boolean shouldSkip(final SubscriptionTransitionData input) {
         if (visibility == Visibility.FROM_DISK_ONLY && !input.isFromDisk()) {
             return true;
         }
@@ -85,7 +85,7 @@ public class SubscriptionTransitionDataIterator implements Iterator<Subscription
                 (kind == Kind.BILLING && input.getTransitionType() == SubscriptionTransitionType.MIGRATE_ENTITLEMENT)) {
             return true;
         }
-        if ((timeLimit == TimeLimit.FUTURE_ONLY && ! input.getEffectiveTransitionTime().isAfter(clock.getUTCNow())) ||
+        if ((timeLimit == TimeLimit.FUTURE_ONLY && !input.getEffectiveTransitionTime().isAfter(clock.getUTCNow())) ||
                 ((timeLimit == TimeLimit.PAST_OR_PRESENT_ONLY && input.getEffectiveTransitionTime().isAfter(clock.getUTCNow())))) {
             return true;
         }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/addon/AddonUtils.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/addon/AddonUtils.java
index 2a4a550..44079d8 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/addon/AddonUtils.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/addon/AddonUtils.java
@@ -26,11 +26,9 @@ import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.Product;
-import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
+import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.SubscriptionEvent;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 
 public class AddonUtils {
@@ -40,32 +38,32 @@ public class AddonUtils {
     private final CatalogService catalogService;
 
     @Inject
-    public AddonUtils(CatalogService catalogService) {
+    public AddonUtils(final CatalogService catalogService) {
         this.catalogService = catalogService;
     }
 
-    public void checkAddonCreationRights(SubscriptionData baseSubscription, Plan targetAddOnPlan)
-    throws EntitlementUserApiException, CatalogApiException {
+    public void checkAddonCreationRights(final SubscriptionData baseSubscription, final Plan targetAddOnPlan)
+            throws EntitlementUserApiException, CatalogApiException {
 
         if (baseSubscription.getState() != SubscriptionState.ACTIVE) {
             throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_AO_BP_NON_ACTIVE, targetAddOnPlan.getName());
         }
 
-        Product baseProduct = baseSubscription.getCurrentPlan().getProduct();
+        final Product baseProduct = baseSubscription.getCurrentPlan().getProduct();
         if (isAddonIncluded(baseProduct, targetAddOnPlan)) {
             throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_AO_ALREADY_INCLUDED,
-                    targetAddOnPlan.getName(), baseSubscription.getCurrentPlan().getProduct().getName());
+                                                  targetAddOnPlan.getName(), baseSubscription.getCurrentPlan().getProduct().getName());
         }
 
         if (!isAddonAvailable(baseProduct, targetAddOnPlan)) {
             throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_AO_NOT_AVAILABLE,
-                    targetAddOnPlan.getName(), baseSubscription.getCurrentPlan().getProduct().getName());
+                                                  targetAddOnPlan.getName(), baseSubscription.getCurrentPlan().getProduct().getName());
         }
     }
 
     public boolean isAddonAvailableFromProdName(final String baseProductName, final DateTime requestedDate, final Plan targetAddOnPlan) {
         try {
-            Product product = catalogService.getFullCatalog().findProduct(baseProductName, requestedDate);
+            final Product product = catalogService.getFullCatalog().findProduct(baseProductName, requestedDate);
             return isAddonAvailable(product, targetAddOnPlan);
         } catch (CatalogApiException e) {
             throw new EntitlementError(e);
@@ -74,8 +72,8 @@ public class AddonUtils {
 
     public boolean isAddonAvailableFromPlanName(final String basePlanName, final DateTime requestedDate, final Plan targetAddOnPlan) {
         try {
-            Plan plan = catalogService.getFullCatalog().findPlan(basePlanName, requestedDate);
-            Product product = plan.getProduct();
+            final Plan plan = catalogService.getFullCatalog().findPlan(basePlanName, requestedDate);
+            final Product product = plan.getProduct();
             return isAddonAvailable(product, targetAddOnPlan);
         } catch (CatalogApiException e) {
             throw new EntitlementError(e);
@@ -83,20 +81,20 @@ public class AddonUtils {
     }
 
     public boolean isAddonAvailable(final Product baseProduct, final Plan targetAddOnPlan) {
-        Product targetAddonProduct = targetAddOnPlan.getProduct();
-        Product[] availableAddOns = baseProduct.getAvailable();
+        final Product targetAddonProduct = targetAddOnPlan.getProduct();
+        final Product[] availableAddOns = baseProduct.getAvailable();
 
-        for (Product curAv : availableAddOns) {
+        for (final Product curAv : availableAddOns) {
             if (curAv.getName().equals(targetAddonProduct.getName())) {
                 return true;
             }
         }
         return false;
     }
-    
+
     public boolean isAddonIncludedFromProdName(final String baseProductName, final DateTime requestedDate, final Plan targetAddOnPlan) {
-        try {            
-            Product product = catalogService.getFullCatalog().findProduct(baseProductName, requestedDate);
+        try {
+            final Product product = catalogService.getFullCatalog().findProduct(baseProductName, requestedDate);
             return isAddonIncluded(product, targetAddOnPlan);
         } catch (CatalogApiException e) {
             throw new EntitlementError(e);
@@ -105,9 +103,9 @@ public class AddonUtils {
     }
 
     public boolean isAddonIncludedFromPlanName(final String basePlanName, final DateTime requestedDate, final Plan targetAddOnPlan) {
-        try {            
-            Plan plan = catalogService.getFullCatalog().findPlan(basePlanName, requestedDate);
-            Product product = plan.getProduct();
+        try {
+            final Plan plan = catalogService.getFullCatalog().findPlan(basePlanName, requestedDate);
+            final Product product = plan.getProduct();
             return isAddonIncluded(product, targetAddOnPlan);
         } catch (CatalogApiException e) {
             throw new EntitlementError(e);
@@ -115,9 +113,9 @@ public class AddonUtils {
     }
 
     public boolean isAddonIncluded(final Product baseProduct, final Plan targetAddOnPlan) {
-        Product targetAddonProduct = targetAddOnPlan.getProduct();
-        Product[] includedAddOns = baseProduct.getIncluded();
-        for (Product curAv : includedAddOns) {
+        final Product targetAddonProduct = targetAddOnPlan.getProduct();
+        final Product[] includedAddOns = baseProduct.getIncluded();
+        for (final Product curAv : includedAddOns) {
             if (curAv.getName().equals(targetAddonProduct.getName())) {
                 return true;
             }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
index d5b9fb1..a4a926e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
@@ -17,20 +17,19 @@
 package com.ning.billing.entitlement.engine.core;
 
 
-
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;
+
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
-
-
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
@@ -62,6 +61,7 @@ import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.notificationq.NotificationKey;
 import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
@@ -70,11 +70,11 @@ import com.ning.billing.util.notificationq.NotificationQueueService.Notification
 
 public class Engine implements EventListener, EntitlementService {
 
-	
+
     public static final String NOTIFICATION_QUEUE_NAME = "subscription-events";
     public static final String ENTITLEMENT_SERVICE_NAME = "entitlement-service";
 
-    private final static Logger log = LoggerFactory.getLogger(Engine.class);
+    private static final Logger log = LoggerFactory.getLogger(Engine.class);
 
     private final Clock clock;
     private final EntitlementDao dao;
@@ -89,12 +89,12 @@ public class Engine implements EventListener, EntitlementService {
     private NotificationQueue subscriptionEventQueue;
 
     @Inject
-    public Engine(Clock clock, EntitlementDao dao, PlanAligner planAligner,
-            EntitlementConfig config,
-            AddonUtils addonUtils, Bus eventBus,
-            NotificationQueueService notificationQueueService,
-            SubscriptionFactory subscriptionFactory,
-            CallContextFactory factory) {
+    public Engine(final Clock clock, final EntitlementDao dao, final PlanAligner planAligner,
+            final EntitlementConfig config,
+            final AddonUtils addonUtils, final Bus eventBus,
+            final NotificationQueueService notificationQueueService,
+            final SubscriptionFactory subscriptionFactory,
+            final CallContextFactory factory) {
         super();
         this.clock = clock;
         this.dao = dao;
@@ -120,31 +120,37 @@ public class Engine implements EventListener, EntitlementService {
                     NOTIFICATION_QUEUE_NAME,
                     new NotificationQueueHandler() {
                 @Override
-                public void handleReadyNotification(final String inputKey, final DateTime eventDateTime) {
-                	
-                	EntitlementNotificationKey key = new EntitlementNotificationKey(inputKey);
-                    final EntitlementEvent event = dao.getEventById(key.getEventId());
+                public void handleReadyNotification(final NotificationKey inputKey, final DateTime eventDateTime) {
+
+                    if (! (inputKey instanceof EntitlementNotificationKey)) {
+                        log.error("Entitlement service received an unexpected event type {}" + inputKey.getClass().getName());
+                        return;
+                    }
+                    EntitlementNotificationKey key = (EntitlementNotificationKey) inputKey;
+                    
+                     final EntitlementEvent event = dao.getEventById(key.getEventId());
                     if (event == null) {
                         log.warn("Failed to extract event for notification key {}", inputKey);
                         return;
                     }
-                    final UUID userToken =  (event.getType() == EventType.API_USER) ? ((ApiEvent) event).getUserToken() : null;
+                    final UUID userToken = (event.getType() == EventType.API_USER) ? ((ApiEvent) event).getUserToken() : null;
                     final CallContext context = factory.createCallContext("SubscriptionEventQueue", CallOrigin.INTERNAL, UserType.SYSTEM, userToken);
                     processEventReady(event, key.getSeqId(), context);
                 }
             },
             new NotificationConfig() {
-                
+
                 @Override
                 public long getSleepTimeMs() {
                     return config.getSleepTimeMs();
                 }
-                
+
                 @Override
                 public boolean isNotificationProcessingOff() {
                     return config.isNotificationProcessingOff();
                 }
-            });
+            }
+            );
         } catch (NotificationQueueAlreadyExists e) {
             throw new RuntimeException(e);
         }
@@ -160,16 +166,16 @@ public class Engine implements EventListener, EntitlementService {
         if (subscriptionEventQueue != null) {
             subscriptionEventQueue.stopQueue();
             notificationQueueService.deleteNotificationQueue(subscriptionEventQueue.getServiceName(), subscriptionEventQueue.getQueueName());
-         }
+        }
     }
-    
+
 
     @Override
     public void processEventReady(final EntitlementEvent event, final int seqId, final CallContext context) {
         if (!event.isActive()) {
             return;
         }
-        SubscriptionData subscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionFactory, event.getSubscriptionId());
+        final SubscriptionData subscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionFactory, event.getSubscriptionId());
         if (subscription == null) {
             log.warn("Failed to retrieve subscription for id %s", event.getSubscriptionId());
             return;
@@ -178,17 +184,17 @@ public class Engine implements EventListener, EntitlementService {
             // Skip repaired events
             return;
         }
-        
+
         //
         // Do any internal processing on that event before we send the event to the bus
         //
-        
+
         int theRealSeqId = seqId;
         if (event.getType() == EventType.PHASE) {
             onPhaseEvent(subscription, context);
         } else if (event.getType() == EventType.API_USER &&
                 subscription.getCategory() == ProductCategory.BASE) {
-        	theRealSeqId = onBasePlanEvent(subscription, (ApiEvent) event, context);
+            theRealSeqId = onBasePlanEvent(subscription, (ApiEvent) event, context);
         }
         try {
             eventBus.post(subscription.getTransitionFromEvent(event, theRealSeqId));
@@ -198,48 +204,48 @@ public class Engine implements EventListener, EntitlementService {
     }
 
 
-    private void onPhaseEvent(SubscriptionData subscription, CallContext context) {
+    private void onPhaseEvent(final SubscriptionData subscription, final CallContext context) {
         try {
-            DateTime now = clock.getUTCNow();
-            TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, now, now);
-            PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
+            final DateTime now = clock.getUTCNow();
+            final TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, now, now);
+            final PhaseEvent nextPhaseEvent = (nextTimedPhase != null) ?
                     PhaseEventData.createNextPhaseEvent(nextTimedPhase.getPhase().getName(), subscription, now, nextTimedPhase.getStartPhase()) :
                         null;
-            if (nextPhaseEvent != null) {
-                dao.createNextPhaseEvent(subscription.getId(), nextPhaseEvent, context);
-            }
+                    if (nextPhaseEvent != null) {
+                        dao.createNextPhaseEvent(subscription.getId(), nextPhaseEvent, context);
+                    }
         } catch (EntitlementError e) {
             log.error(String.format("Failed to insert next phase for subscription %s", subscription.getId()), e);
         }
     }
 
-    private int onBasePlanEvent(SubscriptionData baseSubscription, ApiEvent event, CallContext context) {
+    private int onBasePlanEvent(final SubscriptionData baseSubscription, final ApiEvent event, final CallContext context) {
 
-        DateTime now = clock.getUTCNow();
+        final DateTime now = clock.getUTCNow();
 
-        Product baseProduct = (baseSubscription.getState() == SubscriptionState.CANCELLED ) ?
+        final Product baseProduct = (baseSubscription.getState() == SubscriptionState.CANCELLED) ?
                 null : baseSubscription.getCurrentPlan().getProduct();
 
-        List<Subscription> subscriptions = dao.getSubscriptions(subscriptionFactory, baseSubscription.getBundleId());
+        final List<Subscription> subscriptions = dao.getSubscriptions(subscriptionFactory, baseSubscription.getBundleId());
+
 
-        
-        Map<UUID, EntitlementEvent> addOnCancellations = new HashMap<UUID, EntitlementEvent>();
-        
-        Iterator<Subscription> it = subscriptions.iterator();
+        final Map<UUID, EntitlementEvent> addOnCancellations = new HashMap<UUID, EntitlementEvent>();
+
+        final Iterator<Subscription> it = subscriptions.iterator();
         while (it.hasNext()) {
-            SubscriptionData cur = (SubscriptionData) it.next();
+            final SubscriptionData cur = (SubscriptionData) it.next();
             if (cur.getState() == SubscriptionState.CANCELLED ||
                     cur.getCategory() != ProductCategory.ADD_ON) {
                 continue;
             }
-            Plan addonCurrentPlan = cur.getCurrentPlan();
+            final Plan addonCurrentPlan = cur.getCurrentPlan();
             if (baseProduct == null ||
                     addonUtils.isAddonIncluded(baseProduct, addonCurrentPlan) ||
-                    ! addonUtils.isAddonAvailable(baseProduct, addonCurrentPlan)) {
+                    !addonUtils.isAddonAvailable(baseProduct, addonCurrentPlan)) {
                 //
                 // Perform AO cancellation using the effectiveDate of the BP
                 //
-                EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
+                final EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
                 .setSubscriptionId(cur.getId())
                 .setActiveVersion(cur.getActiveVersion())
                 .setProcessedDate(now)
@@ -247,7 +253,7 @@ public class Engine implements EventListener, EntitlementService {
                 .setRequestedDate(now)
                 .setUserToken(context.getUserToken())
                 .setFromDisk(true));
-                
+
                 addOnCancellations.put(cur.getId(), cancelEvent);
             }
         }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java
index a4d19b0..1327a72 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java
@@ -16,76 +16,75 @@
 package com.ning.billing.entitlement.engine.core;
 
 import java.util.UUID;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.util.notificationq.NotificationKey;
 
 public class EntitlementNotificationKey implements NotificationKey {
 
-	private static final String DELIMITER = ":";
-	
-	private final UUID eventId;
-	private final int seqId;
-	
-	public EntitlementNotificationKey(final UUID eventId, int seqId) {
-		this.eventId = eventId;
-		this.seqId = seqId;
-	}
+    private final UUID eventId;
+    private final int seqId;
+
+    
+    @JsonCreator
+    public EntitlementNotificationKey(@JsonProperty("eventId") final UUID eventId,
+            @JsonProperty("seqId") final int seqId) {
+        this.eventId = eventId;
+        this.seqId = seqId;
+    }
+
+    public EntitlementNotificationKey(final UUID eventId) {
+        this(eventId, 0);
+    }
 
-	public EntitlementNotificationKey(final UUID eventId) {
-		this(eventId, 0);
-	}
-	
-	public EntitlementNotificationKey(final String input) {
-			
-		String [] parts = input.split(DELIMITER);
-		eventId = UUID.fromString(parts[0]);
-		if (parts.length == 2) {
-			seqId = Integer.valueOf(parts[1]);
-		} else {
-			seqId = 0;
-		}
-	}
-	
-	public UUID getEventId() {
-		return eventId;
-	}
+    public UUID getEventId() {
+        return eventId;
+    }
 
-	public int getSeqId() {
-		return seqId;
-	}
+    public int getSeqId() {
+        return seqId;
+    }
 
-	public String toString() {
-		if (seqId == 0) {
-			return eventId.toString();
-		} else {
-			return eventId.toString() + ":" + seqId;
-		}
-	}
+    public String toString() {
+        if (seqId == 0) {
+            return eventId.toString();
+        } else {
+            return eventId.toString() + ":" + seqId;
+        }
+    }
 
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((eventId == null) ? 0 : eventId.hashCode());
-		result = prime * result + seqId;
-		return result;
-	}
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((eventId == null) ? 0 : eventId.hashCode());
+        result = prime * result + seqId;
+        return result;
+    }
 
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		EntitlementNotificationKey other = (EntitlementNotificationKey) obj;
-		if (eventId == null) {
-			if (other.eventId != null)
-				return false;
-		} else if (!eventId.equals(other.eventId))
-			return false;
-		if (seqId != other.seqId)
-			return false;
-		return true;
-	}
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final EntitlementNotificationKey other = (EntitlementNotificationKey) obj;
+        if (eventId == null) {
+            if (other.eventId != null) {
+                return false;
+            }
+        } else if (!eventId.equals(other.eventId)) {
+            return false;
+        }
+        if (seqId != other.seqId) {
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
index b6a2f01..38bf0ca 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/AuditedEntitlementDao.java
@@ -16,6 +16,9 @@
 
 package com.ning.billing.entitlement.engine.dao;
 
+import javax.annotation.Nullable;
+
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -25,7 +28,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
-import javax.annotation.Nullable;
 
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.IDBI;
@@ -48,11 +50,11 @@ import com.ning.billing.entitlement.api.migration.AccountMigrationData.Subscript
 import com.ning.billing.entitlement.api.timeline.DefaultRepairEntitlementEvent;
 import com.ning.billing.entitlement.api.timeline.RepairEntitlementEvent;
 import com.ning.billing.entitlement.api.timeline.SubscriptionDataRepair;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.engine.addon.AddonUtils;
 import com.ning.billing.entitlement.engine.core.Engine;
 import com.ning.billing.entitlement.engine.core.EntitlementNotificationKey;
@@ -77,7 +79,7 @@ import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
 
 public class AuditedEntitlementDao implements EntitlementDao {
-    private final static Logger log = LoggerFactory.getLogger(AuditedEntitlementDao.class);
+    private static final Logger log = LoggerFactory.getLogger(AuditedEntitlementDao.class);
 
     private final Clock clock;
     private final SubscriptionSqlDao subscriptionsDao;
@@ -89,8 +91,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
 
     @Inject
     public AuditedEntitlementDao(final IDBI dbi, final Clock clock,
-                                 final AddonUtils addonUtils, final NotificationQueueService notificationQueueService,
-                                 final Bus eventBus) {
+            final AddonUtils addonUtils, final NotificationQueueService notificationQueueService,
+            final Bus eventBus) {
 
         this.clock = clock;
         this.subscriptionsDao = dbi.onDemand(SubscriptionSqlDao.class);
@@ -121,11 +123,11 @@ public class AuditedEntitlementDao implements EntitlementDao {
     public SubscriptionBundle createSubscriptionBundle(final SubscriptionBundleData bundle, final CallContext context) {
         return bundlesDao.inTransaction(new Transaction<SubscriptionBundle, BundleSqlDao>() {
             @Override
-            public SubscriptionBundle inTransaction(BundleSqlDao transactional, TransactionStatus status) {
+            public SubscriptionBundle inTransaction(final BundleSqlDao transactional, final TransactionStatus status) {
                 bundlesDao.insertBundle(bundle, context);
-                Long recordId = bundlesDao.getRecordId(bundle.getId().toString());
+                final Long recordId = bundlesDao.getRecordId(bundle.getId().toString());
 
-                EntityAudit audit = new EntityAudit(TableName.BUNDLES, recordId, ChangeType.INSERT);
+                final EntityAudit audit = new EntityAudit(TableName.BUNDLES, recordId, ChangeType.INSERT);
                 bundlesDao.insertAuditFromTransaction(audit, context);
 
                 return bundle;
@@ -135,19 +137,19 @@ public class AuditedEntitlementDao implements EntitlementDao {
 
     @Override
     public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) {
-        Subscription subscription = subscriptionsDao.getSubscriptionFromId(subscriptionId.toString());
+        final Subscription subscription = subscriptionsDao.getSubscriptionFromId(subscriptionId.toString());
         if (subscription == null) {
             log.error(String.format(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getFormat(), subscriptionId.toString()));
             return null;
         }
 
-        UUID bundleId = subscription.getBundleId();
+        final UUID bundleId = subscription.getBundleId();
         if (bundleId == null) {
             log.error(String.format(ErrorCode.ENT_GET_NO_BUNDLE_FOR_SUBSCRIPTION.getFormat(), subscriptionId.toString()));
             return null;
         }
 
-        SubscriptionBundle bundle = bundlesDao.getBundleFromId(bundleId.toString());
+        final SubscriptionBundle bundle = bundlesDao.getBundleFromId(bundleId.toString());
         if (bundle == null) {
             log.error(String.format(ErrorCode.ENT_GET_INVALID_BUNDLE_ID.getFormat(), bundleId.toString()));
             return null;
@@ -173,7 +175,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
 
     @Override
     public List<Subscription> getSubscriptionsForKey(final SubscriptionFactory factory, final String bundleKey) {
-        SubscriptionBundle bundle =  bundlesDao.getBundleFromKey(bundleKey);
+        final SubscriptionBundle bundle = bundlesDao.getBundleFromKey(bundleKey);
         if (bundle == null) {
             return Collections.emptyList();
         }
@@ -183,24 +185,24 @@ public class AuditedEntitlementDao implements EntitlementDao {
     @Override
     public void updateChargedThroughDate(final SubscriptionData subscription, final CallContext context) {
 
-        final Date ctd = (subscription.getChargedThroughDate() != null)  ? subscription.getChargedThroughDate().toDate() : null;
+        final Date ctd = (subscription.getChargedThroughDate() != null) ? subscription.getChargedThroughDate().toDate() : null;
 
         subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
             @Override
-            public Void inTransaction(SubscriptionSqlDao transactionalDao,
-                    TransactionStatus status) throws Exception {
-                String subscriptionId = subscription.getId().toString();
+            public Void inTransaction(final SubscriptionSqlDao transactionalDao,
+                    final TransactionStatus status) throws Exception {
+                final String subscriptionId = subscription.getId().toString();
                 transactionalDao.updateChargedThroughDate(subscription.getId().toString(), ctd, context);
-                Long subscriptionRecordId = transactionalDao.getRecordId(subscriptionId);
-                EntityAudit subscriptionAudit = new EntityAudit(TableName.SUBSCRIPTIONS, subscriptionRecordId, ChangeType.UPDATE);
+                final Long subscriptionRecordId = transactionalDao.getRecordId(subscriptionId);
+                final EntityAudit subscriptionAudit = new EntityAudit(TableName.SUBSCRIPTIONS, subscriptionRecordId, ChangeType.UPDATE);
                 transactionalDao.insertAuditFromTransaction(subscriptionAudit, context);
 
-                BundleSqlDao bundleSqlDao = transactionalDao.become(BundleSqlDao.class);
-                String bundleId = subscription.getBundleId().toString();
+                final BundleSqlDao bundleSqlDao = transactionalDao.become(BundleSqlDao.class);
+                final String bundleId = subscription.getBundleId().toString();
                 bundleSqlDao.updateBundleLastSysTime(bundleId, clock.getUTCNow().toDate());
                 // SubscriptionBundle bundle = bundleSqlDao.getById(bundleId);
-                Long recordId = bundleSqlDao.getRecordId(bundleId);
-                EntityAudit bundleAudit = new EntityAudit(TableName.BUNDLES, recordId, ChangeType.UPDATE);
+                final Long recordId = bundleSqlDao.getRecordId(bundleId);
+                final EntityAudit bundleAudit = new EntityAudit(TableName.BUNDLES, recordId, ChangeType.UPDATE);
                 bundleSqlDao.insertAuditFromTransaction(bundleAudit, context);
                 return null;
             }
@@ -211,12 +213,12 @@ public class AuditedEntitlementDao implements EntitlementDao {
     public void createNextPhaseEvent(final UUID subscriptionId, final EntitlementEvent nextPhase, final CallContext context) {
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
-            public Void inTransaction(EntitlementEventSqlDao transactional, TransactionStatus status) throws Exception {
+            public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
                 cancelNextPhaseEventFromTransaction(subscriptionId, transactional, context);
                 transactional.insertEvent(nextPhase, context);
 
-                Long recordId = transactional.getRecordId(nextPhase.getId().toString());
-                EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT);
+                final Long recordId = transactional.getRecordId(nextPhase.getId().toString());
+                final EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT);
                 transactional.insertAuditFromTransaction(audit, context);
 
                 recordFutureNotificationFromTransaction(transactional,
@@ -228,12 +230,12 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public EntitlementEvent getEventById(UUID eventId) {
+    public EntitlementEvent getEventById(final UUID eventId) {
         return eventsDao.getEventById(eventId.toString());
     }
 
     @Override
-    public List<EntitlementEvent> getEventsForSubscription(UUID subscriptionId) {
+    public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId) {
         return eventsDao.getEventsForSubscription(subscriptionId.toString());
     }
 
@@ -241,16 +243,16 @@ public class AuditedEntitlementDao implements EntitlementDao {
     public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId) {
         return subscriptionsDao.inTransaction(new Transaction<Map<UUID, List<EntitlementEvent>>, SubscriptionSqlDao>() {
             @Override
-            public Map<UUID, List<EntitlementEvent>> inTransaction(SubscriptionSqlDao transactional,
-                    TransactionStatus status) throws Exception {
-                List<Subscription> subscriptions = transactional.getSubscriptionsFromBundleId(bundleId.toString());
+            public Map<UUID, List<EntitlementEvent>> inTransaction(final SubscriptionSqlDao transactional,
+                    final TransactionStatus status) throws Exception {
+                final List<Subscription> subscriptions = transactional.getSubscriptionsFromBundleId(bundleId.toString());
                 if (subscriptions.size() == 0) {
                     return Collections.emptyMap();
                 }
-                EntitlementEventSqlDao eventsDaoFromSameTransaction = transactional.become(EntitlementEventSqlDao.class);
-                Map<UUID, List<EntitlementEvent>> result = new HashMap<UUID, List<EntitlementEvent>>();
-                for (Subscription cur : subscriptions) {
-                    List<EntitlementEvent> events = eventsDaoFromSameTransaction.getEventsForSubscription(cur.getId().toString());
+                final EntitlementEventSqlDao eventsDaoFromSameTransaction = transactional.become(EntitlementEventSqlDao.class);
+                final Map<UUID, List<EntitlementEvent>> result = new HashMap<UUID, List<EntitlementEvent>>();
+                for (final Subscription cur : subscriptions) {
+                    final List<EntitlementEvent> events = eventsDaoFromSameTransaction.getEventsForSubscription(cur.getId().toString());
                     result.put(cur.getId(), events);
                 }
                 return result;
@@ -259,8 +261,8 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public List<EntitlementEvent> getPendingEventsForSubscription(UUID subscriptionId) {
-        Date now = clock.getUTCNow().toDate();
+    public List<EntitlementEvent> getPendingEventsForSubscription(final UUID subscriptionId) {
+        final Date now = clock.getUTCNow().toDate();
         return eventsDao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
     }
 
@@ -271,21 +273,21 @@ public class AuditedEntitlementDao implements EntitlementDao {
         subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
 
             @Override
-            public Void inTransaction(SubscriptionSqlDao transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final SubscriptionSqlDao transactional,
+                    final TransactionStatus status) throws Exception {
 
                 transactional.insertSubscription(subscription, context);
-                Long subscriptionRecordId = transactional.getRecordId(subscription.getId().toString());
-                EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTIONS, subscriptionRecordId, ChangeType.INSERT);
+                final Long subscriptionRecordId = transactional.getRecordId(subscription.getId().toString());
+                final EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTIONS, subscriptionRecordId, ChangeType.INSERT);
                 transactional.insertAuditFromTransaction(audit, context);
 
                 // STEPH batch as well
-                EntitlementEventSqlDao eventsDaoFromSameTransaction = transactional.become(EntitlementEventSqlDao.class);
-                List<EntityAudit> audits = new ArrayList<EntityAudit>();
+                final EntitlementEventSqlDao eventsDaoFromSameTransaction = transactional.become(EntitlementEventSqlDao.class);
+                final List<EntityAudit> audits = new ArrayList<EntityAudit>();
 
                 for (final EntitlementEvent cur : initialEvents) {
                     eventsDaoFromSameTransaction.insertEvent(cur, context);
-                    Long recordId = eventsDaoFromSameTransaction.getRecordId(cur.getId().toString());
+                    final Long recordId = eventsDaoFromSameTransaction.getRecordId(cur.getId().toString());
                     audits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
                     recordFutureNotificationFromTransaction(transactional,
                             cur.getEffectiveDate(),
@@ -304,13 +306,13 @@ public class AuditedEntitlementDao implements EntitlementDao {
 
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
-            public Void inTransaction(EntitlementEventSqlDao transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final EntitlementEventSqlDao transactional,
+                    final TransactionStatus status) throws Exception {
 
-                List<EntityAudit> audits = new ArrayList<EntityAudit>();
+                final List<EntityAudit> audits = new ArrayList<EntityAudit>();
                 for (final EntitlementEvent cur : recreateEvents) {
                     transactional.insertEvent(cur, context);
-                    Long recordId = transactional.getRecordId(cur.getId().toString());
+                    final Long recordId = transactional.getRecordId(cur.getId().toString());
                     audits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
                     recordFutureNotificationFromTransaction(transactional,
                             cur.getEffectiveDate(),
@@ -329,16 +331,16 @@ public class AuditedEntitlementDao implements EntitlementDao {
 
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
-            public Void inTransaction(EntitlementEventSqlDao transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final EntitlementEventSqlDao transactional,
+                    final TransactionStatus status) throws Exception {
                 cancelNextCancelEventFromTransaction(subscriptionId, transactional, context);
                 cancelNextChangeEventFromTransaction(subscriptionId, transactional, context);
                 cancelNextPhaseEventFromTransaction(subscriptionId, transactional, context);
                 transactional.insertEvent(cancelEvent, context);
-                String cancelEventId = cancelEvent.getId().toString();
+                final String cancelEventId = cancelEvent.getId().toString();
 
-                Long recordId = transactional.getRecordId(cancelEventId);
-                EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT);
+                final Long recordId = transactional.getRecordId(cancelEventId);
+                final EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT);
                 transactional.insertAuditFromTransaction(audit, context);
 
                 recordFutureNotificationFromTransaction(transactional,
@@ -355,14 +357,14 @@ public class AuditedEntitlementDao implements EntitlementDao {
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
 
             @Override
-            public Void inTransaction(EntitlementEventSqlDao transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final EntitlementEventSqlDao transactional,
+                    final TransactionStatus status) throws Exception {
 
                 EntitlementEvent cancelledEvent = null;
-                Date now = clock.getUTCNow().toDate();
-                List<EntitlementEvent> events = transactional.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
+                final Date now = clock.getUTCNow().toDate();
+                final List<EntitlementEvent> events = transactional.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
 
-                for (EntitlementEvent cur : events) {
+                for (final EntitlementEvent cur : events) {
                     if (cur.getType() == EventType.API_USER && ((ApiEvent) cur).getEventType() == ApiEventType.CANCEL) {
                         if (cancelledEvent != null) {
                             throw new EntitlementError(String.format("Found multiple cancel active events for subscriptions %s", subscriptionId.toString()));
@@ -372,16 +374,16 @@ public class AuditedEntitlementDao implements EntitlementDao {
                 }
 
                 if (cancelledEvent != null) {
-                    List<EntityAudit> eventAudits = new ArrayList<EntityAudit>();
+                    final List<EntityAudit> eventAudits = new ArrayList<EntityAudit>();
 
-                    String cancelledEventId = cancelledEvent.getId().toString();
+                    final String cancelledEventId = cancelledEvent.getId().toString();
                     transactional.unactiveEvent(cancelledEventId, context);
-                    Long cancelledRecordId = transactional.getRecordId(cancelledEventId);
+                    final Long cancelledRecordId = transactional.getRecordId(cancelledEventId);
                     eventAudits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, cancelledRecordId, ChangeType.UPDATE));
 
                     for (final EntitlementEvent cur : uncancelEvents) {
                         transactional.insertEvent(cur, context);
-                        Long recordId = transactional.getRecordId(cur.getId().toString());
+                        final Long recordId = transactional.getRecordId(cur.getId().toString());
                         eventAudits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
                         recordFutureNotificationFromTransaction(transactional,
                                 cur.getEffectiveDate(),
@@ -399,14 +401,14 @@ public class AuditedEntitlementDao implements EntitlementDao {
     public void changePlan(final UUID subscriptionId, final List<EntitlementEvent> changeEvents, final CallContext context) {
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
             @Override
-            public Void inTransaction(EntitlementEventSqlDao transactional, TransactionStatus status) throws Exception {
+            public Void inTransaction(final EntitlementEventSqlDao transactional, final TransactionStatus status) throws Exception {
                 cancelNextChangeEventFromTransaction(subscriptionId, transactional, context);
                 cancelNextPhaseEventFromTransaction(subscriptionId, transactional, context);
 
-                List<EntityAudit> eventAudits = new ArrayList<EntityAudit>();
+                final List<EntityAudit> eventAudits = new ArrayList<EntityAudit>();
                 for (final EntitlementEvent cur : changeEvents) {
                     transactional.insertEvent(cur, context);
-                    Long recordId = transactional.getRecordId(cur.getId().toString());
+                    final Long recordId = transactional.getRecordId(cur.getId().toString());
                     eventAudits.add(new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.INSERT));
 
                     recordFutureNotificationFromTransaction(transactional,
@@ -437,11 +439,11 @@ public class AuditedEntitlementDao implements EntitlementDao {
             final CallContext context) {
 
         EntitlementEvent futureEvent = null;
-        Date now = clock.getUTCNow().toDate();
-        List<EntitlementEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
-        for (EntitlementEvent cur : events) {
+        final Date now = clock.getUTCNow().toDate();
+        final List<EntitlementEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
+        for (final EntitlementEvent cur : events) {
             if (cur.getType() == type &&
-                    (apiType == null || apiType == ((ApiEvent) cur).getEventType() )) {
+                    (apiType == null || apiType == ((ApiEvent) cur).getEventType())) {
                 if (futureEvent != null) {
                     throw new EntitlementError(
                             String.format("Found multiple future events for type %s for subscriptions %s",
@@ -452,10 +454,10 @@ public class AuditedEntitlementDao implements EntitlementDao {
         }
 
         if (futureEvent != null) {
-            String eventId = futureEvent.getId().toString();
+            final String eventId = futureEvent.getId().toString();
             dao.unactiveEvent(eventId, context);
-            Long recordId = dao.getRecordId(eventId);
-            EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.UPDATE);
+            final Long recordId = dao.getRecordId(eventId);
+            final EntityAudit audit = new EntityAudit(TableName.SUBSCRIPTION_EVENTS, recordId, ChangeType.UPDATE);
             dao.insertAuditFromTransaction(audit, context);
         }
     }
@@ -464,16 +466,16 @@ public class AuditedEntitlementDao implements EntitlementDao {
         if (input == null) {
             return null;
         }
-        List<Subscription> bundleInput = new ArrayList<Subscription>();
+        final List<Subscription> bundleInput = new ArrayList<Subscription>();
         if (input.getCategory() == ProductCategory.ADD_ON) {
-            Subscription baseSubscription = getBaseSubscription(factory, input.getBundleId(), false);
+            final Subscription baseSubscription = getBaseSubscription(factory, input.getBundleId(), false);
             bundleInput.add(baseSubscription);
             bundleInput.add(input);
         } else {
             bundleInput.add(input);
         }
-        List<Subscription> reloadedSubscriptions = buildBundleSubscriptions(factory, bundleInput);
-        for (Subscription cur : reloadedSubscriptions) {
+        final List<Subscription> reloadedSubscriptions = buildBundleSubscriptions(factory, bundleInput);
+        for (final Subscription cur : reloadedSubscriptions) {
             if (cur.getId().equals(input.getId())) {
                 return cur;
             }
@@ -482,10 +484,13 @@ public class AuditedEntitlementDao implements EntitlementDao {
     }
 
     private List<Subscription> buildBundleSubscriptions(final SubscriptionFactory factory, final List<Subscription> input) {
+        if (input == null || input.size() == 0) {
+            return Collections.emptyList();
+        }
         // Make sure BasePlan -- if exists-- is first
         Collections.sort(input, new Comparator<Subscription>() {
             @Override
-            public int compare(Subscription o1, Subscription o2) {
+            public int compare(final Subscription o1, final Subscription o2) {
                 if (o1.getCategory() == ProductCategory.BASE) {
                     return -1;
                 } else if (o2.getCategory() == ProductCategory.BASE) {
@@ -497,17 +502,17 @@ public class AuditedEntitlementDao implements EntitlementDao {
         });
 
         EntitlementEvent futureBaseEvent = null;
-        List<Subscription> result = new ArrayList<Subscription>(input.size());
-        for (Subscription cur : input) {
+        final List<Subscription> result = new ArrayList<Subscription>(input.size());
+        for (final Subscription cur : input) {
 
-            List<EntitlementEvent> events = eventsDao.getEventsForSubscription(cur.getId().toString());
+            final List<EntitlementEvent> events = eventsDao.getEventsForSubscription(cur.getId().toString());
             Subscription reloaded = factory.createSubscription(new SubscriptionBuilder((SubscriptionData) cur), events);
 
             switch (cur.getCategory()) {
             case BASE:
-                Collection<EntitlementEvent> futureApiEvents = Collections2.filter(events, new Predicate<EntitlementEvent>() {
+                final Collection<EntitlementEvent> futureApiEvents = Collections2.filter(events, new Predicate<EntitlementEvent>() {
                     @Override
-                    public boolean apply(EntitlementEvent input) {
+                    public boolean apply(final EntitlementEvent input) {
                         return (input.getEffectiveDate().isAfter(clock.getUTCNow()) &&
                                 ((input instanceof ApiEventCancel) || (input instanceof ApiEventChange)));
                     }
@@ -516,18 +521,18 @@ public class AuditedEntitlementDao implements EntitlementDao {
                 break;
 
             case ADD_ON:
-                Plan targetAddOnPlan = reloaded.getCurrentPlan();
-                String baseProductName = (futureBaseEvent instanceof ApiEventChange) ?
+                final Plan targetAddOnPlan = reloaded.getCurrentPlan();
+                final String baseProductName = (futureBaseEvent instanceof ApiEventChange) ?
                         ((ApiEventChange) futureBaseEvent).getEventPlan() : null;
 
-                        boolean createCancelEvent = (futureBaseEvent != null) &&
+                        final boolean createCancelEvent = (futureBaseEvent != null) &&
                         ((futureBaseEvent instanceof ApiEventCancel) ||
-                                ((! addonUtils.isAddonAvailableFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan)) ||
+                                ((!addonUtils.isAddonAvailableFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan)) ||
                                         (addonUtils.isAddonIncludedFromPlanName(baseProductName, futureBaseEvent.getEffectiveDate(), targetAddOnPlan))));
 
                         if (createCancelEvent) {
-                            DateTime now = clock.getUTCNow();
-                            EntitlementEvent addOnCancelEvent = new ApiEventCancel(new ApiEventBuilder()
+                            final DateTime now = clock.getUTCNow();
+                            final EntitlementEvent addOnCancelEvent = new ApiEventCancel(new ApiEventBuilder()
                             .setSubscriptionId(reloaded.getId())
                             .setActiveVersion(((SubscriptionData) reloaded).getActiveVersion())
                             .setProcessedDate(now)
@@ -557,22 +562,22 @@ public class AuditedEntitlementDao implements EntitlementDao {
         eventsDao.inTransaction(new Transaction<Void, EntitlementEventSqlDao>() {
 
             @Override
-            public Void inTransaction(EntitlementEventSqlDao transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final EntitlementEventSqlDao transactional,
+                    final TransactionStatus status) throws Exception {
 
-                SubscriptionSqlDao transSubDao = transactional.become(SubscriptionSqlDao.class);
-                BundleSqlDao transBundleDao = transactional.become(BundleSqlDao.class);
+                final SubscriptionSqlDao transSubDao = transactional.become(SubscriptionSqlDao.class);
+                final BundleSqlDao transBundleDao = transactional.become(BundleSqlDao.class);
 
-                List<EntityAudit> audits = new ArrayList<EntityAudit>();
+                final List<EntityAudit> audits = new ArrayList<EntityAudit>();
 
                 Long recordId;
 
-                for (BundleMigrationData curBundle : accountData.getData()) {
-                    SubscriptionBundleData bundleData = curBundle.getData();
+                for (final BundleMigrationData curBundle : accountData.getData()) {
+                    final SubscriptionBundleData bundleData = curBundle.getData();
 
-                    for (SubscriptionMigrationData curSubscription : curBundle.getSubscriptions()) {
+                    for (final SubscriptionMigrationData curSubscription : curBundle.getSubscriptions()) {
 
-                        SubscriptionData subData = curSubscription.getData();
+                        final SubscriptionData subData = curSubscription.getData();
                         for (final EntitlementEvent curEvent : curSubscription.getInitialEvents()) {
                             transactional.insertEvent(curEvent, context);
                             recordId = transactional.getRecordId(curEvent.getId().toString());
@@ -603,16 +608,16 @@ public class AuditedEntitlementDao implements EntitlementDao {
         subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
 
             @Override
-            public Void inTransaction(SubscriptionSqlDao transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final SubscriptionSqlDao transactional,
+                    final TransactionStatus status) throws Exception {
 
-                EntitlementEventSqlDao transEventDao = transactional.become(EntitlementEventSqlDao.class);
+                final EntitlementEventSqlDao transEventDao = transactional.become(EntitlementEventSqlDao.class);
                 for (final SubscriptionDataRepair cur : inRepair) {
                     transactional.updateForRepair(cur.getId().toString(), cur.getActiveVersion(), cur.getStartDate().toDate(), cur.getBundleStartDate().toDate(), context);
-                    for (EntitlementEvent event : cur.getInitialEvents()) {
+                    for (final EntitlementEvent event : cur.getInitialEvents()) {
                         transEventDao.updateVersion(event.getId().toString(), event.getActiveVersion(), context);
                     }
-                    for (EntitlementEvent event : cur.getNewEvents()) {
+                    for (final EntitlementEvent event : cur.getNewEvents()) {
                         transEventDao.insertEvent(event, context);
                         if (event.getEffectiveDate().isAfter(clock.getUTCNow())) {
                             recordFutureNotificationFromTransaction(transactional,
@@ -622,7 +627,7 @@ public class AuditedEntitlementDao implements EntitlementDao {
                     }
                 }
                 try {
-                    RepairEntitlementEvent busEvent = new DefaultRepairEntitlementEvent(context.getUserToken(), accountId, bundleId, clock.getUTCNow());
+                    final RepairEntitlementEvent busEvent = new DefaultRepairEntitlementEvent(context.getUserToken(), accountId, bundleId, clock.getUTCNow());
                     eventBus.postFromTransaction(busEvent, transactional);
                 } catch (EventBusException e) {
                     log.warn("Failed to post repair entitlement event for bundle " + bundleId, e);
@@ -632,11 +637,11 @@ public class AuditedEntitlementDao implements EntitlementDao {
         });
     }
 
-    private Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, boolean rebuildSubscription) {
-        List<Subscription> subscriptions = subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString());
-        for (Subscription cur : subscriptions) {
+    private Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, final boolean rebuildSubscription) {
+        final List<Subscription> subscriptions = subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString());
+        for (final Subscription cur : subscriptions) {
             if (cur.getCategory() == ProductCategory.BASE) {
-                return  rebuildSubscription ? buildSubscription(factory, cur) : cur;
+                return rebuildSubscription ? buildSubscription(factory, cur) : cur;
             }
         }
         return null;
@@ -644,11 +649,13 @@ public class AuditedEntitlementDao implements EntitlementDao {
 
     private void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime effectiveDate, final NotificationKey notificationKey) {
         try {
-            NotificationQueue subscriptionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
+            final NotificationQueue subscriptionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
                     Engine.NOTIFICATION_QUEUE_NAME);
             subscriptionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, notificationKey);
         } catch (NoSuchNotificationQueue e) {
             throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
         }
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
index b6becbb..3530c28 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/BundleSqlDao.java
@@ -22,8 +22,6 @@ import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.dao.AuditSqlDao;
-import com.ning.billing.util.entity.dao.EntitySqlDao;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
@@ -42,13 +40,15 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.dao.AuditSqlDao;
 import com.ning.billing.util.dao.BinderBase;
 import com.ning.billing.util.dao.MapperBase;
+import com.ning.billing.util.entity.dao.EntitySqlDao;
 
 
 @ExternalizedSqlViaStringTemplate3()
 public interface BundleSqlDao extends Transactional<BundleSqlDao>, EntitySqlDao<SubscriptionBundle>,
-                                      AuditSqlDao, CloseMe, Transmogrifier {
+        AuditSqlDao, CloseMe, Transmogrifier {
 
     @SqlUpdate
     public void insertBundle(@Bind(binder = SubscriptionBundleBinder.class) SubscriptionBundleData bundle,
@@ -56,7 +56,7 @@ public interface BundleSqlDao extends Transactional<BundleSqlDao>, EntitySqlDao<
 
     @SqlUpdate
     public void updateBundleLastSysTime(@Bind("id") String id, @Bind("lastSysUpdateDate") Date lastSysUpdate);
-    
+
     @SqlQuery
     @Mapper(ISubscriptionBundleSqlMapper.class)
     public SubscriptionBundle getBundleFromId(@Bind("id") String id);
@@ -71,7 +71,7 @@ public interface BundleSqlDao extends Transactional<BundleSqlDao>, EntitySqlDao<
 
     public static class SubscriptionBundleBinder extends BinderBase implements Binder<Bind, SubscriptionBundleData> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, SubscriptionBundleData bundle) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final SubscriptionBundleData bundle) {
             stmt.bind("id", bundle.getId().toString());
             stmt.bind("startDate", getDate(bundle.getStartDate()));
             stmt.bind("externalKey", bundle.getKey());
@@ -81,16 +81,16 @@ public interface BundleSqlDao extends Transactional<BundleSqlDao>, EntitySqlDao<
     }
 
     public static class ISubscriptionBundleSqlMapper extends MapperBase implements ResultSetMapper<SubscriptionBundle> {
-        
+
         @Override
-        public SubscriptionBundle map(int arg, ResultSet r,
-                StatementContext ctx) throws SQLException {
-            UUID id = UUID.fromString(r.getString("id"));
-            String key = r.getString("external_key");
-            UUID accountId = UUID.fromString(r.getString("account_id"));
-            DateTime startDate = getDate(r, "start_date");
-            DateTime lastSysUpdateDate = getDate(r, "last_sys_update_date");
-            SubscriptionBundleData bundle = new SubscriptionBundleData(id, key, accountId, startDate, lastSysUpdateDate);
+        public SubscriptionBundle map(final int arg, final ResultSet r,
+                                      final StatementContext ctx) throws SQLException {
+            final UUID id = UUID.fromString(r.getString("id"));
+            final String key = r.getString("external_key");
+            final UUID accountId = UUID.fromString(r.getString("account_id"));
+            final DateTime startDate = getDate(r, "start_date");
+            final DateTime lastSysUpdateDate = getDate(r, "last_sys_update_date");
+            final SubscriptionBundleData bundle = new SubscriptionBundleData(id, key, accountId, startDate, lastSysUpdateDate);
             return bundle;
         }
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
index 97270ba..710391b 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
@@ -20,8 +20,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-import com.ning.billing.util.callcontext.CallContext;
-
 import com.ning.billing.entitlement.api.SubscriptionFactory;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData;
 import com.ning.billing.entitlement.api.timeline.SubscriptionDataRepair;
@@ -30,6 +28,7 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.util.callcontext.CallContext;
 
 public interface EntitlementDao {
     // Bundle apis
@@ -62,7 +61,7 @@ public interface EntitlementDao {
     public EntitlementEvent getEventById(final UUID eventId);
 
     public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId);
-    
+
     public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId);
 
     public List<EntitlementEvent> getPendingEventsForSubscription(final UUID subscriptionId);
@@ -73,7 +72,7 @@ public interface EntitlementDao {
     public void recreateSubscription(final UUID subscriptionId, final List<EntitlementEvent> recreateEvents, final CallContext context);
 
     public void cancelSubscription(final UUID subscriptionId, final EntitlementEvent cancelEvent, final CallContext context, final int cancelSeq);
-    
+
     public void uncancelSubscription(final UUID subscriptionId, final List<EntitlementEvent> uncancelEvents, final CallContext context);
 
     public void changePlan(final UUID subscriptionId, final List<EntitlementEvent> changeEvents, final CallContext context);
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.java
index 124aee1..bc4bd1e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementEventSqlDao.java
@@ -16,20 +16,12 @@
 
 package com.ning.billing.entitlement.engine.dao;
 
-import com.ning.billing.entitlement.events.EntitlementEvent;
-import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
-import com.ning.billing.entitlement.events.EventBaseBuilder;
-import com.ning.billing.entitlement.events.phase.PhaseEvent;
-import com.ning.billing.entitlement.events.phase.PhaseEventBuilder;
-import com.ning.billing.entitlement.events.phase.PhaseEventData;
-import com.ning.billing.entitlement.events.user.*;
-import com.ning.billing.entitlement.exceptions.EntitlementError;
-import com.ning.billing.util.dao.AuditSqlDao;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
-import com.ning.billing.util.dao.BinderBase;
-import com.ning.billing.util.dao.MapperBase;
-import com.ning.billing.util.entity.dao.EntitySqlDao;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
@@ -43,15 +35,34 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
+
+import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
+import com.ning.billing.entitlement.events.EventBaseBuilder;
+import com.ning.billing.entitlement.events.phase.PhaseEvent;
+import com.ning.billing.entitlement.events.phase.PhaseEventBuilder;
+import com.ning.billing.entitlement.events.phase.PhaseEventData;
+import com.ning.billing.entitlement.events.user.ApiEvent;
+import com.ning.billing.entitlement.events.user.ApiEventBuilder;
+import com.ning.billing.entitlement.events.user.ApiEventCancel;
+import com.ning.billing.entitlement.events.user.ApiEventChange;
+import com.ning.billing.entitlement.events.user.ApiEventCreate;
+import com.ning.billing.entitlement.events.user.ApiEventMigrateBilling;
+import com.ning.billing.entitlement.events.user.ApiEventMigrateEntitlement;
+import com.ning.billing.entitlement.events.user.ApiEventReCreate;
+import com.ning.billing.entitlement.events.user.ApiEventType;
+import com.ning.billing.entitlement.events.user.ApiEventUncancel;
+import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.dao.AuditSqlDao;
+import com.ning.billing.util.dao.BinderBase;
+import com.ning.billing.util.dao.MapperBase;
+import com.ning.billing.util.entity.dao.EntitySqlDao;
 
 @ExternalizedSqlViaStringTemplate3()
 public interface EntitlementEventSqlDao extends Transactional<EntitlementEventSqlDao>, AuditSqlDao,
-                                                 EntitySqlDao<EntitlementEvent>, CloseMe, Transmogrifier  {
+        EntitySqlDao<EntitlementEvent>, CloseMe, Transmogrifier {
 
     @SqlQuery
     @Mapper(EventSqlMapper.class)
@@ -62,18 +73,18 @@ public interface EntitlementEventSqlDao extends Transactional<EntitlementEventSq
                             @CallContextBinder final CallContext context);
 
     @SqlUpdate
-    public void unactiveEvent(@Bind("id")String id,
+    public void unactiveEvent(@Bind("id") String id,
                               @CallContextBinder final CallContext context);
 
     @SqlUpdate
-    public void reactiveEvent(@Bind("id")String id,
+    public void reactiveEvent(@Bind("id") String id,
                               @CallContextBinder final CallContext context);
 
     @SqlUpdate
-    public void updateVersion(@Bind("id")String id,
+    public void updateVersion(@Bind("id") String id,
                               @Bind("currentVersion") Long currentVersion,
                               @CallContextBinder final CallContext context);
-    
+
     @SqlQuery
     @Mapper(EventSqlMapper.class)
     public List<EntitlementEvent> getFutureActiveEventForSubscription(@Bind("subscriptionId") String subscriptionId, @Bind("now") Date now);
@@ -84,21 +95,21 @@ public interface EntitlementEventSqlDao extends Transactional<EntitlementEventSq
 
     public static class EventSqlDaoBinder extends BinderBase implements Binder<Bind, EntitlementEvent> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, EntitlementEvent evt) {
-        	
-        	String planName = null;
-        	String phaseName = null;
-        	String priceListName = null;
-        	String userType = null;
-        	if (evt.getType() == EventType.API_USER) {
-        		ApiEvent userEvent = (ApiEvent) evt;
-            	planName = userEvent.getEventPlan();
-            	phaseName = userEvent.getEventPlanPhase();
-            	priceListName = userEvent.getPriceList();
-            	userType = userEvent.getEventType().toString();
-        	} else {
-        		phaseName = ((PhaseEvent) evt).getPhase();
-        	}
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final EntitlementEvent evt) {
+
+            String planName = null;
+            String phaseName = null;
+            String priceListName = null;
+            String userType = null;
+            if (evt.getType() == EventType.API_USER) {
+                final ApiEvent userEvent = (ApiEvent) evt;
+                planName = userEvent.getEventPlan();
+                phaseName = userEvent.getEventPlanPhase();
+                priceListName = userEvent.getPriceList();
+                userType = userEvent.getEventType().toString();
+            } else {
+                phaseName = ((PhaseEvent) evt).getPhase();
+            }
             stmt.bind("id", evt.getId().toString());
             stmt.bind("eventType", evt.getType().toString());
             stmt.bind("userType", userType);
@@ -115,47 +126,47 @@ public interface EntitlementEventSqlDao extends Transactional<EntitlementEventSq
 
     public static class EventSqlMapper extends MapperBase implements ResultSetMapper<EntitlementEvent> {
         @Override
-        public EntitlementEvent map(int index, ResultSet r, StatementContext ctx)
-        throws SQLException {
-
-            long totalOrdering = r.getLong("record_id");
-            UUID id = UUID.fromString(r.getString("id"));
-            EventType eventType = EventType.valueOf(r.getString("event_type"));
-            ApiEventType userType = (eventType == EventType.API_USER) ? ApiEventType.valueOf(r.getString("user_type")) : null;
-            DateTime createdDate = getDate(r, "created_date");
-            DateTime requestedDate = getDate(r, "requested_date");
-            DateTime effectiveDate = getDate(r, "effective_date");
-            UUID subscriptionId = UUID.fromString(r.getString("subscription_id"));
-            String planName = r.getString("plan_name");
-            String phaseName = r.getString("phase_name");
-            String priceListName = r.getString("price_list_name");
-            long currentVersion = r.getLong("current_version");
-            boolean isActive = r.getBoolean("is_active");
-            UUID userToken = r.getString("user_token") != null ? UUID.fromString(r.getString("user_token")) : null;
-            
-            EventBaseBuilder<?> base = ((eventType == EventType.PHASE) ?
+        public EntitlementEvent map(final int index, final ResultSet r, final StatementContext ctx)
+                throws SQLException {
+
+            final long totalOrdering = r.getLong("record_id");
+            final UUID id = UUID.fromString(r.getString("id"));
+            final EventType eventType = EventType.valueOf(r.getString("event_type"));
+            final ApiEventType userType = (eventType == EventType.API_USER) ? ApiEventType.valueOf(r.getString("user_type")) : null;
+            final DateTime createdDate = getDate(r, "created_date");
+            final DateTime requestedDate = getDate(r, "requested_date");
+            final DateTime effectiveDate = getDate(r, "effective_date");
+            final UUID subscriptionId = UUID.fromString(r.getString("subscription_id"));
+            final String planName = r.getString("plan_name");
+            final String phaseName = r.getString("phase_name");
+            final String priceListName = r.getString("price_list_name");
+            final long currentVersion = r.getLong("current_version");
+            final boolean isActive = r.getBoolean("is_active");
+            final UUID userToken = r.getString("user_token") != null ? UUID.fromString(r.getString("user_token")) : null;
+
+            final EventBaseBuilder<?> base = ((eventType == EventType.PHASE) ?
                     new PhaseEventBuilder() :
-                        new ApiEventBuilder())
-                        .setTotalOrdering(totalOrdering)
-                        .setUuid(id)
-                        .setSubscriptionId(subscriptionId)
-                        .setRequestedDate(requestedDate)
-                        .setEffectiveDate(effectiveDate)
-                        .setProcessedDate(createdDate)
-                        .setActiveVersion(currentVersion)
-                        .setActive(isActive);
+                    new ApiEventBuilder())
+                    .setTotalOrdering(totalOrdering)
+                    .setUuid(id)
+                    .setSubscriptionId(subscriptionId)
+                    .setRequestedDate(requestedDate)
+                    .setEffectiveDate(effectiveDate)
+                    .setProcessedDate(createdDate)
+                    .setActiveVersion(currentVersion)
+                    .setActive(isActive);
 
             EntitlementEvent result = null;
             if (eventType == EventType.PHASE) {
                 result = new PhaseEventData(new PhaseEventBuilder(base).setPhaseName(phaseName));
             } else if (eventType == EventType.API_USER) {
-                ApiEventBuilder builder = new ApiEventBuilder(base)
-                    .setEventPlan(planName)
-                    .setEventPlanPhase(phaseName)
-                    .setEventPriceList(priceListName)
-                    .setEventType(userType)
-                    .setUserToken(userToken)
-                    .setFromDisk(true);
+                final ApiEventBuilder builder = new ApiEventBuilder(base)
+                        .setEventPlan(planName)
+                        .setEventPlanPhase(phaseName)
+                        .setEventPriceList(priceListName)
+                        .setEventType(userType)
+                        .setUserToken(userToken)
+                        .setFromDisk(true);
 
                 if (userType == ApiEventType.CREATE) {
                     result = new ApiEventCreate(builder);
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
index b2a10ac..d6f3fe9 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
@@ -40,15 +40,15 @@ import com.ning.billing.util.callcontext.CallContext;
 public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLifecycleDao {
 
     private final ThreadLocal<Map<UUID, SubscriptionRepairEvent>> preThreadsInRepairSubscriptions = new ThreadLocal<Map<UUID, SubscriptionRepairEvent>>();
-    
-    private final static class SubscriptionRepairEvent {
-        
+
+    private static final class SubscriptionRepairEvent {
+
         private final Set<EntitlementEvent> events;
-        
-        public SubscriptionRepairEvent(List<EntitlementEvent> initialEvents) {
+
+        public SubscriptionRepairEvent(final List<EntitlementEvent> initialEvents) {
             events = new TreeSet<EntitlementEvent>(new Comparator<EntitlementEvent>() {
                 @Override
-                public int compare(EntitlementEvent o1, EntitlementEvent o2) {
+                public int compare(final EntitlementEvent o1, final EntitlementEvent o2) {
                     return o1.compareTo(o2);
                 }
             });
@@ -56,74 +56,74 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
                 events.addAll(initialEvents);
             }
         }
-        
+
         public Set<EntitlementEvent> getEvents() {
             return events;
         }
-        
-        public void addEvents(List<EntitlementEvent> newEvents) {
+
+        public void addEvents(final List<EntitlementEvent> newEvents) {
             events.addAll(newEvents);
         }
     }
-    
+
     private Map<UUID, SubscriptionRepairEvent> getRepairMap() {
         if (preThreadsInRepairSubscriptions.get() == null) {
             preThreadsInRepairSubscriptions.set(new HashMap<UUID, SubscriptionRepairEvent>());
         }
         return preThreadsInRepairSubscriptions.get();
     }
-    
-    private SubscriptionRepairEvent getRepairSubscriptionEvents(UUID subscriptionId) {
-        Map<UUID, SubscriptionRepairEvent> map = getRepairMap();
+
+    private SubscriptionRepairEvent getRepairSubscriptionEvents(final UUID subscriptionId) {
+        final Map<UUID, SubscriptionRepairEvent> map = getRepairMap();
         return map.get(subscriptionId);
     }
-    
+
     @Override
-    public List<EntitlementEvent> getEventsForSubscription(UUID subscriptionId) {
-        SubscriptionRepairEvent target =  getRepairSubscriptionEvents(subscriptionId);
+    public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId) {
+        final SubscriptionRepairEvent target = getRepairSubscriptionEvents(subscriptionId);
         return new LinkedList<EntitlementEvent>(target.getEvents());
     }
 
     @Override
-    public void createSubscription(SubscriptionData subscription,
-            List<EntitlementEvent> createEvents, CallContext context) {
+    public void createSubscription(final SubscriptionData subscription,
+                                   final List<EntitlementEvent> createEvents, final CallContext context) {
         addEvents(subscription.getId(), createEvents);
     }
 
     @Override
-    public void recreateSubscription(UUID subscriptionId,
-            List<EntitlementEvent> recreateEvents, CallContext context) {
+    public void recreateSubscription(final UUID subscriptionId,
+                                     final List<EntitlementEvent> recreateEvents, final CallContext context) {
         addEvents(subscriptionId, recreateEvents);
     }
 
     @Override
-    public void cancelSubscription(UUID subscriptionId,
-            EntitlementEvent cancelEvent, CallContext context, int cancelSeq) {
-        long activeVersion = cancelEvent.getActiveVersion();
+    public void cancelSubscription(final UUID subscriptionId,
+                                   final EntitlementEvent cancelEvent, final CallContext context, final int cancelSeq) {
+        final long activeVersion = cancelEvent.getActiveVersion();
         addEvents(subscriptionId, Collections.singletonList(cancelEvent));
-        SubscriptionRepairEvent target =  getRepairSubscriptionEvents(subscriptionId);
+        final SubscriptionRepairEvent target = getRepairSubscriptionEvents(subscriptionId);
         boolean foundCancelEvent = false;
-        for (EntitlementEvent cur : target.getEvents()) {
+        for (final EntitlementEvent cur : target.getEvents()) {
             if (cur.getId().equals(cancelEvent.getId())) {
                 foundCancelEvent = true;
-            } else if (foundCancelEvent) { 
+            } else if (foundCancelEvent) {
                 cur.setActiveVersion(activeVersion - 1);
             }
         }
     }
 
-    
+
     @Override
-    public void changePlan(UUID subscriptionId,
-            List<EntitlementEvent> changeEvents, CallContext context) {
-        addEvents(subscriptionId, changeEvents);        
+    public void changePlan(final UUID subscriptionId,
+                           final List<EntitlementEvent> changeEvents, final CallContext context) {
+        addEvents(subscriptionId, changeEvents);
     }
 
     @Override
-    public void initializeRepair(UUID subscriptionId, List<EntitlementEvent> initialEvents) {
-        Map<UUID, SubscriptionRepairEvent> map = getRepairMap();
+    public void initializeRepair(final UUID subscriptionId, final List<EntitlementEvent> initialEvents) {
+        final Map<UUID, SubscriptionRepairEvent> map = getRepairMap();
         if (map.get(subscriptionId) == null) {
-            SubscriptionRepairEvent value = new SubscriptionRepairEvent(initialEvents);
+            final SubscriptionRepairEvent value = new SubscriptionRepairEvent(initialEvents);
             map.put(subscriptionId, value);
         } else {
             throw new EntitlementError(String.format("Unexpected SubscriptionRepairEvent %s for thread %s", subscriptionId, Thread.currentThread().getName()));
@@ -132,112 +132,112 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
 
     @Override
     public void cleanup() {
-        Map<UUID, SubscriptionRepairEvent> map = getRepairMap();
+        final Map<UUID, SubscriptionRepairEvent> map = getRepairMap();
         map.clear();
     }
 
-    
-    private void addEvents(UUID subscriptionId, List<EntitlementEvent> events) {
-        SubscriptionRepairEvent target =  getRepairSubscriptionEvents(subscriptionId);
-        target.addEvents(events);        
+
+    private void addEvents(final UUID subscriptionId, final List<EntitlementEvent> events) {
+        final SubscriptionRepairEvent target = getRepairSubscriptionEvents(subscriptionId);
+        target.addEvents(events);
     }
 
-    
+
     @Override
-    public void uncancelSubscription(UUID subscriptionId,
-            List<EntitlementEvent> uncancelEvents, CallContext context) {
-        throw new EntitlementError("Not implemented");        
+    public void uncancelSubscription(final UUID subscriptionId,
+                                     final List<EntitlementEvent> uncancelEvents, final CallContext context) {
+        throw new EntitlementError("Not implemented");
     }
-    
+
     @Override
-    public List<SubscriptionBundle> getSubscriptionBundleForAccount(UUID accountId) {
+    public List<SubscriptionBundle> getSubscriptionBundleForAccount(final UUID accountId) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public SubscriptionBundle getSubscriptionBundleFromKey(String bundleKey) {
+    public SubscriptionBundle getSubscriptionBundleFromKey(final String bundleKey) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public SubscriptionBundle getSubscriptionBundleFromId(UUID bundleId) {
+    public SubscriptionBundle getSubscriptionBundleFromId(final UUID bundleId) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
     public SubscriptionBundle createSubscriptionBundle(
-            SubscriptionBundleData bundle, CallContext context) {
+            final SubscriptionBundleData bundle, final CallContext context) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public Subscription getSubscriptionFromId(SubscriptionFactory factory,
-            UUID subscriptionId) {
+    public Subscription getSubscriptionFromId(final SubscriptionFactory factory,
+                                              final UUID subscriptionId) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public UUID getAccountIdFromSubscriptionId(UUID subscriptionId) {
+    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public Subscription getBaseSubscription(SubscriptionFactory factory,
-            UUID bundleId) {
+    public Subscription getBaseSubscription(final SubscriptionFactory factory,
+                                            final UUID bundleId) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public List<Subscription> getSubscriptions(SubscriptionFactory factory,
-            UUID bundleId) {
+    public List<Subscription> getSubscriptions(final SubscriptionFactory factory,
+                                               final UUID bundleId) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
     public List<Subscription> getSubscriptionsForKey(
-            SubscriptionFactory factory, String bundleKey) {
+            final SubscriptionFactory factory, final String bundleKey) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public void updateChargedThroughDate(SubscriptionData subscription,
-            CallContext context) {
+    public void updateChargedThroughDate(final SubscriptionData subscription,
+                                         final CallContext context) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public void createNextPhaseEvent(UUID subscriptionId,
-            EntitlementEvent nextPhase, CallContext context) {
+    public void createNextPhaseEvent(final UUID subscriptionId,
+                                     final EntitlementEvent nextPhase, final CallContext context) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public EntitlementEvent getEventById(UUID eventId) {
+    public EntitlementEvent getEventById(final UUID eventId) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(UUID bundleId) {
+    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId) {
         throw new EntitlementError("Not implemented");
     }
 
 
     @Override
     public List<EntitlementEvent> getPendingEventsForSubscription(
-            UUID subscriptionId) {
+            final UUID subscriptionId) {
         throw new EntitlementError("Not implemented");
     }
 
 
     @Override
-    public void migrate(UUID accountId, AccountMigrationData data,
-            CallContext context) {
+    public void migrate(final UUID accountId, final AccountMigrationData data,
+                        final CallContext context) {
         throw new EntitlementError("Not implemented");
     }
 
     @Override
-    public void repair(UUID accountId, UUID bundleId, List<SubscriptionDataRepair> inRepair,
-            CallContext context) {
+    public void repair(final UUID accountId, final UUID bundleId, final List<SubscriptionDataRepair> inRepair,
+                       final CallContext context) {
         throw new EntitlementError("Not implemented");
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java
index a43117d..07c72c0 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/SubscriptionSqlDao.java
@@ -16,15 +16,12 @@
 
 package com.ning.billing.entitlement.engine.dao;
 
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
-import com.ning.billing.util.dao.AuditSqlDao;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
-import com.ning.billing.util.dao.BinderBase;
-import com.ning.billing.util.dao.MapperBase;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
@@ -39,15 +36,19 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionData;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.dao.AuditSqlDao;
+import com.ning.billing.util.dao.BinderBase;
+import com.ning.billing.util.dao.MapperBase;
 
 @ExternalizedSqlViaStringTemplate3()
 public interface SubscriptionSqlDao extends Transactional<SubscriptionSqlDao>, AuditSqlDao, CloseMe, Transmogrifier {
-	@SqlUpdate
+    @SqlUpdate
     public void insertSubscription(@Bind(binder = SubscriptionBinder.class) SubscriptionData sub,
                                    @CallContextBinder final CallContext context);
 
@@ -61,20 +62,21 @@ public interface SubscriptionSqlDao extends Transactional<SubscriptionSqlDao>, A
 
     @SqlUpdate
     public void updateChargedThroughDate(@Bind("id") String id, @Bind("chargedThroughDate") Date chargedThroughDate,
-                                        @CallContextBinder final CallContext context);
+                                         @CallContextBinder final CallContext context);
+
+    @SqlUpdate
+    void updateActiveVersion(@Bind("id") String id, @Bind("activeVersion") long activeVersion,
+                             @CallContextBinder final CallContext context);
 
-    @SqlUpdate void updateActiveVersion(@Bind("id") String id, @Bind("activeVersion") long activeVersion,
-            @CallContextBinder final CallContext context);
-    
     @SqlUpdate
     public void updateForRepair(@Bind("id") String id, @Bind("activeVersion") long activeVersion,
-            @Bind("startDate") Date startDate,
-            @Bind("bundleStartDate") Date bundleStartDate,
-            @CallContextBinder final CallContext context);
+                                @Bind("startDate") Date startDate,
+                                @Bind("bundleStartDate") Date bundleStartDate,
+                                @CallContextBinder final CallContext context);
 
     public static class SubscriptionBinder extends BinderBase implements Binder<Bind, SubscriptionData> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, SubscriptionData sub) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final SubscriptionData sub) {
             stmt.bind("id", sub.getId().toString());
             stmt.bind("bundleId", sub.getBundleId().toString());
             stmt.bind("category", sub.getCategory().toString());
@@ -88,27 +90,27 @@ public interface SubscriptionSqlDao extends Transactional<SubscriptionSqlDao>, A
 
     public static class SubscriptionMapper extends MapperBase implements ResultSetMapper<SubscriptionData> {
         @Override
-        public SubscriptionData map(int arg0, ResultSet r, StatementContext ctx)
+        public SubscriptionData map(final int arg0, final ResultSet r, final StatementContext ctx)
                 throws SQLException {
 
-            UUID id = UUID.fromString(r.getString("id"));
-            UUID bundleId = UUID.fromString(r.getString("bundle_id"));
-            ProductCategory category = ProductCategory.valueOf(r.getString("category"));
-            DateTime bundleStartDate = getDate(r, "bundle_start_date");
-            DateTime startDate = getDate(r, "start_date");
-            DateTime ctd = getDate(r, "charged_through_date");
-            DateTime ptd = getDate(r, "paid_through_date");
-            long activeVersion = r.getLong("active_version");
+            final UUID id = UUID.fromString(r.getString("id"));
+            final UUID bundleId = UUID.fromString(r.getString("bundle_id"));
+            final ProductCategory category = ProductCategory.valueOf(r.getString("category"));
+            final DateTime bundleStartDate = getDate(r, "bundle_start_date");
+            final DateTime startDate = getDate(r, "start_date");
+            final DateTime ctd = getDate(r, "charged_through_date");
+            final DateTime ptd = getDate(r, "paid_through_date");
+            final long activeVersion = r.getLong("active_version");
 
             return new SubscriptionData(new SubscriptionBuilder()
-            .setId(id)
-            .setBundleId(bundleId)
-            .setCategory(category)
-            .setBundleStartDate(bundleStartDate)
-            .setStartDate(startDate)
-            .setActiveVersion(activeVersion)
-            .setChargedThroughDate(ctd)
-            .setPaidThroughDate(ptd));
+                                                .setId(id)
+                                                .setBundleId(bundleId)
+                                                .setCategory(category)
+                                                .setBundleStartDate(bundleStartDate)
+                                                .setStartDate(startDate)
+                                                .setActiveVersion(activeVersion)
+                                                .setChargedThroughDate(ctd)
+                                                .setPaidThroughDate(ptd));
         }
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/EntitlementEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/EntitlementEvent.java
index 8e7688b..6698dfb 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/EntitlementEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/EntitlementEvent.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.entitlement.events;
 
-import com.ning.billing.util.entity.Entity;
+import java.util.UUID;
+
 import org.joda.time.DateTime;
 
-import java.util.UUID;
+import com.ning.billing.util.entity.Entity;
 
 
 public interface EntitlementEvent extends Comparable<EntitlementEvent>, Entity {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java
index 4afc75d..ed1a0db 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java
@@ -16,10 +16,11 @@
 
 package com.ning.billing.entitlement.events;
 
-import com.ning.billing.entitlement.events.user.ApiEvent;
+import java.util.UUID;
+
 import org.joda.time.DateTime;
 
-import java.util.UUID;
+import com.ning.billing.entitlement.events.user.ApiEvent;
 
 public abstract class EventBase implements EntitlementEvent {
 
@@ -33,7 +34,7 @@ public abstract class EventBase implements EntitlementEvent {
     private long activeVersion;
     private boolean isActive;
 
-    public EventBase(EventBaseBuilder<?> builder) {
+    public EventBase(final EventBaseBuilder<?> builder) {
         this.totalOrdering = builder.getTotalOrdering();
         this.uuid = builder.getUuid();
         this.subscriptionId = builder.getSubscriptionId();
@@ -102,7 +103,7 @@ public abstract class EventBase implements EntitlementEvent {
     }
 
     @Override
-    public void setActiveVersion(long activeVersion) {
+    public void setActiveVersion(final long activeVersion) {
         this.activeVersion = activeVersion;
     }
 
@@ -122,7 +123,6 @@ public abstract class EventBase implements EntitlementEvent {
     }
 
 
-
     //
     // Really used for unit tests only as the sql implementation relies on date first and then event insertion
     //
@@ -133,7 +133,7 @@ public abstract class EventBase implements EntitlementEvent {
     // - If all that is not enough return consistent by random ordering based on UUID
     //
     @Override
-    public int compareTo(EntitlementEvent other) {
+    public int compareTo(final EntitlementEvent other) {
         if (other == null) {
             throw new NullPointerException("IEvent is compared to a null instance");
         }
@@ -161,11 +161,11 @@ public abstract class EventBase implements EntitlementEvent {
 
 
     @Override
-    public boolean equals(Object other) {
-      if (! (other instanceof EntitlementEvent)) {
-          return false;
-      }
-      return (this.compareTo((EntitlementEvent) other) == 0);
+    public boolean equals(final Object other) {
+        if (!(other instanceof EntitlementEvent)) {
+            return false;
+        }
+        return (this.compareTo((EntitlementEvent) other) == 0);
     }
 
     @Override
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java
index aa07385..7d9bb13 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java
@@ -16,10 +16,10 @@
 
 package com.ning.billing.entitlement.events;
 
-import org.joda.time.DateTime;
-
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 @SuppressWarnings("unchecked")
 public class EventBaseBuilder<T extends EventBaseBuilder<T>> {
 
@@ -39,7 +39,7 @@ public class EventBaseBuilder<T extends EventBaseBuilder<T>> {
         this.isActive = true;
     }
 
-    public EventBaseBuilder(EventBaseBuilder<?> copy) {
+    public EventBaseBuilder(final EventBaseBuilder<?> copy) {
         this.uuid = copy.uuid;
         this.subscriptionId = copy.subscriptionId;
         this.requestedDate = copy.requestedDate;
@@ -51,42 +51,42 @@ public class EventBaseBuilder<T extends EventBaseBuilder<T>> {
         this.totalOrdering = copy.totalOrdering;
     }
 
-    public T setTotalOrdering(long totalOrdering) {
+    public T setTotalOrdering(final long totalOrdering) {
         this.totalOrdering = totalOrdering;
         return (T) this;
     }
 
-    public T setUuid(UUID uuid) {
+    public T setUuid(final UUID uuid) {
         this.uuid = uuid;
         return (T) this;
     }
 
-    public T setSubscriptionId(UUID subscriptionId) {
+    public T setSubscriptionId(final UUID subscriptionId) {
         this.subscriptionId = subscriptionId;
         return (T) this;
     }
 
-    public T setRequestedDate(DateTime requestedDate) {
+    public T setRequestedDate(final DateTime requestedDate) {
         this.requestedDate = requestedDate;
         return (T) this;
     }
 
-    public T setEffectiveDate(DateTime effectiveDate) {
+    public T setEffectiveDate(final DateTime effectiveDate) {
         this.effectiveDate = effectiveDate;
         return (T) this;
     }
 
-    public T setProcessedDate(DateTime processedDate) {
+    public T setProcessedDate(final DateTime processedDate) {
         this.processedDate = processedDate;
         return (T) this;
     }
 
-    public T setActiveVersion(long activeVersion) {
+    public T setActiveVersion(final long activeVersion) {
         this.activeVersion = activeVersion;
         return (T) this;
     }
 
-    public T setActive(boolean isActive) {
+    public T setActive(final boolean isActive) {
         this.isActive = isActive;
         return (T) this;
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventBuilder.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventBuilder.java
index 5847970..95b6fcf 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventBuilder.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventBuilder.java
@@ -26,11 +26,11 @@ public class PhaseEventBuilder extends EventBaseBuilder<PhaseEventBuilder> {
         super();
     }
 
-    public PhaseEventBuilder(EventBaseBuilder<?> base) {
+    public PhaseEventBuilder(final EventBaseBuilder<?> base) {
         super(base);
     }
 
-    public PhaseEventBuilder setPhaseName(String phaseName) {
+    public PhaseEventBuilder setPhaseName(final String phaseName) {
         this.phaseName = phaseName;
         return this;
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventData.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventData.java
index 23f7b2b..f26e0f8 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventData.java
@@ -17,16 +17,17 @@
 package com.ning.billing.entitlement.events.phase;
 
 
+import org.joda.time.DateTime;
+
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.events.EventBase;
-import org.joda.time.DateTime;
 
 
 public class PhaseEventData extends EventBase implements PhaseEvent {
 
     private final String phaseName;
 
-    public PhaseEventData(PhaseEventBuilder builder) {
+    public PhaseEventData(final PhaseEventBuilder builder) {
         super(builder);
         this.phaseName = builder.getPhaseName();
     }
@@ -44,8 +45,8 @@ public class PhaseEventData extends EventBase implements PhaseEvent {
     @Override
     public String toString() {
         return "PhaseEvent [getId()= " + getId()
-        		+ ", phaseName=" + phaseName
-        		+ ", getType()=" + getType()
+                + ", phaseName=" + phaseName
+                + ", getType()=" + getType()
                 + ", getPhase()=" + getPhase()
                 + ", getRequestedDate()=" + getRequestedDate()
                 + ", getEffectiveDate()=" + getEffectiveDate()
@@ -55,15 +56,15 @@ public class PhaseEventData extends EventBase implements PhaseEvent {
                 + ", isActive()=" + isActive() + "]\n";
     }
 
-    public static final PhaseEvent createNextPhaseEvent(String phaseName, SubscriptionData subscription, DateTime now, DateTime effectiveDate) {
+    public static PhaseEvent createNextPhaseEvent(final String phaseName, final SubscriptionData subscription, final DateTime now, final DateTime effectiveDate) {
         return (phaseName == null) ?
                 null :
-                    new PhaseEventData(new PhaseEventBuilder()
-                        .setSubscriptionId(subscription.getId())
-                        .setRequestedDate(now)
-                        .setEffectiveDate(effectiveDate)
-                        .setProcessedDate(now)
-                        .setActiveVersion(subscription.getActiveVersion())
-                        .setPhaseName(phaseName));
+                new PhaseEventData(new PhaseEventBuilder()
+                                           .setSubscriptionId(subscription.getId())
+                                           .setRequestedDate(now)
+                                           .setEffectiveDate(effectiveDate)
+                                           .setProcessedDate(now)
+                                           .setActiveVersion(subscription.getActiveVersion())
+                                           .setPhaseName(phaseName));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEvent.java
index 20a6569..9a91b76 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEvent.java
@@ -32,7 +32,7 @@ public interface ApiEvent extends EntitlementEvent {
     public String getPriceList();
 
     public boolean isFromDisk();
-    
+
     public UUID getUserToken();
 
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java
index d2ea706..83c2812 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java
@@ -16,10 +16,10 @@
 
 package com.ning.billing.entitlement.events.user;
 
-import com.ning.billing.entitlement.events.EventBase;
-
 import java.util.UUID;
 
+import com.ning.billing.entitlement.events.EventBase;
+
 public class ApiEventBase extends EventBase implements ApiEvent {
 
     private final ApiEventType eventType;
@@ -30,7 +30,7 @@ public class ApiEventBase extends EventBase implements ApiEvent {
     private final UUID userToken;
     private final boolean fromDisk;
 
-    public ApiEventBase(ApiEventBuilder builder) {
+    public ApiEventBase(final ApiEventBuilder builder) {
         super(builder);
         this.eventType = builder.getEventType();
         this.eventPriceList = builder.getEventPriceList();
@@ -64,11 +64,11 @@ public class ApiEventBase extends EventBase implements ApiEvent {
     public String getPriceList() {
         return eventPriceList;
     }
-    
-	@Override
-	public UUID getUserToken() {
-		return userToken;
-	}
+
+    @Override
+    public UUID getUserToken() {
+        return userToken;
+    }
 
 
     @Override
@@ -80,8 +80,8 @@ public class ApiEventBase extends EventBase implements ApiEvent {
     @Override
     public String toString() {
         return "ApiEventBase [ getId()= " + getId()
-        		+ " eventType=" + eventType
-        		+ ", eventPlan=" + eventPlan
+                + " eventType=" + eventType
+                + ", eventPlan=" + eventPlan
                 + ", eventPlanPhase=" + eventPlanPhase
                 + ", getEventType()=" + getEventType()
                 + ", getEventPlan()=" + getEventPlan()
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBuilder.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBuilder.java
index b6be427..82efd59 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBuilder.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBuilder.java
@@ -34,7 +34,7 @@ public class ApiEventBuilder extends EventBaseBuilder<ApiEventBuilder> {
         super();
     }
 
-    public ApiEventBuilder(EventBaseBuilder<?> base) {
+    public ApiEventBuilder(final EventBaseBuilder<?> base) {
         super(base);
     }
 
@@ -53,42 +53,42 @@ public class ApiEventBuilder extends EventBaseBuilder<ApiEventBuilder> {
     public String getEventPriceList() {
         return eventPriceList;
     }
-    
+
     public UUID getUserToken() {
-    	return userToken;
+        return userToken;
     }
 
     public boolean isFromDisk() {
         return fromDisk;
     }
 
-    public ApiEventBuilder setUserToken(UUID userToken) {
+    public ApiEventBuilder setUserToken(final UUID userToken) {
         this.userToken = userToken;
         return this;
     }
 
-    
-    public ApiEventBuilder setFromDisk(boolean fromDisk) {
+
+    public ApiEventBuilder setFromDisk(final boolean fromDisk) {
         this.fromDisk = fromDisk;
         return this;
     }
 
-    public ApiEventBuilder setEventType(ApiEventType eventType) {
+    public ApiEventBuilder setEventType(final ApiEventType eventType) {
         this.eventType = eventType;
         return this;
     }
 
-    public ApiEventBuilder setEventPlan(String eventPlan) {
+    public ApiEventBuilder setEventPlan(final String eventPlan) {
         this.eventPlan = eventPlan;
         return this;
     }
 
-    public ApiEventBuilder setEventPlanPhase(String eventPlanPhase) {
+    public ApiEventBuilder setEventPlanPhase(final String eventPlanPhase) {
         this.eventPlanPhase = eventPlanPhase;
         return this;
     }
 
-    public ApiEventBuilder setEventPriceList(String eventPriceList) {
+    public ApiEventBuilder setEventPriceList(final String eventPriceList) {
         this.eventPriceList = eventPriceList;
         return this;
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCancel.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCancel.java
index 5df11ba..447adb4 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCancel.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCancel.java
@@ -19,7 +19,7 @@ package com.ning.billing.entitlement.events.user;
 public class ApiEventCancel extends ApiEventBase {
 
 
-    public ApiEventCancel(ApiEventBuilder builder) {
+    public ApiEventCancel(final ApiEventBuilder builder) {
         super(builder.setEventType(ApiEventType.CANCEL));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventChange.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventChange.java
index 3770a2f..8b796c5 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventChange.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventChange.java
@@ -17,10 +17,9 @@
 package com.ning.billing.entitlement.events.user;
 
 
-
 public class ApiEventChange extends ApiEventBase {
 
-    public ApiEventChange(ApiEventBuilder builder) {
+    public ApiEventChange(final ApiEventBuilder builder) {
         super(builder.setEventType(ApiEventType.CHANGE));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCreate.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCreate.java
index df1879d..7e9fe68 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCreate.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventCreate.java
@@ -17,10 +17,9 @@
 package com.ning.billing.entitlement.events.user;
 
 
-
 public class ApiEventCreate extends ApiEventBase {
 
-    public ApiEventCreate(ApiEventBuilder builder) {
+    public ApiEventCreate(final ApiEventBuilder builder) {
         super(builder.setEventType(ApiEventType.CREATE));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventMigrateBilling.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventMigrateBilling.java
index 3c10699..e206a6a 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventMigrateBilling.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventMigrateBilling.java
@@ -19,22 +19,22 @@ package com.ning.billing.entitlement.events.user;
 import org.joda.time.DateTime;
 
 public class ApiEventMigrateBilling extends ApiEventBase {
-    public ApiEventMigrateBilling(ApiEventBuilder builder) {
+    public ApiEventMigrateBilling(final ApiEventBuilder builder) {
         super(builder.setEventType(ApiEventType.MIGRATE_BILLING));
     }
 
-    public ApiEventMigrateBilling(ApiEventMigrateEntitlement input, DateTime ctd) {
+    public ApiEventMigrateBilling(final ApiEventMigrateEntitlement input, final DateTime ctd) {
         super(new ApiEventBuilder()
-        .setSubscriptionId(input.getSubscriptionId())
-        .setEventPlan(input.getEventPlan())
-        .setEventPlanPhase(input.getEventPlanPhase())
-        .setEventPriceList(input.getPriceList())
-        .setActiveVersion(input.getActiveVersion())
-        .setEffectiveDate(ctd)
-        .setProcessedDate(input.getProcessedDate())
-        .setRequestedDate(input.getRequestedDate())
-        .setFromDisk(true)
-        .setEventType(ApiEventType.MIGRATE_BILLING));
+                      .setSubscriptionId(input.getSubscriptionId())
+                      .setEventPlan(input.getEventPlan())
+                      .setEventPlanPhase(input.getEventPlanPhase())
+                      .setEventPriceList(input.getPriceList())
+                      .setActiveVersion(input.getActiveVersion())
+                      .setEffectiveDate(ctd)
+                      .setProcessedDate(input.getProcessedDate())
+                      .setRequestedDate(input.getRequestedDate())
+                      .setFromDisk(true)
+                      .setEventType(ApiEventType.MIGRATE_BILLING));
     }
 
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventMigrateEntitlement.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventMigrateEntitlement.java
index 7c704cd..4ebc9a6 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventMigrateEntitlement.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventMigrateEntitlement.java
@@ -18,7 +18,7 @@ package com.ning.billing.entitlement.events.user;
 
 public class ApiEventMigrateEntitlement extends ApiEventBase {
 
-    public ApiEventMigrateEntitlement(ApiEventBuilder builder) {
+    public ApiEventMigrateEntitlement(final ApiEventBuilder builder) {
         super(builder.setEventType(ApiEventType.MIGRATE_ENTITLEMENT));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventReCreate.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventReCreate.java
index f608210..6e024b4 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventReCreate.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventReCreate.java
@@ -18,7 +18,7 @@ package com.ning.billing.entitlement.events.user;
 
 public class ApiEventReCreate extends ApiEventBase {
 
-    public ApiEventReCreate(ApiEventBuilder builder) {
+    public ApiEventReCreate(final ApiEventBuilder builder) {
         super(builder.setEventType(ApiEventType.RE_CREATE));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventType.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventType.java
index d1eae92..fb1954c 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventType.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventType.java
@@ -22,31 +22,45 @@ import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 public enum ApiEventType {
     MIGRATE_ENTITLEMENT {
         @Override
-        public SubscriptionTransitionType getSubscriptionTransitionType() { return SubscriptionTransitionType.MIGRATE_ENTITLEMENT; }
+        public SubscriptionTransitionType getSubscriptionTransitionType() {
+            return SubscriptionTransitionType.MIGRATE_ENTITLEMENT;
+        }
     },
     CREATE {
         @Override
-        public SubscriptionTransitionType getSubscriptionTransitionType() { return SubscriptionTransitionType.CREATE; }
+        public SubscriptionTransitionType getSubscriptionTransitionType() {
+            return SubscriptionTransitionType.CREATE;
+        }
     },
     MIGRATE_BILLING {
         @Override
-        public SubscriptionTransitionType getSubscriptionTransitionType() { return SubscriptionTransitionType.MIGRATE_BILLING; }
+        public SubscriptionTransitionType getSubscriptionTransitionType() {
+            return SubscriptionTransitionType.MIGRATE_BILLING;
+        }
     },
     CHANGE {
         @Override
-        public SubscriptionTransitionType getSubscriptionTransitionType() { return SubscriptionTransitionType.CHANGE; }
+        public SubscriptionTransitionType getSubscriptionTransitionType() {
+            return SubscriptionTransitionType.CHANGE;
+        }
     },
     RE_CREATE {
         @Override
-        public SubscriptionTransitionType getSubscriptionTransitionType() { return SubscriptionTransitionType.RE_CREATE; }
+        public SubscriptionTransitionType getSubscriptionTransitionType() {
+            return SubscriptionTransitionType.RE_CREATE;
+        }
     },
     CANCEL {
         @Override
-        public SubscriptionTransitionType getSubscriptionTransitionType() { return SubscriptionTransitionType.CANCEL; }
+        public SubscriptionTransitionType getSubscriptionTransitionType() {
+            return SubscriptionTransitionType.CANCEL;
+        }
     },
     UNCANCEL {
         @Override
-        public SubscriptionTransitionType getSubscriptionTransitionType() { return SubscriptionTransitionType.UNCANCEL; }
+        public SubscriptionTransitionType getSubscriptionTransitionType() {
+            return SubscriptionTransitionType.UNCANCEL;
+        }
     };
 
     // Used to map from internal events to User visible events (both user and phase)
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventUncancel.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventUncancel.java
index 93d8029..039c762 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventUncancel.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventUncancel.java
@@ -18,7 +18,7 @@ package com.ning.billing.entitlement.events.user;
 
 public class ApiEventUncancel extends ApiEventBase {
 
-    public ApiEventUncancel(ApiEventBuilder builder) {
+    public ApiEventUncancel(final ApiEventBuilder builder) {
         super(builder.setEventType(ApiEventType.UNCANCEL));
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/exceptions/EntitlementError.java b/entitlement/src/main/java/com/ning/billing/entitlement/exceptions/EntitlementError.java
index 2cdba51..79daec9 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/exceptions/EntitlementError.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/exceptions/EntitlementError.java
@@ -24,15 +24,15 @@ public class EntitlementError extends Error {
         super();
     }
 
-    public EntitlementError(String msg, Throwable arg1) {
+    public EntitlementError(final String msg, final Throwable arg1) {
         super(msg, arg1);
     }
 
-    public EntitlementError(String msg) {
+    public EntitlementError(final String msg) {
         super(msg);
     }
 
-    public EntitlementError(Throwable msg) {
+    public EntitlementError(final Throwable msg) {
         super(msg);
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/glue/DefaultEntitlementModule.java b/entitlement/src/main/java/com/ning/billing/entitlement/glue/DefaultEntitlementModule.java
index a809c9f..5dc11bf 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/glue/DefaultEntitlementModule.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/glue/DefaultEntitlementModule.java
@@ -41,16 +41,16 @@ import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.engine.addon.AddonUtils;
 import com.ning.billing.entitlement.engine.core.Engine;
-import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.engine.dao.AuditedEntitlementDao;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.engine.dao.RepairEntitlementDao;
 import com.ning.billing.glue.EntitlementModule;
 import com.ning.billing.util.glue.RealImplementation;
 
-public class DefaultEntitlementModule extends AbstractModule implements EntitlementModule{
-    
+public class DefaultEntitlementModule extends AbstractModule implements EntitlementModule {
+
     public static final String REPAIR_NAMED = "repair";
-    
+
     protected void installConfig() {
         final EntitlementConfig config = new ConfigurationObjectFactory(System.getProperties()).build(EntitlementConfig.class);
         bind(EntitlementConfig.class).toInstance(config);
@@ -62,20 +62,20 @@ public class DefaultEntitlementModule extends AbstractModule implements Entitlem
         bind(RepairEntitlementLifecycleDao.class).annotatedWith(Names.named(REPAIR_NAMED)).to(RepairEntitlementDao.class);
         bind(RepairEntitlementDao.class).asEagerSingleton();
     }
-    
+
     protected void installEntitlementCore() {
-        
+
         bind(SubscriptionFactory.class).annotatedWith(Names.named(REPAIR_NAMED)).to(RepairSubscriptionFactory.class).asEagerSingleton();
         bind(SubscriptionFactory.class).to(DefaultSubscriptionFactory.class).asEagerSingleton();
-        
+
         bind(SubscriptionApiService.class).annotatedWith(Names.named(REPAIR_NAMED)).to(RepairSubscriptionApiService.class).asEagerSingleton();
         bind(SubscriptionApiService.class).to(DefaultSubscriptionApiService.class).asEagerSingleton();
-        
+
         bind(Engine.class).asEagerSingleton();
         bind(PlanAligner.class).asEagerSingleton();
         bind(AddonUtils.class).asEagerSingleton();
         bind(MigrationPlanAligner.class).asEagerSingleton();
-        
+
         installEntitlementService();
         installEntitlementTimelineApi();
         installEntitlementMigrationApi();
@@ -93,7 +93,7 @@ public class DefaultEntitlementModule extends AbstractModule implements Entitlem
     @Override
     public void installEntitlementService() {
         bind(EntitlementService.class).to(Engine.class).asEagerSingleton();
-     }
+    }
 
     @Override
     public void installEntitlementTimelineApi() {
diff --git a/entitlement/src/main/resources/com/ning/billing/entitlement/ddl.sql b/entitlement/src/main/resources/com/ning/billing/entitlement/ddl.sql
index f69a20d..ae45518 100644
--- a/entitlement/src/main/resources/com/ning/billing/entitlement/ddl.sql
+++ b/entitlement/src/main/resources/com/ning/billing/entitlement/ddl.sql
@@ -25,6 +25,8 @@ CREATE UNIQUE INDEX subscription_events_id ON subscription_events(id);
 CREATE INDEX idx_ent_1 ON subscription_events(subscription_id, is_active, effective_date);
 CREATE INDEX idx_ent_2 ON subscription_events(subscription_id, effective_date, created_date, requested_date,id);
 
+
+
 DROP TABLE IF EXISTS subscriptions;
 CREATE TABLE subscriptions (
     record_id int(11) unsigned NOT NULL AUTO_INCREMENT,
@@ -43,6 +45,7 @@ CREATE TABLE subscriptions (
     PRIMARY KEY(record_id)
 ) ENGINE=innodb;
 CREATE UNIQUE INDEX subscriptions_id ON subscriptions(id);
+CREATE INDEX subscriptions_bundle_id ON subscriptions(bundle_id);
 
 DROP TABLE IF EXISTS bundles;
 CREATE TABLE bundles (
@@ -54,4 +57,7 @@ CREATE TABLE bundles (
     last_sys_update_date datetime,
     PRIMARY KEY(record_id)
 ) ENGINE=innodb;
- CREATE UNIQUE INDEX bundles_id ON bundles(id);
+CREATE UNIQUE INDEX bundles_id ON bundles(id);
+CREATE INDEX bundles_key ON bundles(external_key);
+CREATE INDEX bundles_account ON bundles(account_id);
+
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
index 2681a0b..961923f 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigration.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.entitlement.api.migration;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
@@ -45,29 +40,34 @@ import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
 public abstract class TestMigration extends TestApiBase {
     public void testSingleBasePlan() {
 
         try {
-            
+
             log.info("Starting testSingleBasePlan");
 
             final DateTime startDate = clock.getUTCNow().minusMonths(2);
-            DateTime beforeMigration =  clock.getUTCNow();
-            EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlan(startDate);
-            DateTime afterMigration = clock.getUTCNow();
+            final DateTime beforeMigration = clock.getUTCNow();
+            final EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlan(startDate);
+            final DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
             migrationApi.migrate(toBeMigrated, context);
             assertTrue(testListener.isCompleted(5000));
 
-            List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
             assertEquals(bundles.size(), 1);
-            SubscriptionBundle bundle = bundles.get(0);
+            final SubscriptionBundle bundle = bundles.get(0);
 
-            List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
             assertEquals(subscriptions.size(), 1);
-            Subscription subscription = subscriptions.get(0);
+            final Subscription subscription = subscriptions.get(0);
             assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
             assertEquals(subscription.getEndDate(), null);
             assertEquals(subscription.getCurrentPriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME);
@@ -85,25 +85,25 @@ public abstract class TestMigration extends TestApiBase {
     public void testPlanWithAddOn() {
         try {
             log.info("Starting testPlanWithAddOn");
-            DateTime beforeMigration = clock.getUTCNow();
+            final DateTime beforeMigration = clock.getUTCNow();
             final DateTime initalBPStart = clock.getUTCNow().minusMonths(3);
             final DateTime initalAddonStart = clock.getUTCNow().minusMonths(1).plusDays(7);
-            EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlanAndAddons(initalBPStart, initalAddonStart);
-            DateTime afterMigration = clock.getUTCNow();
+            final EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlanAndAddons(initalBPStart, initalAddonStart);
+            final DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
             migrationApi.migrate(toBeMigrated, context);
             assertTrue(testListener.isCompleted(5000));
 
-            List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
             assertEquals(bundles.size(), 1);
-            SubscriptionBundle bundle = bundles.get(0);
+            final SubscriptionBundle bundle = bundles.get(0);
 
-            List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
             assertEquals(subscriptions.size(), 2);
 
-            Subscription baseSubscription = (subscriptions.get(0).getCurrentPlan().getProduct().getCategory() == ProductCategory.BASE) ?
+            final Subscription baseSubscription = (subscriptions.get(0).getCurrentPlan().getProduct().getCategory() == ProductCategory.BASE) ?
                     subscriptions.get(0) : subscriptions.get(1);
             assertDateWithin(baseSubscription.getStartDate(), beforeMigration, afterMigration);
             assertEquals(baseSubscription.getEndDate(), null);
@@ -113,7 +113,7 @@ public abstract class TestMigration extends TestApiBase {
             assertEquals(baseSubscription.getCurrentPlan().getName(), "shotgun-annual");
             assertEquals(baseSubscription.getChargedThroughDate(), initalBPStart.plusYears(1));
 
-            Subscription aoSubscription = (subscriptions.get(0).getCurrentPlan().getProduct().getCategory() == ProductCategory.ADD_ON) ?
+            final Subscription aoSubscription = (subscriptions.get(0).getCurrentPlan().getProduct().getCategory() == ProductCategory.ADD_ON) ?
                     subscriptions.get(0) : subscriptions.get(1);
             // initalAddonStart.plusMonths(1).minusMonths(1) may be different from initalAddonStart, depending on exact date
             // e.g : March 31 + 1 month => April 30 and April 30 - 1 month = March 30 which is != March 31 !!!! 
@@ -136,22 +136,22 @@ public abstract class TestMigration extends TestApiBase {
         try {
             log.info("Starting testSingleBasePlanFutureCancelled");
             final DateTime startDate = clock.getUTCNow().minusMonths(1);
-            DateTime beforeMigration = clock.getUTCNow();
-            EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlanFutreCancelled(startDate);
-            DateTime afterMigration = clock.getUTCNow();
+            final DateTime beforeMigration = clock.getUTCNow();
+            final EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlanFutreCancelled(startDate);
+            final DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
             migrationApi.migrate(toBeMigrated, context);
             assertTrue(testListener.isCompleted(5000));
 
-            List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
             assertEquals(bundles.size(), 1);
-            SubscriptionBundle bundle = bundles.get(0);
+            final SubscriptionBundle bundle = bundles.get(0);
             //assertEquals(bundle.getStartDate(), effectiveDate);
 
-            List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
             assertEquals(subscriptions.size(), 1);
-            Subscription subscription = subscriptions.get(0);
+            final Subscription subscription = subscriptions.get(0);
             assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
             assertEquals(subscription.getCurrentPriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME);
             assertEquals(subscription.getCurrentPhase().getPhaseType(), PhaseType.EVERGREEN);
@@ -162,8 +162,8 @@ public abstract class TestMigration extends TestApiBase {
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_BILLING);
             testListener.pushExpectedEvent(NextEvent.CANCEL);
-            
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusYears(1));
+
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusYears(1));
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
 
@@ -176,7 +176,7 @@ public abstract class TestMigration extends TestApiBase {
             assertNull(subscription.getCurrentPlan());
 
             assertListenerStatus();
-            
+
         } catch (EntitlementMigrationApiException e) {
             Assert.fail("", e);
         }
@@ -185,22 +185,22 @@ public abstract class TestMigration extends TestApiBase {
     public void testSingleBasePlanWithPendingPhase() {
 
         try {
-            
+
             log.info("Starting testSingleBasePlanWithPendingPhase");
             final DateTime trialDate = clock.getUTCNow().minusDays(10);
-            EntitlementAccountMigration toBeMigrated = createAccountFuturePendingPhase(trialDate);
+            final EntitlementAccountMigration toBeMigrated = createAccountFuturePendingPhase(trialDate);
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
             migrationApi.migrate(toBeMigrated, context);
             assertTrue(testListener.isCompleted(5000));
 
-            List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
             assertEquals(bundles.size(), 1);
-            SubscriptionBundle bundle = bundles.get(0);
+            final SubscriptionBundle bundle = bundles.get(0);
 
-            List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
             assertEquals(subscriptions.size(), 1);
-            Subscription subscription = subscriptions.get(0);
+            final Subscription subscription = subscriptions.get(0);
 
             assertEquals(subscription.getStartDate(), trialDate);
             assertEquals(subscription.getEndDate(), null);
@@ -213,7 +213,7 @@ public abstract class TestMigration extends TestApiBase {
             testListener.pushExpectedEvent(NextEvent.MIGRATE_BILLING);
             testListener.pushExpectedEvent(NextEvent.PHASE);
 
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(30));
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(30));
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
 
@@ -226,7 +226,7 @@ public abstract class TestMigration extends TestApiBase {
             assertEquals(subscription.getCurrentPhase().getName(), "assault-rifle-monthly-evergreen");
 
             assertListenerStatus();
-            
+
         } catch (EntitlementMigrationApiException e) {
             Assert.fail("", e);
         }
@@ -236,21 +236,21 @@ public abstract class TestMigration extends TestApiBase {
 
         try {
             log.info("Starting testSingleBasePlanWithPendingChange");
-            DateTime beforeMigration = clock.getUTCNow();
-            EntitlementAccountMigration toBeMigrated = createAccountFuturePendingChange();
-            DateTime afterMigration = clock.getUTCNow();
+            final DateTime beforeMigration = clock.getUTCNow();
+            final EntitlementAccountMigration toBeMigrated = createAccountFuturePendingChange();
+            final DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
             migrationApi.migrate(toBeMigrated, context);
             assertTrue(testListener.isCompleted(5000));
 
-            List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(toBeMigrated.getAccountKey());
             assertEquals(bundles.size(), 1);
-            SubscriptionBundle bundle = bundles.get(0);
+            final SubscriptionBundle bundle = bundles.get(0);
 
-            List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
+            final List<Subscription> subscriptions = entitlementApi.getSubscriptionsForBundle(bundle.getId());
             assertEquals(subscriptions.size(), 1);
-            Subscription subscription = subscriptions.get(0);
+            final Subscription subscription = subscriptions.get(0);
             assertDateWithin(subscription.getStartDate(), beforeMigration, afterMigration);
             assertEquals(subscription.getEndDate(), null);
             assertEquals(subscription.getCurrentPriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME);
@@ -259,8 +259,8 @@ public abstract class TestMigration extends TestApiBase {
             assertEquals(subscription.getCurrentPlan().getName(), "assault-rifle-monthly");
 
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
+
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
 
@@ -273,7 +273,7 @@ public abstract class TestMigration extends TestApiBase {
             assertEquals(subscription.getCurrentPlan().getName(), "shotgun-annual");
 
             assertListenerStatus();
-            
+
         } catch (EntitlementMigrationApiException e) {
             Assert.fail("", e);
         }
@@ -288,29 +288,31 @@ public abstract class TestMigration extends TestApiBase {
 
             @Override
             public EntitlementBundleMigration[] getBundles() {
-                List<EntitlementBundleMigration> bundles = new ArrayList<EntitlementBundleMigration>();
-                EntitlementBundleMigration bundle0 = new EntitlementBundleMigration() {
+                final List<EntitlementBundleMigration> bundles = new ArrayList<EntitlementBundleMigration>();
+                final EntitlementBundleMigration bundle0 = new EntitlementBundleMigration() {
 
                     @Override
                     public EntitlementSubscriptionMigration[] getSubscriptions() {
 
-                        EntitlementSubscriptionMigration[] result = new EntitlementSubscriptionMigration[cases.size()];
+                        final EntitlementSubscriptionMigration[] result = new EntitlementSubscriptionMigration[cases.size()];
 
                         for (int i = 0; i < cases.size(); i++) {
 
                             final List<EntitlementSubscriptionMigrationCaseWithCTD> curCases = cases.get(i);
-                            EntitlementSubscriptionMigration subscription = new EntitlementSubscriptionMigration() {
+                            final EntitlementSubscriptionMigration subscription = new EntitlementSubscriptionMigration() {
                                 @Override
                                 public EntitlementSubscriptionMigrationCaseWithCTD[] getSubscriptionCases() {
                                     return curCases.toArray(new EntitlementSubscriptionMigrationCaseWithCTD[curCases.size()]);
                                 }
+
                                 @Override
                                 public ProductCategory getCategory() {
                                     return curCases.get(0).getPlanPhaseSpecifier().getProductCategory();
                                 }
+
                                 @Override
                                 public DateTime getChargedThroughDate() {
-                                    for (EntitlementSubscriptionMigrationCaseWithCTD cur :curCases) {
+                                    for (final EntitlementSubscriptionMigrationCaseWithCTD cur : curCases) {
                                         if (cur.getChargedThroughDate() != null) {
                                             return cur.getChargedThroughDate();
                                         }
@@ -322,6 +324,7 @@ public abstract class TestMigration extends TestApiBase {
                         }
                         return result;
                     }
+
                     @Override
                     public String getBundleKey() {
                         return "12345";
@@ -340,14 +343,14 @@ public abstract class TestMigration extends TestApiBase {
 
     private EntitlementAccountMigration createAccountWithRegularBasePlanAndAddons(final DateTime initialBPstart, final DateTime initalAddonStart) {
 
-        List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
+        final List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
         cases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
                 new PlanPhaseSpecifier("Shotgun", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN),
                 initialBPstart,
                 null,
                 initialBPstart.plusYears(1)));
 
-        List<EntitlementSubscriptionMigrationCaseWithCTD> firstAddOnCases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
+        final List<EntitlementSubscriptionMigrationCaseWithCTD> firstAddOnCases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
         firstAddOnCases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
                 new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.DISCOUNT),
                 initalAddonStart,
@@ -360,39 +363,39 @@ public abstract class TestMigration extends TestApiBase {
                 null));
 
 
-        List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
+        final List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
         input.add(cases);
         input.add(firstAddOnCases);
         return createAccountTest(input);
     }
 
     private EntitlementAccountMigration createAccountWithRegularBasePlan(final DateTime startDate) {
-        List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
+        final List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
         cases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
                 new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN),
                 startDate,
                 null,
                 startDate.plusYears(1)));
-        List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
+        final List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
         input.add(cases);
         return createAccountTest(input);
     }
 
     private EntitlementAccountMigration createAccountWithRegularBasePlanFutreCancelled(final DateTime startDate) {
-        List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
+        final List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
         cases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
                 new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN),
                 startDate,
                 startDate.plusYears(1),
                 startDate.plusYears(1)));
-        List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
+        final List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
         input.add(cases);
         return createAccountTest(input);
     }
 
 
     private EntitlementAccountMigration createAccountFuturePendingPhase(final DateTime trialDate) {
-        List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
+        final List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
         cases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
                 new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL),
                 trialDate,
@@ -403,13 +406,13 @@ public abstract class TestMigration extends TestApiBase {
                 trialDate.plusDays(30),
                 null,
                 null));
-        List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
+        final List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
         input.add(cases);
         return createAccountTest(input);
     }
 
     private EntitlementAccountMigration createAccountFuturePendingChange() {
-        List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
+        final List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
         final DateTime effectiveDate = clock.getUTCNow().minusDays(10);
         cases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
                 new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN),
@@ -421,7 +424,7 @@ public abstract class TestMigration extends TestApiBase {
                 effectiveDate.plusMonths(1).plusDays(1),
                 null,
                 null));
-        List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
+        final List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
         input.add(cases);
         return createAccountTest(input);
     }
@@ -434,7 +437,7 @@ public abstract class TestMigration extends TestApiBase {
         private final DateTime cancelDt;
         private final DateTime ctd;
 
-        public EntitlementSubscriptionMigrationCaseWithCTD(PlanPhaseSpecifier pps, DateTime effDt, DateTime cancelDt, DateTime ctd) {
+        public EntitlementSubscriptionMigrationCaseWithCTD(final PlanPhaseSpecifier pps, final DateTime effDt, final DateTime cancelDt, final DateTime ctd) {
             this.pps = pps;
             this.cancelDt = cancelDt;
             this.effDt = effDt;
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
index 0195d69..81c12cd 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationMemory.java
@@ -31,26 +31,26 @@ public class TestMigrationMemory extends TestMigration {
     }
 
     @Override
-    @Test(enabled=true, groups="fast")
+    @Test(enabled = true, groups = "fast")
     public void testSingleBasePlan() {
         super.testSingleBasePlan();
     }
 
     @Override
-    @Test(enabled=true, groups="fast")
+    @Test(enabled = true, groups = "fast")
     public void testSingleBasePlanFutureCancelled() {
         super.testSingleBasePlanFutureCancelled();
     }
 
     @Override
-    @Test(enabled=true, groups="fast")
+    @Test(enabled = true, groups = "fast")
     public void testPlanWithAddOn() {
         super.testPlanWithAddOn();
     }
 
 
     @Override
-    @Test(enabled=true, groups="fast")
+    @Test(enabled = true, groups = "fast")
     public void testSingleBasePlanWithPendingPhase() {
         super.testSingleBasePlanWithPendingPhase();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationSql.java
index 34b2266..82fc7e7 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/migration/TestMigrationSql.java
@@ -30,25 +30,25 @@ public class TestMigrationSql extends TestMigration {
     }
 
     @Override
-    @Test(enabled=true, groups="slow")
+    @Test(enabled = true, groups = "slow")
     public void testSingleBasePlan() {
         super.testSingleBasePlan();
     }
 
     @Override
-    @Test(enabled=true, groups="slow")
+    @Test(enabled = true, groups = "slow")
     public void testPlanWithAddOn() {
         super.testPlanWithAddOn();
     }
 
     @Override
-    @Test(enabled=true, groups="slow")
+    @Test(enabled = true, groups = "slow")
     public void testSingleBasePlanFutureCancelled() {
         super.testSingleBasePlanFutureCancelled();
     }
 
     @Override
-    @Test(enabled=true, groups="slow")
+    @Test(enabled = true, groups = "slow")
     public void testSingleBasePlanWithPendingPhase() {
         super.testSingleBasePlanWithPendingPhase();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
index ba09b34..bfbc817 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
@@ -16,19 +16,12 @@
 
 package com.ning.billing.entitlement.api;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
+import javax.annotation.Nullable;
 import java.io.IOException;
 import java.net.URL;
 import java.util.List;
 import java.util.UUID;
 
-import javax.annotation.Nullable;
-
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.Period;
@@ -81,14 +74,16 @@ import com.ning.billing.util.callcontext.TestCallContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.glue.RealImplementation;
+import com.ning.billing.util.io.IOUtils;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
 
 public abstract class TestApiBase implements TestListenerStatus {
-    
     protected static final Logger log = LoggerFactory.getLogger(TestApiBase.class);
 
-    protected static final long DAY_IN_MS = (24 * 3600 * 1000);
-
     protected EntitlementService entitlementService;
     protected EntitlementUserApi entitlementApi;
     protected ChargeThruApi billingApi;
@@ -111,7 +106,7 @@ public abstract class TestApiBase implements TestListenerStatus {
     protected CallContext context = new TestCallContext("Api Test");
 
     private boolean isListenerFailed;
-    private String listenerFailedMsg;    
+    private String listenerFailedMsg;
 
     //
     // The date on which we make our test start; just to ensure that running tests at different dates does not
@@ -120,13 +115,12 @@ public abstract class TestApiBase implements TestListenerStatus {
     protected DateTime testStartDate = new DateTime(2012, 5, 7, 0, 3, 42, 0);
 
 
-    
     public static void loadSystemPropertiesFromClasspath(final String resource) {
         final URL url = TestApiBase.class.getResource(resource);
         assertNotNull(url);
 
         try {
-            System.getProperties().load( url.openStream() );
+            System.getProperties().load(url.openStream());
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
@@ -146,7 +140,7 @@ public abstract class TestApiBase implements TestListenerStatus {
         }
     }
 
-    
+
     @Override
     public void failed(final String msg) {
         this.isListenerFailed = true;
@@ -158,7 +152,7 @@ public abstract class TestApiBase implements TestListenerStatus {
         this.isListenerFailed = false;
         this.listenerFailedMsg = null;
     }
-    
+
     @BeforeClass(alwaysRun = true)
     public void setup() throws Exception {
 
@@ -166,7 +160,7 @@ public abstract class TestApiBase implements TestListenerStatus {
         final Injector g = getInjector();
 
         entitlementService = g.getInstance(EntitlementService.class);
-        EntitlementUserApi entApi = (EntitlementUserApi)g.getInstance(Key.get(EntitlementUserApi.class, RealImplementation.class));
+        final EntitlementUserApi entApi = (EntitlementUserApi) g.getInstance(Key.get(EntitlementUserApi.class, RealImplementation.class));
         entitlementApi = entApi;
         billingApi = g.getInstance(ChargeThruApi.class);
         migrationApi = g.getInstance(EntitlementMigrationApi.class);
@@ -184,7 +178,7 @@ public abstract class TestApiBase implements TestListenerStatus {
 
         setupDao();
 
-        ((DefaultCatalogService) catalogService).loadCatalog();        
+        ((DefaultCatalogService) catalogService).loadCatalog();
 
         accountData = getAccountData();
         assertNotNull(accountData);
@@ -203,10 +197,10 @@ public abstract class TestApiBase implements TestListenerStatus {
         }
     }
 
-    private static boolean isSqlTest(EntitlementDao theDao) {
-        return (! (theDao instanceof MockEntitlementDaoMemory));
+    private static boolean isSqlTest(final EntitlementDao theDao) {
+        return (!(theDao instanceof MockEntitlementDaoMemory));
     }
-   
+
     @BeforeMethod(alwaysRun = true)
     public void setupTest() throws Exception {
 
@@ -214,53 +208,53 @@ public abstract class TestApiBase implements TestListenerStatus {
 
         // CLEANUP ALL DB TABLES OR IN MEMORY STRUCTURES
         cleanupDao();
-        
+
         // RESET LIST OF EXPECTED EVENTS
         if (testListener != null) {
             testListener.reset();
             resetTestListenerStatus();
         }
-        
+
         // RESET CLOCK
         clock.resetDeltaFromReality();
 
         // START BUS AND REGISTER LISTENER
         busService.getBus().start();
         busService.getBus().register(testListener);
-        
+
         // START NOTIFICATION QUEUE FOR ENTITLEMENT
         ((Engine) entitlementService).initialize();
-        ((Engine)entitlementService).start();
-        
+        ((Engine) entitlementService).start();
+
         // SETUP START DATE
         clock.setDeltaFromReality(testStartDate.getMillis() - clock.getUTCNow().getMillis());
-        
+
         // CREATE NEW BUNDLE FOR TEST
-        UUID accountId = UUID.randomUUID();
+        final UUID accountId = UUID.randomUUID();
         bundle = entitlementApi.createBundleForAccount(accountId, "myDefaultBundle", context);
         assertNotNull(bundle);
     }
 
     @AfterMethod(alwaysRun = true)
     public void cleanupTest() throws Exception {
-        
+
         // UNREGISTER TEST LISTENER AND STOP BUS
         busService.getBus().unregister(testListener);
         busService.getBus().stop();
-        
+
         // STOP NOTIFICATION QUEUE
-        ((Engine)entitlementService).stop();
+        ((Engine) entitlementService).stop();
 
         log.warn("DONE WITH TEST\n");
     }
-    
+
     protected void assertListenerStatus() {
         if (isListenerFailed) {
             log.error(listenerFailedMsg);
             Assert.fail(listenerFailedMsg);
         }
     }
-    
+
     private void cleanupDao() {
         if (helper != null) {
             helper.cleanupAllTables();
@@ -270,29 +264,30 @@ public abstract class TestApiBase implements TestListenerStatus {
     }
 
     protected SubscriptionData createSubscription(final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate)
-        throws EntitlementUserApiException {
+            throws EntitlementUserApiException {
         return createSubscriptionWithBundle(bundle.getId(), productName, term, planSet, requestedDate);
     }
+
     protected SubscriptionData createSubscription(final String productName, final BillingPeriod term, final String planSet)
-    throws EntitlementUserApiException {
+            throws EntitlementUserApiException {
         return createSubscriptionWithBundle(bundle.getId(), productName, term, planSet, null);
     }
 
     protected SubscriptionData createSubscriptionWithBundle(final UUID bundleId, final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate)
-        throws EntitlementUserApiException {
-        
+            throws EntitlementUserApiException {
+
         testListener.pushExpectedEvent(NextEvent.CREATE);
-        SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundleId,
-                new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSet, null),
-                requestedDate == null ? clock.getUTCNow() : requestedDate, context);
+        final SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundleId,
+                                                                                                   new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSet, null),
+                                                                                                   requestedDate == null ? clock.getUTCNow() : requestedDate, context);
         assertNotNull(subscription);
         assertTrue(testListener.isCompleted(5000));
         return subscription;
     }
 
-    protected void checkNextPhaseChange(SubscriptionData subscription, int expPendingEvents, DateTime expPhaseChange) {
+    protected void checkNextPhaseChange(final SubscriptionData subscription, final int expPendingEvents, final DateTime expPhaseChange) {
 
-        List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
+        final List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
         assertNotNull(events);
         printEvents(events);
         assertEquals(events.size(), expPendingEvents);
@@ -300,13 +295,13 @@ public abstract class TestApiBase implements TestListenerStatus {
             boolean foundPhase = false;
             boolean foundChange = false;
 
-            for (EntitlementEvent cur : events) {
+            for (final EntitlementEvent cur : events) {
                 if (cur instanceof PhaseEvent) {
                     assertEquals(foundPhase, false);
                     foundPhase = true;
                     assertEquals(cur.getEffectiveDate(), expPhaseChange);
                 } else if (cur instanceof ApiEvent) {
-                    ApiEvent uEvent = (ApiEvent) cur;
+                    final ApiEvent uEvent = (ApiEvent) cur;
                     assertEquals(ApiEventType.CHANGE, uEvent.getEventType());
                     assertEquals(foundChange, false);
                     foundChange = true;
@@ -317,26 +312,28 @@ public abstract class TestApiBase implements TestListenerStatus {
         }
     }
 
-    protected void assertDateWithin(DateTime in, DateTime lower, DateTime upper) {
+    protected void assertDateWithin(final DateTime in, final DateTime lower, final DateTime upper) {
         assertTrue(in.isEqual(lower) || in.isAfter(lower));
         assertTrue(in.isEqual(upper) || in.isBefore(upper));
     }
 
     protected Duration getDurationDay(final int days) {
-        Duration result = new Duration() {
+        final Duration result = new Duration() {
             @Override
             public TimeUnit getUnit() {
                 return TimeUnit.DAYS;
             }
+
             @Override
             public int getNumber() {
                 return days;
             }
 
             @Override
-            public DateTime addToDateTime(DateTime dateTime) {
+            public DateTime addToDateTime(final DateTime dateTime) {
                 return null;
             }
+
             @Override
             public Period toJodaPeriod() {
                 throw new UnsupportedOperationException();
@@ -346,20 +343,22 @@ public abstract class TestApiBase implements TestListenerStatus {
     }
 
     protected Duration getDurationMonth(final int months) {
-        Duration result = new Duration() {
+        final Duration result = new Duration() {
             @Override
             public TimeUnit getUnit() {
                 return TimeUnit.MONTHS;
             }
+
             @Override
             public int getNumber() {
                 return months;
             }
 
             @Override
-            public DateTime addToDateTime(DateTime dateTime) {
+            public DateTime addToDateTime(final DateTime dateTime) {
                 return null;  //To change body of implemented methods use File | Settings | File Templates.
             }
+
             @Override
             public Period toJodaPeriod() {
                 throw new UnsupportedOperationException();
@@ -370,20 +369,22 @@ public abstract class TestApiBase implements TestListenerStatus {
 
 
     protected Duration getDurationYear(final int years) {
-        Duration result = new Duration() {
+        final Duration result = new Duration() {
             @Override
             public TimeUnit getUnit() {
                 return TimeUnit.YEARS;
             }
+
             @Override
             public int getNumber() {
                 return years;
             }
 
             @Override
-            public DateTime addToDateTime(DateTime dateTime) {
-                return dateTime.plusYears(years);  
+            public DateTime addToDateTime(final DateTime dateTime) {
+                return dateTime.plusYears(years);
             }
+
             @Override
             public Period toJodaPeriod() {
                 throw new UnsupportedOperationException();
@@ -393,14 +394,14 @@ public abstract class TestApiBase implements TestListenerStatus {
     }
 
     protected AccountData getAccountData() {
-        AccountData accountData = new AccountData() {
+        final AccountData accountData = new AccountData() {
             @Override
             public String getName() {
                 return "firstName lastName";
             }
 
             @Override
-            public int getFirstNameLength() {
+            public Integer getFirstNameLength() {
                 return "firstName".length();
             }
 
@@ -415,12 +416,12 @@ public abstract class TestApiBase implements TestListenerStatus {
             }
 
             @Override
-            public boolean isMigrated() {
+            public Boolean isMigrated() {
                 return false;
             }
 
             @Override
-            public boolean isNotifiedForInvoices() {
+            public Boolean isNotifiedForInvoices() {
                 return false;
             }
 
@@ -430,7 +431,7 @@ public abstract class TestApiBase implements TestListenerStatus {
             }
 
             @Override
-            public int getBillCycleDay() {
+            public Integer getBillCycleDay() {
                 return 1;
             }
 
@@ -443,6 +444,7 @@ public abstract class TestApiBase implements TestListenerStatus {
             public UUID getPaymentMethodId() {
                 return UUID.randomUUID();
             }
+
             @Override
             public DateTimeZone getTimeZone() {
                 return DateTimeZone.forID("Europe/Paris");
@@ -497,14 +499,14 @@ public abstract class TestApiBase implements TestListenerStatus {
         return new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, priceList, phaseType);
     }
 
-    protected void printEvents(List<EntitlementEvent> events) {
-        for (EntitlementEvent cur : events) {
+    protected void printEvents(final List<EntitlementEvent> events) {
+        for (final EntitlementEvent cur : events) {
             log.debug("Inspect event " + cur);
         }
     }
 
-    protected void printSubscriptionTransitions(List<SubscriptionEvent> transitions) {
-        for (SubscriptionEvent cur : transitions) {
+    protected void printSubscriptionTransitions(final List<SubscriptionEvent> transitions) {
+        for (final SubscriptionEvent cur : transitions) {
             log.debug("Transition " + cur);
         }
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestEventJson.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestEventJson.java
index e50fd41..978c39b 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/TestEventJson.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestEventJson.java
@@ -17,7 +17,6 @@ package com.ning.billing.entitlement.api;
 
 import java.util.UUID;
 
-import com.ning.billing.util.jackson.ObjectMapper;
 import org.joda.time.DateTime;
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -27,37 +26,36 @@ import com.ning.billing.entitlement.api.timeline.RepairEntitlementEvent;
 import com.ning.billing.entitlement.api.user.DefaultSubscriptionEvent;
 import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionEvent;
+import com.ning.billing.util.jackson.ObjectMapper;
 
 public class TestEventJson {
     private final ObjectMapper mapper = new ObjectMapper();
 
-    @Test(groups= {"fast"})
+    @Test(groups = {"fast"})
     public void testSubscriptionEvent() throws Exception {
-        
 
-        SubscriptionEvent e = new DefaultSubscriptionEvent(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), new DateTime(), new DateTime(),
-                SubscriptionState.ACTIVE, "pro", "TRIAL", "DEFAULT", SubscriptionState.CANCELLED, null, null, null, 3L, UUID.randomUUID(), SubscriptionTransitionType.CANCEL, 0, new DateTime());
-            
-        String json = mapper.writeValueAsString(e);
 
-        Class<?> claz = Class.forName(DefaultSubscriptionEvent.class.getName());
-        Object obj =  mapper.readValue(json, claz);
+        final SubscriptionEvent e = new DefaultSubscriptionEvent(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), new DateTime(), new DateTime(),
+                                                           SubscriptionState.ACTIVE, "pro", "TRIAL", "DEFAULT", SubscriptionState.CANCELLED, null, null, null, 3L, UUID.randomUUID(), SubscriptionTransitionType.CANCEL, 0, new DateTime());
+
+        final String json = mapper.writeValueAsString(e);
+
+        final Class<?> claz = Class.forName(DefaultSubscriptionEvent.class.getName());
+        final Object obj = mapper.readValue(json, claz);
         Assert.assertTrue(obj.equals(e));
 
     }
-    
-    @Test(groups= {"fast"})
+
+    @Test(groups = {"fast"})
     public void testRepairEntitlementEvent() throws Exception {
-        RepairEntitlementEvent e = new DefaultRepairEntitlementEvent(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), new DateTime());
-        
-        String json = mapper.writeValueAsString(e);
+        final RepairEntitlementEvent e = new DefaultRepairEntitlementEvent(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), new DateTime());
+
+        final String json = mapper.writeValueAsString(e);
 
-        Class<?> claz = Class.forName(DefaultRepairEntitlementEvent.class.getName());
-        Object obj =  mapper.readValue(json, claz);
+        final Class<?> claz = Class.forName(DefaultRepairEntitlementEvent.class.getName());
+        final Object obj = mapper.readValue(json, claz);
         Assert.assertTrue(obj.equals(e));
     }
-        
 
-    
-    
+
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestApiBaseRepair.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestApiBaseRepair.java
index 6ab5904..292dc37 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestApiBaseRepair.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestApiBaseRepair.java
@@ -15,8 +15,6 @@
  */
 package com.ning.billing.entitlement.api.timeline;
 
-import static org.testng.Assert.assertEquals;
-
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
@@ -27,7 +25,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 
-
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PhaseType;
@@ -35,25 +32,24 @@ import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.TestApiBase;
-import com.ning.billing.entitlement.api.timeline.BundleTimeline;
-import com.ning.billing.entitlement.api.timeline.EntitlementRepairException;
-import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.DeletedEvent;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.ExistingEvent;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.NewEvent;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 
+import static org.testng.Assert.assertEquals;
+
 
 public abstract class TestApiBaseRepair extends TestApiBase {
 
-    protected final static Logger log = LoggerFactory.getLogger(TestApiBaseRepair.class);
-    
+    protected static final Logger log = LoggerFactory.getLogger(TestApiBaseRepair.class);
+
     public interface TestWithExceptionCallback {
         public void doTest() throws EntitlementRepairException, EntitlementUserApiException;
     }
-    
+
     public static class TestWithException {
-        public void withException(TestWithExceptionCallback callback, ErrorCode code) throws Exception {
+        public void withException(final TestWithExceptionCallback callback, final ErrorCode code) throws Exception {
             try {
                 callback.doTest();
                 Assert.fail("Failed to catch exception " + code);
@@ -63,21 +59,24 @@ public abstract class TestApiBaseRepair extends TestApiBase {
         }
     }
 
-    
+
     protected SubscriptionTimeline createSubscriptionRepair(final UUID id, final List<DeletedEvent> deletedEvents, final List<NewEvent> newEvents) {
         return new SubscriptionTimeline() {
             @Override
             public UUID getId() {
                 return id;
             }
+
             @Override
             public List<NewEvent> getNewEvents() {
                 return newEvents;
             }
+
             @Override
             public List<ExistingEvent> getExistingEvents() {
                 return null;
             }
+
             @Override
             public List<DeletedEvent> getDeletedEvents() {
                 return deletedEvents;
@@ -91,14 +90,17 @@ public abstract class TestApiBaseRepair extends TestApiBase {
             public String getViewId() {
                 return viewId;
             }
+
             @Override
             public List<SubscriptionTimeline> getSubscriptions() {
                 return subscriptionRepair;
             }
+
             @Override
             public UUID getBundleId() {
                 return bundleId;
             }
+
             @Override
             public String getExternalKey() {
                 return null;
@@ -106,28 +108,32 @@ public abstract class TestApiBaseRepair extends TestApiBase {
         };
     }
 
-    protected ExistingEvent createExistingEventForAssertion(final SubscriptionTransitionType type, 
-            final String productName, final PhaseType phaseType, final ProductCategory category, final String priceListName, final BillingPeriod billingPeriod,
-            final DateTime effectiveDateTime) {
+    protected ExistingEvent createExistingEventForAssertion(final SubscriptionTransitionType type,
+                                                            final String productName, final PhaseType phaseType, final ProductCategory category, final String priceListName, final BillingPeriod billingPeriod,
+                                                            final DateTime effectiveDateTime) {
 
         final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, category, billingPeriod, priceListName, phaseType);
-        ExistingEvent ev = new ExistingEvent() {
+        final ExistingEvent ev = new ExistingEvent() {
             @Override
             public SubscriptionTransitionType getSubscriptionTransitionType() {
                 return type;
             }
-             @Override
+
+            @Override
             public DateTime getRequestedDate() {
-                 return null;
+                return null;
             }
+
             @Override
             public PlanPhaseSpecifier getPlanPhaseSpecifier() {
                 return spec;
             }
+
             @Override
             public UUID getEventId() {
                 return null;
             }
+
             @Override
             public DateTime getEffectiveDate() {
                 return effectiveDateTime;
@@ -135,9 +141,9 @@ public abstract class TestApiBaseRepair extends TestApiBase {
         };
         return ev;
     }
-    
+
     protected SubscriptionTimeline getSubscriptionRepair(final UUID id, final BundleTimeline bundleRepair) {
-        for (SubscriptionTimeline cur : bundleRepair.getSubscriptions()) {
+        for (final SubscriptionTimeline cur : bundleRepair.getSubscriptions()) {
             if (cur.getId().equals(id)) {
                 return cur;
             }
@@ -145,22 +151,23 @@ public abstract class TestApiBaseRepair extends TestApiBase {
         Assert.fail("Failed to find SubscriptionReapir " + id);
         return null;
     }
+
     protected void validateExistingEventForAssertion(final ExistingEvent expected, final ExistingEvent input) {
-        
+
         log.info(String.format("Got %s -> Expected %s", input.getPlanPhaseSpecifier().getProductName(), expected.getPlanPhaseSpecifier().getProductName()));
         assertEquals(input.getPlanPhaseSpecifier().getProductName(), expected.getPlanPhaseSpecifier().getProductName());
         log.info(String.format("Got %s -> Expected %s", input.getPlanPhaseSpecifier().getPhaseType(), expected.getPlanPhaseSpecifier().getPhaseType()));
         assertEquals(input.getPlanPhaseSpecifier().getPhaseType(), expected.getPlanPhaseSpecifier().getPhaseType());
         log.info(String.format("Got %s -> Expected %s", input.getPlanPhaseSpecifier().getProductCategory(), expected.getPlanPhaseSpecifier().getProductCategory()));
-        assertEquals(input.getPlanPhaseSpecifier().getProductCategory(), expected.getPlanPhaseSpecifier().getProductCategory());                    
+        assertEquals(input.getPlanPhaseSpecifier().getProductCategory(), expected.getPlanPhaseSpecifier().getProductCategory());
         log.info(String.format("Got %s -> Expected %s", input.getPlanPhaseSpecifier().getPriceListName(), expected.getPlanPhaseSpecifier().getPriceListName()));
-        assertEquals(input.getPlanPhaseSpecifier().getPriceListName(), expected.getPlanPhaseSpecifier().getPriceListName());                    
+        assertEquals(input.getPlanPhaseSpecifier().getPriceListName(), expected.getPlanPhaseSpecifier().getPriceListName());
         log.info(String.format("Got %s -> Expected %s", input.getPlanPhaseSpecifier().getBillingPeriod(), expected.getPlanPhaseSpecifier().getBillingPeriod()));
         assertEquals(input.getPlanPhaseSpecifier().getBillingPeriod(), expected.getPlanPhaseSpecifier().getBillingPeriod());
         log.info(String.format("Got %s -> Expected %s", input.getEffectiveDate(), expected.getEffectiveDate()));
-        assertEquals(input.getEffectiveDate(), expected.getEffectiveDate());        
+        assertEquals(input.getEffectiveDate(), expected.getEffectiveDate());
     }
-    
+
     protected DeletedEvent createDeletedEvent(final UUID eventId) {
         return new DeletedEvent() {
             @Override
@@ -177,10 +184,12 @@ public abstract class TestApiBaseRepair extends TestApiBase {
             public SubscriptionTransitionType getSubscriptionTransitionType() {
                 return type;
             }
+
             @Override
             public DateTime getRequestedDate() {
                 return requestedDate;
             }
+
             @Override
             public PlanPhaseSpecifier getPlanPhaseSpecifier() {
                 return spec;
@@ -192,7 +201,7 @@ public abstract class TestApiBaseRepair extends TestApiBase {
         if (bundle.getSubscriptions() == null) {
             return;
         }
-        for (SubscriptionTimeline cur : bundle.getSubscriptions()) {
+        for (final SubscriptionTimeline cur : bundle.getSubscriptions()) {
             if (cur.getExistingEvents() != null) {
                 sortExistingEvent(cur.getExistingEvents());
             }
@@ -205,15 +214,16 @@ public abstract class TestApiBaseRepair extends TestApiBase {
     protected void sortExistingEvent(final List<ExistingEvent> events) {
         Collections.sort(events, new Comparator<ExistingEvent>() {
             @Override
-            public int compare(ExistingEvent arg0, ExistingEvent arg1) {
+            public int compare(final ExistingEvent arg0, final ExistingEvent arg1) {
                 return arg0.getEffectiveDate().compareTo(arg1.getEffectiveDate());
             }
         });
     }
+
     protected void sortNewEvent(final List<NewEvent> events) {
         Collections.sort(events, new Comparator<NewEvent>() {
             @Override
-            public int compare(NewEvent arg0, NewEvent arg1) {
+            public int compare(final NewEvent arg0, final NewEvent arg1) {
                 return arg0.getRequestedDate().compareTo(arg1.getRequestedDate());
             }
         });
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
index e001fe2..af685e4 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
@@ -15,11 +15,6 @@
  */
 package com.ning.billing.entitlement.api.timeline;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
@@ -52,6 +47,11 @@ import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.api.user.SubscriptionEvents;
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
 public class TestRepairBP extends TestApiBaseRepair {
 
     @Override
@@ -59,294 +59,294 @@ public class TestRepairBP extends TestApiBaseRepair {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
-    @Test(groups={"slow"})
-    public void testFetchBundleRepair() throws Exception  {
+    @Test(groups = {"slow"})
+    public void testFetchBundleRepair() throws Exception {
 
         log.info("Starting testFetchBundleRepair");
-        
-        String baseProduct = "Shotgun";
-        BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-        String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+        final String baseProduct = "Shotgun";
+        final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+        final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
         // CREATE BP
-        Subscription baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
+        final Subscription baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
 
-        String aoProduct = "Telescopic-Scope";
-        BillingPeriod aoTerm = BillingPeriod.MONTHLY;
-        String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+        final String aoProduct = "Telescopic-Scope";
+        final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
+        final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
-        SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
+        final SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
 
-        BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
-        List<SubscriptionTimeline> subscriptionRepair = bundleRepair.getSubscriptions();
+        final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+        final List<SubscriptionTimeline> subscriptionRepair = bundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 2);
 
-        for (SubscriptionTimeline cur : subscriptionRepair) {
+        for (final SubscriptionTimeline cur : subscriptionRepair) {
             assertNull(cur.getDeletedEvents());
-            assertNull(cur.getNewEvents());                
+            assertNull(cur.getNewEvents());
 
-            List<ExistingEvent> events = cur.getExistingEvents();
+            final List<ExistingEvent> events = cur.getExistingEvents();
             assertEquals(events.size(), 2);
             sortExistingEvent(events);
 
             assertEquals(events.get(0).getSubscriptionTransitionType(), SubscriptionTransitionType.CREATE);
-            assertEquals(events.get(1).getSubscriptionTransitionType(), SubscriptionTransitionType.PHASE);                    
+            assertEquals(events.get(1).getSubscriptionTransitionType(), SubscriptionTransitionType.PHASE);
             final boolean isBP = cur.getId().equals(baseSubscription.getId());
             if (isBP) {
                 assertEquals(cur.getId(), baseSubscription.getId());
 
                 assertEquals(events.get(0).getPlanPhaseSpecifier().getProductName(), baseProduct);
                 assertEquals(events.get(0).getPlanPhaseSpecifier().getPhaseType(), PhaseType.TRIAL);
-                assertEquals(events.get(0).getPlanPhaseSpecifier().getProductCategory(),ProductCategory.BASE);                    
-                assertEquals(events.get(0).getPlanPhaseSpecifier().getPriceListName(), basePriceList);                    
+                assertEquals(events.get(0).getPlanPhaseSpecifier().getProductCategory(), ProductCategory.BASE);
+                assertEquals(events.get(0).getPlanPhaseSpecifier().getPriceListName(), basePriceList);
                 assertEquals(events.get(0).getPlanPhaseSpecifier().getBillingPeriod(), BillingPeriod.NO_BILLING_PERIOD);
 
                 assertEquals(events.get(1).getPlanPhaseSpecifier().getProductName(), baseProduct);
                 assertEquals(events.get(1).getPlanPhaseSpecifier().getPhaseType(), PhaseType.EVERGREEN);
-                assertEquals(events.get(1).getPlanPhaseSpecifier().getProductCategory(),ProductCategory.BASE);                    
-                assertEquals(events.get(1).getPlanPhaseSpecifier().getPriceListName(), basePriceList);                    
+                assertEquals(events.get(1).getPlanPhaseSpecifier().getProductCategory(), ProductCategory.BASE);
+                assertEquals(events.get(1).getPlanPhaseSpecifier().getPriceListName(), basePriceList);
                 assertEquals(events.get(1).getPlanPhaseSpecifier().getBillingPeriod(), baseTerm);
             } else {
                 assertEquals(cur.getId(), aoSubscription.getId());
 
                 assertEquals(events.get(0).getPlanPhaseSpecifier().getProductName(), aoProduct);
-                assertEquals(events.get(0).getPlanPhaseSpecifier().getPhaseType(), PhaseType.DISCOUNT);                    
-                assertEquals(events.get(0).getPlanPhaseSpecifier().getProductCategory(),ProductCategory.ADD_ON); 
-                assertEquals(events.get(0).getPlanPhaseSpecifier().getPriceListName(), aoPriceList); 
-                assertEquals(events.get(1).getPlanPhaseSpecifier().getBillingPeriod(), aoTerm);                    
+                assertEquals(events.get(0).getPlanPhaseSpecifier().getPhaseType(), PhaseType.DISCOUNT);
+                assertEquals(events.get(0).getPlanPhaseSpecifier().getProductCategory(), ProductCategory.ADD_ON);
+                assertEquals(events.get(0).getPlanPhaseSpecifier().getPriceListName(), aoPriceList);
+                assertEquals(events.get(1).getPlanPhaseSpecifier().getBillingPeriod(), aoTerm);
 
                 assertEquals(events.get(1).getPlanPhaseSpecifier().getProductName(), aoProduct);
-                assertEquals(events.get(1).getPlanPhaseSpecifier().getPhaseType(), PhaseType.EVERGREEN);                    
-                assertEquals(events.get(1).getPlanPhaseSpecifier().getProductCategory(),ProductCategory.ADD_ON); 
-                assertEquals(events.get(1).getPlanPhaseSpecifier().getPriceListName(), aoPriceList);  
-                assertEquals(events.get(1).getPlanPhaseSpecifier().getBillingPeriod(), aoTerm);                    
+                assertEquals(events.get(1).getPlanPhaseSpecifier().getPhaseType(), PhaseType.EVERGREEN);
+                assertEquals(events.get(1).getPlanPhaseSpecifier().getProductCategory(), ProductCategory.ADD_ON);
+                assertEquals(events.get(1).getPlanPhaseSpecifier().getPriceListName(), aoPriceList);
+                assertEquals(events.get(1).getPlanPhaseSpecifier().getBillingPeriod(), aoTerm);
             }
         }
         assertListenerStatus();
     }
-    
+
     //TODO MDW: Temporary disable need to look at this with Stephane
-    @Test(groups={"slow"}, enabled = false)
+    @Test(groups = {"slow"}, enabled = false)
     public void testBPRepairWithCancellationOnstart() throws Exception {
 
         log.info("Starting testBPRepairWithCancellationOnstart");
-        
-        String baseProduct = "Shotgun";
-        DateTime startDate = clock.getUTCNow();
-         
+
+        final String baseProduct = "Shotgun";
+        final DateTime startDate = clock.getUTCNow();
+
         // CREATE BP
-        Subscription baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
+        final Subscription baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
 
         // Stays in trial-- for instance
-        Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(10));
+        final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(10));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
         sortEventsOnBundle(bundleRepair);
 
-        List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+        final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
         des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));
-        NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, baseSubscription.getStartDate(), null);
+        final NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, baseSubscription.getStartDate(), null);
+
+        final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
 
-        SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
-        
         // FIRST ISSUE DRY RUN
-        BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
-        
+        final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+
         boolean dryRun = true;
-        BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
         sortEventsOnBundle(dryRunBundleRepair);
         List<SubscriptionTimeline> subscriptionRepair = dryRunBundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 1);
         SubscriptionTimeline cur = subscriptionRepair.get(0);
         int index = 0;
-        List<ExistingEvent> events = subscriptionRepair.get(0).getExistingEvents();
+        final List<ExistingEvent> events = subscriptionRepair.get(0).getExistingEvents();
         assertEquals(events.size(), 2);
-        List<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+        final List<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, baseProduct, PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, baseProduct, PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD,baseSubscription.getStartDate()));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
 
-        for (ExistingEvent e : expected) {
-           validateExistingEventForAssertion(e, events.get(index++));           
+        for (final ExistingEvent e : expected) {
+            validateExistingEventForAssertion(e, events.get(index++));
         }
-        
-        SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
-        
+
+        final SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
         assertEquals(dryRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         assertEquals(dryRunBaseSubscription.getBundleId(), bundle.getId());
         assertEquals(dryRunBaseSubscription.getStartDate(), baseSubscription.getStartDate());
 
-        Plan currentPlan = dryRunBaseSubscription.getCurrentPlan();
+        final Plan currentPlan = dryRunBaseSubscription.getCurrentPlan();
         assertNotNull(currentPlan);
         assertEquals(currentPlan.getProduct().getName(), baseProduct);
         assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
         assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
 
-        PlanPhase currentPhase = dryRunBaseSubscription.getCurrentPhase();
+        final PlanPhase currentPhase = dryRunBaseSubscription.getCurrentPhase();
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
-        
-       // SECOND RE-ISSUE CALL-- NON DRY RUN
+
+        // SECOND RE-ISSUE CALL-- NON DRY RUN
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
         assertTrue(testListener.isCompleted(5000));
-        
+
         subscriptionRepair = realRunBundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 1);
         cur = subscriptionRepair.get(0);
         assertEquals(cur.getId(), baseSubscription.getId());
         index = 0;
-        for (ExistingEvent e : expected) {
-           validateExistingEventForAssertion(e, events.get(index++));           
+        for (final ExistingEvent e : expected) {
+            validateExistingEventForAssertion(e, events.get(index++));
         }
-        SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(realRunBaseSubscription.getAllTransitions().size(), 2);
-        
-        
+
+
         assertEquals(realRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
         assertEquals(realRunBaseSubscription.getBundleId(), bundle.getId());
         assertEquals(realRunBaseSubscription.getStartDate(), startDate);
 
         assertEquals(realRunBaseSubscription.getState(), SubscriptionState.CANCELLED);
-        
+
         assertListenerStatus();
     }
-    
-    @Test(groups={"slow"})
+
+    @Test(groups = {"slow"})
     public void testBPRepairReplaceCreateBeforeTrial() throws Exception {
-        
+
         log.info("Starting testBPRepairReplaceCreateBeforeTrial");
-        
-        String baseProduct = "Shotgun";
-        String newBaseProduct = "Assault-Rifle";
-        
-        DateTime startDate = clock.getUTCNow();
-        int clockShift = -1;
-        DateTime restartDate =  startDate.plusDays(clockShift).minusDays(1);
-        LinkedList<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
-        
+
+        final String baseProduct = "Shotgun";
+        final String newBaseProduct = "Assault-Rifle";
+
+        final DateTime startDate = clock.getUTCNow();
+        final int clockShift = -1;
+        final DateTime restartDate = startDate.plusDays(clockShift).minusDays(1);
+        final LinkedList<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, newBaseProduct, PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, restartDate));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, restartDate));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, newBaseProduct, PhaseType.EVERGREEN,
-                    ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, restartDate.plusDays(30)));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, restartDate.plusDays(30)));
 
         testBPRepairCreate(true, startDate, clockShift, baseProduct, newBaseProduct, expected);
         assertListenerStatus();
     }
 
-    @Test(groups={"slow"}, enabled=true)
+    @Test(groups = {"slow"}, enabled = true)
     public void testBPRepairReplaceCreateInTrial() throws Exception {
-        
+
         log.info("Starting testBPRepairReplaceCreateInTrial");
-        
-        String baseProduct = "Shotgun";
-        String newBaseProduct = "Assault-Rifle";
-        
-        DateTime startDate = clock.getUTCNow();
-        int clockShift = 10;
-        DateTime restartDate =  startDate.plusDays(clockShift).minusDays(1);
-        LinkedList<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
-        
+
+        final String baseProduct = "Shotgun";
+        final String newBaseProduct = "Assault-Rifle";
+
+        final DateTime startDate = clock.getUTCNow();
+        final int clockShift = 10;
+        final DateTime restartDate = startDate.plusDays(clockShift).minusDays(1);
+        final LinkedList<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, newBaseProduct, PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, restartDate));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, restartDate));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, newBaseProduct, PhaseType.EVERGREEN,
-                    ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, restartDate.plusDays(30)));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, restartDate.plusDays(30)));
+
+        final UUID baseSubscriptionId = testBPRepairCreate(true, startDate, clockShift, baseProduct, newBaseProduct, expected);
 
-        UUID baseSubscriptionId = testBPRepairCreate(true, startDate, clockShift, baseProduct, newBaseProduct, expected);
-        
         testListener.pushExpectedEvent(NextEvent.PHASE);
-        Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
+        final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(testListener.isCompleted(5000));
-        
+
         // CHECK WHAT"S GOING ON AFTER WE MOVE CLOCK-- FUTURE MOTIFICATION SHOULD KICK IN
-        SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId);
-        
+        final SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId);
+
         assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
         assertEquals(subscription.getBundleId(), bundle.getId());
         assertEquals(subscription.getStartDate(), restartDate);
-        assertEquals(subscription.getBundleStartDate(), restartDate);        
+        assertEquals(subscription.getBundleStartDate(), restartDate);
 
-        Plan currentPlan = subscription.getCurrentPlan();
+        final Plan currentPlan = subscription.getCurrentPlan();
         assertNotNull(currentPlan);
         assertEquals(currentPlan.getProduct().getName(), newBaseProduct);
         assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
         assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
 
-        PlanPhase currentPhase = subscription.getCurrentPhase();
+        final PlanPhase currentPhase = subscription.getCurrentPhase();
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
-        
+
         assertListenerStatus();
     }
 
-    
-    @Test(groups={"slow"})
+
+    @Test(groups = {"slow"})
     public void testBPRepairReplaceCreateAfterTrial() throws Exception {
-        
+
         log.info("Starting testBPRepairReplaceCreateAfterTrial");
-        
-        String baseProduct = "Shotgun";
-        String newBaseProduct = "Assault-Rifle";
-        
-        DateTime startDate = clock.getUTCNow();
-        int clockShift = 40;
-        DateTime restartDate =  startDate.plusDays(clockShift).minusDays(1);
-        LinkedList<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
-        
+
+        final String baseProduct = "Shotgun";
+        final String newBaseProduct = "Assault-Rifle";
+
+        final DateTime startDate = clock.getUTCNow();
+        final int clockShift = 40;
+        final DateTime restartDate = startDate.plusDays(clockShift).minusDays(1);
+        final LinkedList<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, newBaseProduct, PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, restartDate));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, restartDate));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, newBaseProduct, PhaseType.EVERGREEN,
-                    ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, restartDate.plusDays(30)));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, restartDate.plusDays(30)));
 
         testBPRepairCreate(false, startDate, clockShift, baseProduct, newBaseProduct, expected);
         assertListenerStatus();
     }
-    
-    
-    private UUID testBPRepairCreate(boolean inTrial, DateTime startDate, int clockShift, 
-            String baseProduct, String newBaseProduct, List<ExistingEvent> expectedEvents) throws Exception {
+
+
+    private UUID testBPRepairCreate(final boolean inTrial, final DateTime startDate, final int clockShift,
+                                    final String baseProduct, final String newBaseProduct, final List<ExistingEvent> expectedEvents) throws Exception {
 
         log.info("Starting testBPRepairCreate");
-        
+
         // CREATE BP
-        Subscription baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
+        final Subscription baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
 
         // MOVE CLOCK
         if (clockShift > 0) {
             if (!inTrial) {
                 testListener.pushExpectedEvent(NextEvent.PHASE);
-            }               
-            
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(clockShift));
+            }
+
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(clockShift));
             clock.addDeltaFromReality(it.toDurationMillis());
             if (!inTrial) {
                 assertTrue(testListener.isCompleted(5000));
             }
         }
 
-        BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
         sortEventsOnBundle(bundleRepair);
-        
-        DateTime newCreateTime = baseSubscription.getStartDate().plusDays(clockShift - 1);
 
-        PlanPhaseSpecifier spec = new PlanPhaseSpecifier(newBaseProduct, ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
+        final DateTime newCreateTime = baseSubscription.getStartDate().plusDays(clockShift - 1);
+
+        final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(newBaseProduct, ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
 
-        NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, newCreateTime, spec);
-        List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+        final NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, newCreateTime, spec);
+        final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
         des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));
         des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));
 
-        SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
-        
+        final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
+
         // FIRST ISSUE DRY RUN
-        BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
-        
-        boolean dryRun = true;        
-        BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+
+        boolean dryRun = true;
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
         List<SubscriptionTimeline> subscriptionRepair = dryRunBundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 1);
         SubscriptionTimeline cur = subscriptionRepair.get(0);
@@ -355,11 +355,11 @@ public class TestRepairBP extends TestApiBaseRepair {
         List<ExistingEvent> events = cur.getExistingEvents();
         assertEquals(expectedEvents.size(), events.size());
         int index = 0;
-        for (ExistingEvent e : expectedEvents) {
-           validateExistingEventForAssertion(e, events.get(index++));           
+        for (final ExistingEvent e : expectedEvents) {
+            validateExistingEventForAssertion(e, events.get(index++));
         }
-        SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
-        
+        final SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
         assertEquals(dryRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         assertEquals(dryRunBaseSubscription.getBundleId(), bundle.getId());
         assertEquals(dryRunBaseSubscription.getStartDate(), baseSubscription.getStartDate());
@@ -377,11 +377,11 @@ public class TestRepairBP extends TestApiBaseRepair {
         } else {
             assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
         }
-        
-       // SECOND RE-ISSUE CALL-- NON DRY RUN
+
+        // SECOND RE-ISSUE CALL-- NON DRY RUN
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
         assertTrue(testListener.isCompleted(5000));
         subscriptionRepair = realRunBundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 1);
@@ -389,18 +389,18 @@ public class TestRepairBP extends TestApiBaseRepair {
         assertEquals(cur.getId(), baseSubscription.getId());
 
         events = cur.getExistingEvents();
-        for (ExistingEvent e : events) {
-            log.info(String.format("%s, %s, %s, %s", e.getSubscriptionTransitionType(), e.getEffectiveDate(), e.getPlanPhaseSpecifier().getProductName(),  e.getPlanPhaseSpecifier().getPhaseType()));
+        for (final ExistingEvent e : events) {
+            log.info(String.format("%s, %s, %s, %s", e.getSubscriptionTransitionType(), e.getEffectiveDate(), e.getPlanPhaseSpecifier().getProductName(), e.getPlanPhaseSpecifier().getPhaseType()));
         }
         assertEquals(events.size(), expectedEvents.size());
         index = 0;
-        for (ExistingEvent e : expectedEvents) {
-           validateExistingEventForAssertion(e, events.get(index++));           
+        for (final ExistingEvent e : expectedEvents) {
+            validateExistingEventForAssertion(e, events.get(index++));
         }
-        SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(realRunBaseSubscription.getAllTransitions().size(), 2);
-        
-        
+
+
         assertEquals(realRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
         assertEquals(realRunBaseSubscription.getBundleId(), bundle.getId());
         assertEquals(realRunBaseSubscription.getStartDate(), newCreateTime);
@@ -414,133 +414,133 @@ public class TestRepairBP extends TestApiBaseRepair {
         currentPhase = realRunBaseSubscription.getCurrentPhase();
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
-        
+
         return baseSubscription.getId();
     }
 
-    @Test(groups={"slow"})
+    @Test(groups = {"slow"})
     public void testBPRepairAddChangeInTrial() throws Exception {
-        
+
         log.info("Starting testBPRepairAddChangeInTrial");
-        
-        String baseProduct = "Shotgun";
-        String newBaseProduct = "Assault-Rifle";
-        
-        DateTime startDate = clock.getUTCNow();
-        int clockShift = 10;
-        DateTime changeDate =  startDate.plusDays(clockShift).minusDays(1);
-        LinkedList<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
-        
+
+        final String baseProduct = "Shotgun";
+        final String newBaseProduct = "Assault-Rifle";
+
+        final DateTime startDate = clock.getUTCNow();
+        final int clockShift = 10;
+        final DateTime changeDate = startDate.plusDays(clockShift).minusDays(1);
+        final LinkedList<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, baseProduct, PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, startDate));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, startDate));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CHANGE, newBaseProduct, PhaseType.TRIAL,
-                    ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, changeDate));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, changeDate));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, newBaseProduct, PhaseType.EVERGREEN,
-                    ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, startDate.plusDays(30)));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, startDate.plusDays(30)));
+
+        final UUID baseSubscriptionId = testBPRepairAddChange(true, startDate, clockShift, baseProduct, newBaseProduct, expected, 3);
 
-        UUID baseSubscriptionId = testBPRepairAddChange(true, startDate, clockShift, baseProduct, newBaseProduct, expected, 3);
-        
         // CHECK WHAT"S GOING ON AFTER WE MOVE CLOCK-- FUTURE MOTIFICATION SHOULD KICK IN
         testListener.pushExpectedEvent(NextEvent.PHASE);
-        Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
+        final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(testListener.isCompleted(5000));
-        SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId);
-        
+        final SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscriptionId);
+
         assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
         assertEquals(subscription.getBundleId(), bundle.getId());
         assertEquals(subscription.getStartDate(), startDate);
-        assertEquals(subscription.getBundleStartDate(), startDate);        
+        assertEquals(subscription.getBundleStartDate(), startDate);
 
-        Plan currentPlan = subscription.getCurrentPlan();
+        final Plan currentPlan = subscription.getCurrentPlan();
         assertNotNull(currentPlan);
         assertEquals(currentPlan.getProduct().getName(), newBaseProduct);
         assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
         assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
 
-        PlanPhase currentPhase = subscription.getCurrentPhase();
+        final PlanPhase currentPhase = subscription.getCurrentPhase();
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
-        
+
         assertListenerStatus();
     }
 
-    @Test(groups={"slow"})
+    @Test(groups = {"slow"})
     public void testBPRepairAddChangeAfterTrial() throws Exception {
-        
+
         log.info("Starting testBPRepairAddChangeAfterTrial");
-        
-        String baseProduct = "Shotgun";
-        String newBaseProduct = "Assault-Rifle";
-        
-        DateTime startDate = clock.getUTCNow();
-        int clockShift = 40;
-        DateTime changeDate =  startDate.plusDays(clockShift).minusDays(1);
-        
-        LinkedList<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+
+        final String baseProduct = "Shotgun";
+        final String newBaseProduct = "Assault-Rifle";
+
+        final DateTime startDate = clock.getUTCNow();
+        final int clockShift = 40;
+        final DateTime changeDate = startDate.plusDays(clockShift).minusDays(1);
+
+        final LinkedList<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, baseProduct, PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, startDate));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, startDate));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, baseProduct, PhaseType.EVERGREEN,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, startDate.plusDays(30)));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, startDate.plusDays(30)));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CHANGE, newBaseProduct, PhaseType.EVERGREEN,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, changeDate));
+                                                     ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, changeDate));
         testBPRepairAddChange(false, startDate, clockShift, baseProduct, newBaseProduct, expected, 3);
-    
+
         assertListenerStatus();
     }
-    
 
-    private UUID testBPRepairAddChange(boolean inTrial, DateTime startDate, int clockShift, 
-            String baseProduct, String newBaseProduct, List<ExistingEvent> expectedEvents, int expectedTransitions) throws Exception {
 
-        
+    private UUID testBPRepairAddChange(final boolean inTrial, final DateTime startDate, final int clockShift,
+                                       final String baseProduct, final String newBaseProduct, final List<ExistingEvent> expectedEvents, final int expectedTransitions) throws Exception {
+
+
         // CREATE BP
-        Subscription baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
+        final Subscription baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
 
         // MOVE CLOCK
         if (!inTrial) {
             testListener.pushExpectedEvent(NextEvent.PHASE);
-        }               
-        
-        Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(clockShift));
+        }
+
+        final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(clockShift));
         clock.addDeltaFromReality(it.toDurationMillis());
         if (!inTrial) {
             assertTrue(testListener.isCompleted(5000));
         }
 
-        BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
         sortEventsOnBundle(bundleRepair);
-        
-        DateTime changeTime = baseSubscription.getStartDate().plusDays(clockShift - 1);
 
-        PlanPhaseSpecifier spec = new PlanPhaseSpecifier(newBaseProduct, ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
+        final DateTime changeTime = baseSubscription.getStartDate().plusDays(clockShift - 1);
+
+        final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(newBaseProduct, ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
 
-        NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, changeTime, spec);
-        List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+        final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, changeTime, spec);
+        final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
         if (inTrial) {
             des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));
         }
-        SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
-        
+        final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
+
         // FIRST ISSUE DRY RUN
-        BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
-        
+        final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+
         boolean dryRun = true;
-        BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
-        
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+
         List<SubscriptionTimeline> subscriptionRepair = dryRunBundleRepair.getSubscriptions();
         assertEquals(subscriptionRepair.size(), 1);
         SubscriptionTimeline cur = subscriptionRepair.get(0);
         assertEquals(cur.getId(), baseSubscription.getId());
 
         List<ExistingEvent> events = cur.getExistingEvents();
-       assertEquals(expectedEvents.size(), events.size());
-       int index = 0;
-       for (ExistingEvent e : expectedEvents) {
-           validateExistingEventForAssertion(e, events.get(index++));           
-       }
-        SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
-        
+        assertEquals(expectedEvents.size(), events.size());
+        int index = 0;
+        for (final ExistingEvent e : expectedEvents) {
+            validateExistingEventForAssertion(e, events.get(index++));
+        }
+        final SubscriptionData dryRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
         assertEquals(dryRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         assertEquals(dryRunBaseSubscription.getBundleId(), bundle.getId());
         assertEquals(dryRunBaseSubscription.getStartDate(), baseSubscription.getStartDate());
@@ -558,12 +558,12 @@ public class TestRepairBP extends TestApiBaseRepair {
         } else {
             assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
         }
-        
-        
-       // SECOND RE-ISSUE CALL-- NON DRY RUN
+
+
+        // SECOND RE-ISSUE CALL-- NON DRY RUN
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
         assertTrue(testListener.isCompleted(5000));
 
         subscriptionRepair = realRunBundleRepair.getSubscriptions();
@@ -574,13 +574,13 @@ public class TestRepairBP extends TestApiBaseRepair {
         events = cur.getExistingEvents();
         assertEquals(expectedEvents.size(), events.size());
         index = 0;
-        for (ExistingEvent e : expectedEvents) {
-           validateExistingEventForAssertion(e, events.get(index++));           
+        for (final ExistingEvent e : expectedEvents) {
+            validateExistingEventForAssertion(e, events.get(index++));
         }
-        SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        final SubscriptionData realRunBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(realRunBaseSubscription.getAllTransitions().size(), expectedTransitions);
-        
-        
+
+
         assertEquals(realRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
         assertEquals(realRunBaseSubscription.getBundleId(), bundle.getId());
         assertEquals(realRunBaseSubscription.getStartDate(), baseSubscription.getStartDate());
@@ -600,64 +600,64 @@ public class TestRepairBP extends TestApiBaseRepair {
         }
         return baseSubscription.getId();
     }
-    
-    @Test(groups={"slow"})
+
+    @Test(groups = {"slow"})
     public void testRepairWithFurureCancelEvent() throws Exception {
-      
+
         log.info("Starting testRepairWithFurureCancelEvent");
-        
-        DateTime startDate = clock.getUTCNow();
-        
+
+        final DateTime startDate = clock.getUTCNow();
+
         // CREATE BP
         Subscription baseSubscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
 
         // MOVE CLOCK -- OUT OF TRIAL
         testListener.pushExpectedEvent(NextEvent.PHASE);
-        
-        Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(35));
+
+        final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(35));
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(testListener.isCompleted(5000));
-        
+
         // SET CTD to BASE SUBSCRIPTION SP CANCEL OCCURS EOT
-        DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
+        final DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
         billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, context);
         baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
 
-        
-        DateTime requestedChange = clock.getUTCNow();
+
+        final DateTime requestedChange = clock.getUTCNow();
         baseSubscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, requestedChange, context);
-        
-        
+
+
         // CHECK CHANGE DID NOT OCCUR YET
         Plan currentPlan = baseSubscription.getCurrentPlan();
         assertNotNull(currentPlan);
         assertEquals(currentPlan.getProduct().getName(), "Shotgun");
         assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
         assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
-        
-        
-        DateTime repairTime = clock.getUTCNow().minusDays(1);
-        BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+
+
+        final DateTime repairTime = clock.getUTCNow().minusDays(1);
+        final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
         sortEventsOnBundle(bundleRepair);
-        
-        PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
 
-        NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, repairTime, spec);
-        List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+        final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+
+        final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, repairTime, spec);
+        final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
         des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(2).getEventId()));
 
-        SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
-        
+        final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
+
         // SKIP DRY RUN AND DO REPAIR...
-        BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
-        
-        boolean dryRun = false;
+        final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+
+        final boolean dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
         repairApi.repairBundle(bRepair, dryRun, context);
         assertTrue(testListener.isCompleted(5000));
-     
+
         baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
-        
+
         assertEquals(((SubscriptionData) baseSubscription).getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
         assertEquals(baseSubscription.getBundleId(), bundle.getId());
         assertEquals(baseSubscription.getStartDate(), baseSubscription.getStartDate());
@@ -668,82 +668,82 @@ public class TestRepairBP extends TestApiBaseRepair {
         assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
         assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
 
-        PlanPhase currentPhase = baseSubscription.getCurrentPhase();
+        final PlanPhase currentPhase = baseSubscription.getCurrentPhase();
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
-        
+
         assertListenerStatus();
     }
-    
-    
+
+
     // Needs real SQL backend to be tested properly
-    @Test(groups={"slow"})
+    @Test(groups = {"slow"})
     public void testENT_REPAIR_VIEW_CHANGED_newEvent() throws Exception {
-       
+
         log.info("Starting testENT_REPAIR_VIEW_CHANGED_newEvent");
-        
-        TestWithException test = new TestWithException();
-        DateTime startDate = clock.getUTCNow();
-        
+
+        final TestWithException test = new TestWithException();
+        final DateTime startDate = clock.getUTCNow();
+
         final Subscription baseSubscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
 
-                BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
                 sortEventsOnBundle(bundleRepair);
-                PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-                NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
-                List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
-                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));                
-                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));                                
-                SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
+                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+                final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
+                final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));
+                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));
+                final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
 
-                BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+                final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
                 testListener.pushExpectedEvent(NextEvent.CHANGE);
-                DateTime changeTime = clock.getUTCNow();
+                final DateTime changeTime = clock.getUTCNow();
                 baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, context);
                 assertTrue(testListener.isCompleted(5000));
-                
+
                 repairApi.repairBundle(bRepair, true, context);
                 assertListenerStatus();
             }
         }, ErrorCode.ENT_REPAIR_VIEW_CHANGED);
     }
 
-    @Test(groups={"slow"}, enabled=false)
+    @Test(groups = {"slow"}, enabled = false)
     public void testENT_REPAIR_VIEW_CHANGED_ctd() throws Exception {
-       
+
         log.info("Starting testENT_REPAIR_VIEW_CHANGED_ctd");
-        
-        TestWithException test = new TestWithException();
-        DateTime startDate = clock.getUTCNow();
-        
+
+        final TestWithException test = new TestWithException();
+        final DateTime startDate = clock.getUTCNow();
+
         final Subscription baseSubscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
 
-                BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
                 sortEventsOnBundle(bundleRepair);
-                PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-                NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
-                List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
-                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));                
-                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));                                
-                SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
+                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+                final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
+                final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));
+                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));
+                final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
 
-                BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+                final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
-                DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
+                final DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
                 billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, context);
                 entitlementApi.getSubscriptionFromId(baseSubscription.getId());
 
                 repairApi.repairBundle(bRepair, true, context);
-                
+
                 assertListenerStatus();
             }
         }, ErrorCode.ENT_REPAIR_VIEW_CHANGED);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
index e3156bd..85116a3 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithAO.java
@@ -19,10 +19,6 @@ import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
 import org.testng.annotations.Test;
@@ -47,32 +43,36 @@ import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.api.user.SubscriptionEvents;
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 public class TestRepairWithAO extends TestApiBaseRepair {
 
     @Override
     public Injector getInjector() {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
-    }    
+    }
 
-    @Test(groups={"slow"})
+    @Test(groups = {"slow"})
     public void testRepairChangeBPWithAddonIncluded() throws Exception {
-        
+
         log.info("Starting testRepairChangeBPWithAddonIncluded");
-        
-        String baseProduct = "Shotgun";
-        BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-        String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+        final String baseProduct = "Shotgun";
+        final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+        final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
         // CREATE BP
-        SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
+        final SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
 
         // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
         Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
-        
-        SubscriptionData aoSubscription2 = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+        final SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
+        final SubscriptionData aoSubscription2 = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
         // MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
@@ -80,32 +80,32 @@ public class TestRepairWithAO extends TestApiBaseRepair {
 
         BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
         sortEventsOnBundle(bundleRepair);
-        
+
         // Quick check
         SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
         assertEquals(bpRepair.getExistingEvents().size(), 2);
-        
+
         SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
 
         SubscriptionTimeline aoRepair2 = getSubscriptionRepair(aoSubscription2.getId(), bundleRepair);
         assertEquals(aoRepair2.getExistingEvents().size(), 2);
 
-        DateTime bpChangeDate = clock.getUTCNow().minusDays(1);
-        
-        List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
-        des.add(createDeletedEvent(bpRepair.getExistingEvents().get(1).getEventId()));        
-        
-        PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
-        NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, bpChangeDate, spec);
-        
+        final DateTime bpChangeDate = clock.getUTCNow().minusDays(1);
+
+        final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+        des.add(createDeletedEvent(bpRepair.getExistingEvents().get(1).getEventId()));
+
+        final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
+        final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, bpChangeDate, spec);
+
         bpRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
-        
-        bundleRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
-        
+
+        bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
+
         boolean dryRun = true;
-        BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
-                
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
 
@@ -113,234 +113,233 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         assertEquals(aoRepair.getExistingEvents().size(), 2);
 
         bpRepair = getSubscriptionRepair(baseSubscription.getId(), dryRunBundleRepair);
-        assertEquals(bpRepair.getExistingEvents().size(), 3);        
-        
+        assertEquals(bpRepair.getExistingEvents().size(), 3);
+
         // Check expected for AO
-        List<ExistingEvent> expectedAO = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+        final List<ExistingEvent> expectedAO = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
+                                                       ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
         expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, "Telescopic-Scope", PhaseType.DISCOUNT,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, bpChangeDate));
+                                                       ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, bpChangeDate));
         int index = 0;
-        for (ExistingEvent e : expectedAO) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedAO) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
 
-        List<ExistingEvent> expectedAO2 = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+        final List<ExistingEvent> expectedAO2 = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expectedAO2.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Laser-Scope", PhaseType.DISCOUNT,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription2.getStartDate()));
+                                                        ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription2.getStartDate()));
         expectedAO2.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Laser-Scope", PhaseType.EVERGREEN,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription2.getStartDate().plusMonths(1)));
+                                                        ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription2.getStartDate().plusMonths(1)));
         index = 0;
-        for (ExistingEvent e : expectedAO2) {
-           validateExistingEventForAssertion(e, aoRepair2.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedAO2) {
+            validateExistingEventForAssertion(e, aoRepair2.getExistingEvents().get(index++));
         }
-        
+
         // Check expected for BP        
-        List<ExistingEvent> expectedBP = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+        final List<ExistingEvent> expectedBP = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Shotgun", PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
+                                                       ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
         expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CHANGE, "Assault-Rifle", PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, bpChangeDate));
+                                                       ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, bpChangeDate));
         expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Assault-Rifle", PhaseType.EVERGREEN,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusDays(30)));
+                                                       ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusDays(30)));
         index = 0;
-        for (ExistingEvent e : expectedBP) {
-           validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedBP) {
+            validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
 
-        
-        SubscriptionData newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
-        SubscriptionData newAoSubscription2 = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription2.getId());
+        SubscriptionData newAoSubscription2 = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription2.getId());
         assertEquals(newAoSubscription2.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription2.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription2.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
-        
-        SubscriptionData newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
+        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
-        
-        dryRun = false;        
+
+        dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
         assertTrue(testListener.isCompleted(5000));
 
-        
-        
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
 
         bpRepair = getSubscriptionRepair(baseSubscription.getId(), realRunBundleRepair);
-        assertEquals(bpRepair.getExistingEvents().size(), 3);        
-        
+        assertEquals(bpRepair.getExistingEvents().size(), 3);
+
         index = 0;
-        for (ExistingEvent e : expectedAO) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedAO) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        
+
         index = 0;
-        for (ExistingEvent e : expectedAO2) {
-           validateExistingEventForAssertion(e, aoRepair2.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedAO2) {
+            validateExistingEventForAssertion(e, aoRepair2.getExistingEvents().get(index++));
         }
 
         index = 0;
-        for (ExistingEvent e : expectedBP) {
-           validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedBP) {
+            validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
 
-        newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
-            
-        newAoSubscription2 = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription2.getId());
+
+        newAoSubscription2 = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription2.getId());
         assertEquals(newAoSubscription2.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription2.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription2.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
-        
-        newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
+        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
     }
 
-    @Test(groups={"slow"})
+    @Test(groups = {"slow"})
     public void testRepairChangeBPWithAddonNonAvailable() throws Exception {
-        
+
         log.info("Starting testRepairChangeBPWithAddonNonAvailable");
-        
-        String baseProduct = "Shotgun";
-        BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-        String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+        final String baseProduct = "Shotgun";
+        final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+        final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
         // CREATE BP
-        SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
+        final SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
 
         // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
         Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
-        
+        final SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
         // MOVE CLOCK A LITTLE BIT MORE -- AFTER TRIAL
         testListener.pushExpectedEvent(NextEvent.PHASE);
         testListener.pushExpectedEvent(NextEvent.PHASE);
-        
+
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
         clock.addDeltaFromReality(it.toDurationMillis());
-        assertTrue(testListener.isCompleted(7000));        
+        assertTrue(testListener.isCompleted(7000));
 
         BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
         sortEventsOnBundle(bundleRepair);
-        
+
         // Quick check
         SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
         assertEquals(bpRepair.getExistingEvents().size(), 2);
-        
+
         SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
 
-        DateTime bpChangeDate = clock.getUTCNow().minusDays(1);
-        
-        PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-        NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, bpChangeDate, spec);
-        
+        final DateTime bpChangeDate = clock.getUTCNow().minusDays(1);
+
+        final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+        final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, bpChangeDate, spec);
+
         bpRepair = createSubscriptionRepair(baseSubscription.getId(), Collections.<SubscriptionTimeline.DeletedEvent>emptyList(), Collections.singletonList(ne));
-        
-        bundleRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
-        
+
+        bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
+
         boolean dryRun = true;
-        BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
-                
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 3);
 
         bpRepair = getSubscriptionRepair(baseSubscription.getId(), dryRunBundleRepair);
-        assertEquals(bpRepair.getExistingEvents().size(), 3);        
-        
+        assertEquals(bpRepair.getExistingEvents().size(), 3);
+
         // Check expected for AO
-        List<ExistingEvent> expectedAO = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+        final List<ExistingEvent> expectedAO = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
+                                                       ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
         expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.EVERGREEN,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusMonths(1)));
+                                                       ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusMonths(1)));
         expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, "Telescopic-Scope", PhaseType.EVERGREEN,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, bpChangeDate));
+                                                       ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, bpChangeDate));
         int index = 0;
-        for (ExistingEvent e : expectedAO) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedAO) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
 
         // Check expected for BP        
-        List<ExistingEvent> expectedBP = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+        final List<ExistingEvent> expectedBP = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Shotgun", PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
+                                                       ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
         expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Shotgun", PhaseType.EVERGREEN,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusDays(30)));
+                                                       ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusDays(30)));
         expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CHANGE, "Pistol", PhaseType.EVERGREEN,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, bpChangeDate));
+                                                       ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, bpChangeDate));
         index = 0;
-        for (ExistingEvent e : expectedBP) {
-           validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedBP) {
+            validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
-        
-        SubscriptionData newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
-        SubscriptionData newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
-        
+
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
         assertTrue(testListener.isCompleted(5000));
 
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 3);
 
         bpRepair = getSubscriptionRepair(baseSubscription.getId(), realRunBundleRepair);
-        assertEquals(bpRepair.getExistingEvents().size(), 3);        
-        
+        assertEquals(bpRepair.getExistingEvents().size(), 3);
+
         index = 0;
-        for (ExistingEvent e : expectedAO) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedAO) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        
+
         index = 0;
-        for (ExistingEvent e : expectedBP) {
-           validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedBP) {
+            validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
 
-        newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newAoSubscription.getAllTransitions().size(), 3);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
-            
-        newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
+        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
     }
 
-    @Test(groups={"slow"})
+    @Test(groups = {"slow"})
     public void testRepairCancelBP_EOT_WithAddons() throws Exception {
-        
+
         log.info("Starting testRepairCancelBP_EOT_WithAddons");
-        
-        String baseProduct = "Shotgun";
-        BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-        String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+        final String baseProduct = "Shotgun";
+        final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+        final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
         // CREATE BP
         SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
@@ -350,318 +349,317 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         clock.addDeltaFromReality(it.toDurationMillis());
 
 
-        SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
-        
+        final SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
         // MOVE CLOCK A LITTLE BIT MORE -- AFTER TRIAL
         testListener.pushExpectedEvent(NextEvent.PHASE);
         testListener.pushExpectedEvent(NextEvent.PHASE);
-        
+
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(testListener.isCompleted(7000));
-        
+
         // SET CTD to BASE SUBSCRIPTION SP CANCEL OCCURS EOT
-        DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
+        final DateTime newChargedThroughDate = baseSubscription.getStartDate().plusDays(30).plusMonths(1);
         billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, context);
         baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
 
         BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
         sortEventsOnBundle(bundleRepair);
-        
+
         // Quick check
         SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
         assertEquals(bpRepair.getExistingEvents().size(), 2);
-        
+
         SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
 
-        DateTime bpCancelDate = clock.getUTCNow().minusDays(1);
-        NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, bpCancelDate, null);
+        final DateTime bpCancelDate = clock.getUTCNow().minusDays(1);
+        final NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, bpCancelDate, null);
         bpRepair = createSubscriptionRepair(baseSubscription.getId(), Collections.<SubscriptionTimeline.DeletedEvent>emptyList(), Collections.singletonList(ne));
-        bundleRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
-        
+        bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(bpRepair));
+
         boolean dryRun = true;
-        BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
-                
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 3);
 
         bpRepair = getSubscriptionRepair(baseSubscription.getId(), dryRunBundleRepair);
-        assertEquals(bpRepair.getExistingEvents().size(), 3);        
-        
+        assertEquals(bpRepair.getExistingEvents().size(), 3);
+
         // Check expected for AO
-        List<ExistingEvent> expectedAO = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+        final List<ExistingEvent> expectedAO = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
+                                                       ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
         expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Telescopic-Scope", PhaseType.EVERGREEN,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusMonths(1)));
+                                                       ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusMonths(1)));
         expectedAO.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, "Telescopic-Scope", PhaseType.EVERGREEN,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, newChargedThroughDate));
+                                                       ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, newChargedThroughDate));
 
         int index = 0;
-        for (ExistingEvent e : expectedAO) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedAO) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
 
         // Check expected for BP        
-        List<ExistingEvent> expectedBP = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+        final List<ExistingEvent> expectedBP = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Shotgun", PhaseType.TRIAL,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
+                                                       ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.NO_BILLING_PERIOD, baseSubscription.getStartDate()));
         expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Shotgun", PhaseType.EVERGREEN,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusDays(30)));
+                                                       ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusDays(30)));
         expectedBP.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, "Shotgun", PhaseType.EVERGREEN,
-                ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, newChargedThroughDate));
+                                                       ProductCategory.BASE, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, newChargedThroughDate));
         index = 0;
-        for (ExistingEvent e : expectedBP) {
-           validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedBP) {
+            validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
-        
-        SubscriptionData newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
 
-        SubscriptionData newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
-        
+
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bundleRepair, dryRun, context);
         assertTrue(testListener.isCompleted(5000));
-        
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 3);
 
         bpRepair = getSubscriptionRepair(baseSubscription.getId(), realRunBundleRepair);
-        assertEquals(bpRepair.getExistingEvents().size(), 3);        
-        
+        assertEquals(bpRepair.getExistingEvents().size(), 3);
+
         index = 0;
-        for (ExistingEvent e : expectedAO) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedAO) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        
+
         index = 0;
-        for (ExistingEvent e : expectedBP) {
-           validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expectedBP) {
+            validateExistingEventForAssertion(e, bpRepair.getExistingEvents().get(index++));
         }
 
-        newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 3);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
-            
-        newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
+        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
-        
+
         // MOVE CLOCK AFTER CANCEL DATE
         testListener.pushExpectedEvent(NextEvent.CANCEL);
         testListener.pushExpectedEvent(NextEvent.CANCEL);
-        
+
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(32));
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(testListener.isCompleted(7000));
 
-        newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newAoSubscription.getAllTransitions().size(), 3);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
-            
-        newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
+        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(newBaseSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 3);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
     }
 
-    
-    
-    @Test(groups={"slow"})
+
+    @Test(groups = {"slow"})
     public void testRepairCancelAO() throws Exception {
-        
+
         log.info("Starting testRepairCancelAO");
-        
-        String baseProduct = "Shotgun";
-        BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-        String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+        final String baseProduct = "Shotgun";
+        final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+        final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
         // CREATE BP
-        SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
+        final SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
 
         // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
         Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+        final SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
         // MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
         sortEventsOnBundle(bundleRepair);
-        
+
         // Quick check
         SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
         assertEquals(bpRepair.getExistingEvents().size(), 2);
-        
+
         SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
-        
-
-        List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
-        des.add(createDeletedEvent(aoRepair.getExistingEvents().get(1).getEventId()));        
-        DateTime aoCancelDate = aoSubscription.getStartDate().plusDays(1);
-        
-        NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, aoCancelDate, null);
-        
-        SubscriptionTimeline saoRepair = createSubscriptionRepair(aoSubscription.getId(), des, Collections.singletonList(ne));
-        
-        BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
-        
+
+
+        final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+        des.add(createDeletedEvent(aoRepair.getExistingEvents().get(1).getEventId()));
+        final DateTime aoCancelDate = aoSubscription.getStartDate().plusDays(1);
+
+        final NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, aoCancelDate, null);
+
+        final SubscriptionTimeline saoRepair = createSubscriptionRepair(aoSubscription.getId(), des, Collections.singletonList(ne));
+
+        final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
+
         boolean dryRun = true;
-        BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
-        
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
-        
+
         bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
-        assertEquals(bpRepair.getExistingEvents().size(), 2);        
-        
-        List<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+        assertEquals(bpRepair.getExistingEvents().size(), 2);
+
+        final List<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
+                                                     ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CANCEL, "Telescopic-Scope", PhaseType.DISCOUNT,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoCancelDate));
+                                                     ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoCancelDate));
         int index = 0;
-        for (ExistingEvent e : expected) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expected) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        SubscriptionData newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
-                
-        SubscriptionData newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+
+        SubscriptionData newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
-        
+
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
         assertTrue(testListener.isCompleted(5000));
 
-        
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
         index = 0;
-        for (ExistingEvent e : expected) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expected) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        
-        newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.CANCELLED);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
-        assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);        
-                
-        newBaseSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(baseSubscription.getId());
+        assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
+
+        newBaseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
         assertEquals(newBaseSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newBaseSubscription.getAllTransitions().size(), 2);
         assertEquals(newBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
     }
-    
-    
-    @Test(groups={"slow"})
+
+
+    @Test(groups = {"slow"})
     public void testRepairRecreateAO() throws Exception {
-        
+
         log.info("Starting testRepairRecreateAO");
-        
-        String baseProduct = "Shotgun";
-        BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-        String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+        final String baseProduct = "Shotgun";
+        final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+        final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
         // CREATE BP
-        SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
+        final SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
 
         // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
         Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+        final SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
         // MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+        final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
         sortEventsOnBundle(bundleRepair);
-        
+
         // Quick check
-        SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+        final SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
         assertEquals(bpRepair.getExistingEvents().size(), 2);
-        
+
         SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
-        
 
-        List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
-        des.add(createDeletedEvent(aoRepair.getExistingEvents().get(0).getEventId()));        
+
+        final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+        des.add(createDeletedEvent(aoRepair.getExistingEvents().get(0).getEventId()));
         des.add(createDeletedEvent(aoRepair.getExistingEvents().get(1).getEventId()));
 
-        DateTime aoRecreateDate = aoSubscription.getStartDate().plusDays(1);
-        PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.DISCOUNT);
-        NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, aoRecreateDate, spec);
-        
-        SubscriptionTimeline saoRepair = createSubscriptionRepair(aoSubscription.getId(), des, Collections.singletonList(ne));
-        
-        BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
-        
+        final DateTime aoRecreateDate = aoSubscription.getStartDate().plusDays(1);
+        final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.DISCOUNT);
+        final NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, aoRecreateDate, spec);
+
+        final SubscriptionTimeline saoRepair = createSubscriptionRepair(aoSubscription.getId(), des, Collections.singletonList(ne));
+
+        final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
+
         boolean dryRun = true;
-        BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
-        
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
-        
-        
-        List<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+
+
+        final List<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoRecreateDate));
+                                                     ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoRecreateDate));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Telescopic-Scope", PhaseType.EVERGREEN,
-                    ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusMonths(1) /* Bundle align */));
+                                                     ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, baseSubscription.getStartDate().plusMonths(1) /* Bundle align */));
         int index = 0;
-        for (ExistingEvent e : expected) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expected) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        SubscriptionData newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getStartDate(), aoSubscription.getStartDate());
-        assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);        
-        
+        assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
+
         // NOW COMMIT
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
         assertTrue(testListener.isCompleted(5000));
-        
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
         index = 0;
-        for (ExistingEvent e : expected) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expected) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        
-        newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
         assertEquals(newAoSubscription.getStartDate(), aoRecreateDate);
-        assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);        
+        assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
 
     }
-    
+
     // Fasten your seatbelt here:
     //
     // We are doing repair for multi-phase tiered-addon with different alignment:
@@ -670,95 +668,95 @@ public class TestRepairWithAO extends TestApiBaseRepair {
     // . Both multi phase
     // . Telescopic-Scope (bundle align) and Laser-Scope is Subscription align
     //
-    @Test(groups={"slow"})
+    @Test(groups = {"slow"})
     public void testRepairChangeAOOK() throws Exception {
-        
+
         log.info("Starting testRepairChangeAOOK");
-        
-        String baseProduct = "Shotgun";
-        BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-        String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+        final String baseProduct = "Shotgun";
+        final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+        final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
         // CREATE BP
-        SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
+        final SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
 
         // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
         Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
         clock.addDeltaFromReality(it.toDurationMillis());
 
-        SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+        final SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
         // MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
         clock.addDeltaFromReality(it.toDurationMillis());
-        
-        BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+
+        final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
         sortEventsOnBundle(bundleRepair);
-        
+
         // Quick check
-        SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+        final SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
         assertEquals(bpRepair.getExistingEvents().size(), 2);
-        
+
         SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 2);
 
-        List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
-        des.add(createDeletedEvent(aoRepair.getExistingEvents().get(1).getEventId()));        
-        DateTime aoChangeDate = aoSubscription.getStartDate().plusDays(1);
-        PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
-        NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, aoChangeDate, spec);
-        
-        SubscriptionTimeline saoRepair = createSubscriptionRepair(aoSubscription.getId(), des, Collections.singletonList(ne));
-        
-        BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
-        
+        final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+        des.add(createDeletedEvent(aoRepair.getExistingEvents().get(1).getEventId()));
+        final DateTime aoChangeDate = aoSubscription.getStartDate().plusDays(1);
+        final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
+        final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, aoChangeDate, spec);
+
+        final SubscriptionTimeline saoRepair = createSubscriptionRepair(aoSubscription.getId(), des, Collections.singletonList(ne));
+
+        final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
+
         boolean dryRun = true;
-        BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
-        
+        final BundleTimeline dryRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), dryRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 3);
-        
-        
-        List<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
+
+
+        final List<ExistingEvent> expected = new LinkedList<SubscriptionTimeline.ExistingEvent>();
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CREATE, "Telescopic-Scope", PhaseType.DISCOUNT,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
+                                                     ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoSubscription.getStartDate()));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.CHANGE, "Laser-Scope", PhaseType.DISCOUNT,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoChangeDate));
+                                                     ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, aoChangeDate));
         expected.add(createExistingEventForAssertion(SubscriptionTransitionType.PHASE, "Laser-Scope", PhaseType.EVERGREEN,
-                ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY,
-                aoSubscription.getStartDate().plusMonths(1) /* Subscription alignment */));
-                
+                                                     ProductCategory.ADD_ON, PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY,
+                                                     aoSubscription.getStartDate().plusMonths(1) /* Subscription alignment */));
+
         int index = 0;
-        for (ExistingEvent e : expected) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expected) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        SubscriptionData newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+        SubscriptionData newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 2);
-        
+
         // AND NOW COMMIT
         dryRun = false;
         testListener.pushExpectedEvent(NextEvent.REPAIR_BUNDLE);
-        BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
+        final BundleTimeline realRunBundleRepair = repairApi.repairBundle(bRepair, dryRun, context);
         assertTrue(testListener.isCompleted(5000));
-        
+
         aoRepair = getSubscriptionRepair(aoSubscription.getId(), realRunBundleRepair);
         assertEquals(aoRepair.getExistingEvents().size(), 3);
         index = 0;
-        for (ExistingEvent e : expected) {
-           validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));           
+        for (final ExistingEvent e : expected) {
+            validateExistingEventForAssertion(e, aoRepair.getExistingEvents().get(index++));
         }
-        
-        newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         assertEquals(newAoSubscription.getState(), SubscriptionState.ACTIVE);
         assertEquals(newAoSubscription.getAllTransitions().size(), 3);
-        
-        
+
+
         assertEquals(newAoSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION + 1);
         assertEquals(newAoSubscription.getBundleId(), bundle.getId());
         assertEquals(newAoSubscription.getStartDate(), aoSubscription.getStartDate());
 
-        Plan currentPlan = newAoSubscription.getCurrentPlan();
+        final Plan currentPlan = newAoSubscription.getCurrentPlan();
         assertNotNull(currentPlan);
         assertEquals(currentPlan.getProduct().getName(), "Laser-Scope");
         assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.ADD_ON);
@@ -767,14 +765,14 @@ public class TestRepairWithAO extends TestApiBaseRepair {
         PlanPhase currentPhase = newAoSubscription.getCurrentPhase();
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
-        
+
         testListener.pushExpectedEvent(NextEvent.PHASE);
-        
+
         it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(60));
         clock.addDeltaFromReality(it.toDurationMillis());
         assertTrue(testListener.isCompleted(5000));
-        
-        newAoSubscription = (SubscriptionData)  entitlementApi.getSubscriptionFromId(aoSubscription.getId());
+
+        newAoSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(aoSubscription.getId());
         currentPhase = newAoSubscription.getCurrentPhase();
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java
index e95d1fa..7c61f4f 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairWithError.java
@@ -15,9 +15,6 @@
  */
 package com.ning.billing.entitlement.api.timeline;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
@@ -46,12 +43,15 @@ import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
 public class TestRepairWithError extends TestApiBaseRepair {
 
     private static final String baseProduct = "Shotgun";
     private TestWithException test;
     private Subscription baseSubscription;
-    private DateTime startDate;
+
     @Override
     public Injector getInjector() {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleMemory());
@@ -61,226 +61,226 @@ public class TestRepairWithError extends TestApiBaseRepair {
     public void setupTest() throws Exception {
         super.setupTest();
         test = new TestWithException();
-        startDate = clock.getUTCNow();
+        final DateTime startDate = clock.getUTCNow();
         baseSubscription = createSubscription(baseProduct, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, startDate);
     }
-  
-    @Test(groups={"fast"})
+
+    @Test(groups = {"fast"})
     public void testENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING() throws Exception {
-        
+
         log.info("Starting testENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING");
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException {
 
                 // MOVE AFTER TRIAL
                 testListener.pushExpectedEvent(NextEvent.PHASE);
-                
-                Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
+
+                final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
                 clock.addDeltaFromReality(it.toDurationMillis());
 
                 assertTrue(testListener.isCompleted(5000));
-                
-                BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+
+                final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
                 sortEventsOnBundle(bundleRepair);
-                PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-                NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
-                
-                SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), Collections.<DeletedEvent>emptyList(), Collections.singletonList(ne));
-                
-                BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+                final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
+
+                final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), Collections.<DeletedEvent>emptyList(), Collections.singletonList(ne));
+
+                final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
                 repairApi.repairBundle(bRepair, true, context);
             }
         }, ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_BP_REMAINING);
     }
-    
-    @Test(groups={"fast"})
+
+    @Test(groups = {"fast"})
     public void testENT_REPAIR_INVALID_DELETE_SET() throws Exception {
-        
+
         log.info("Starting testENT_REPAIR_INVALID_DELETE_SET");
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
 
                 Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
                 clock.addDeltaFromReality(it.toDurationMillis());
-                
+
                 testListener.pushExpectedEvent(NextEvent.CHANGE);
-                DateTime changeTime = clock.getUTCNow();
+                final DateTime changeTime = clock.getUTCNow();
                 baseSubscription.changePlan("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, changeTime, context);
                 assertTrue(testListener.isCompleted(5000));
-                
+
                 // MOVE AFTER TRIAL
                 testListener.pushExpectedEvent(NextEvent.PHASE);
                 it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
                 clock.addDeltaFromReality(it.toDurationMillis());
                 assertTrue(testListener.isCompleted(5000));
-                
-                BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+
+                final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
                 sortEventsOnBundle(bundleRepair);
-                PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-                NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
-                DeletedEvent de = createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId());                
+                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+                final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
+                final DeletedEvent de = createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId());
 
-                SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), Collections.singletonList(de), Collections.singletonList(ne));
-                BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+                final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), Collections.singletonList(de), Collections.singletonList(ne));
+                final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
                 repairApi.repairBundle(bRepair, true, context);
             }
         }, ErrorCode.ENT_REPAIR_INVALID_DELETE_SET);
     }
 
-    @Test(groups={"fast"})
+    @Test(groups = {"fast"})
     public void testENT_REPAIR_NON_EXISTENT_DELETE_EVENT() throws Exception {
-        
+
         log.info("Starting testENT_REPAIR_NON_EXISTENT_DELETE_EVENT");
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException {
-                
-                BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+
+                final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
                 sortEventsOnBundle(bundleRepair);
-                PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-                NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
-                DeletedEvent de = createDeletedEvent(UUID.randomUUID());
-                SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), Collections.singletonList(de), Collections.singletonList(ne));
-                
-                BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+                final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
+                final DeletedEvent de = createDeletedEvent(UUID.randomUUID());
+                final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), Collections.singletonList(de), Collections.singletonList(ne));
+
+                final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
                 repairApi.repairBundle(bRepair, true, context);
             }
         }, ErrorCode.ENT_REPAIR_NON_EXISTENT_DELETE_EVENT);
     }
-    
-    @Test(groups={"fast"})
+
+    @Test(groups = {"fast"})
     public void testENT_REPAIR_SUB_RECREATE_NOT_EMPTY() throws Exception {
-        
+
         log.info("Starting testENT_REPAIR_SUB_RECREATE_NOT_EMPTY");
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException {
-                
+
                 // MOVE AFTER TRIAL
-                   testListener.pushExpectedEvent(NextEvent.PHASE);
-                   Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
-                   clock.addDeltaFromReality(it.toDurationMillis());
-                   assertTrue(testListener.isCompleted(5000));
-                   
-                   BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
-                   sortEventsOnBundle(bundleRepair);
-                   PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-                   NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, baseSubscription.getStartDate().plusDays(10), spec);
-                   List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
-                   des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));                
-                   SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
-                   
-                   BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
-
-                   repairApi.repairBundle(bRepair, true, context);
-                
+                testListener.pushExpectedEvent(NextEvent.PHASE);
+                final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
+                clock.addDeltaFromReality(it.toDurationMillis());
+                assertTrue(testListener.isCompleted(5000));
+
+                final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+                sortEventsOnBundle(bundleRepair);
+                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+                final NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, baseSubscription.getStartDate().plusDays(10), spec);
+                final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));
+                final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
+
+                final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+
+                repairApi.repairBundle(bRepair, true, context);
+
             }
         }, ErrorCode.ENT_REPAIR_SUB_RECREATE_NOT_EMPTY);
     }
 
-    @Test(groups={"fast"})
+    @Test(groups = {"fast"})
     public void testENT_REPAIR_SUB_EMPTY() throws Exception {
 
         log.info("Starting testENT_REPAIR_SUB_EMPTY");
-        
+
         test.withException(new TestWithExceptionCallback() {
 
             @Override
             public void doTest() throws EntitlementRepairException {
-                
-             // MOVE AFTER TRIAL
+
+                // MOVE AFTER TRIAL
                 testListener.pushExpectedEvent(NextEvent.PHASE);
-                Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
+                final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(40));
                 clock.addDeltaFromReality(it.toDurationMillis());
                 assertTrue(testListener.isCompleted(5000));
-                
-                BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+
+                final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
                 sortEventsOnBundle(bundleRepair);
-                PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-                NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
-                List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
-                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));                
-                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));                                
-                SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
-                
-                BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
+                final NewEvent ne = createNewEvent(SubscriptionTransitionType.CHANGE, baseSubscription.getStartDate().plusDays(10), spec);
+                final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));
+                des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));
+                final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
+
+                final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
 
                 repairApi.repairBundle(bRepair, true, context);
             }
         }, ErrorCode.ENT_REPAIR_SUB_EMPTY);
     }
-    
-    @Test(groups={"fast"})
+
+    @Test(groups = {"fast"})
     public void testENT_REPAIR_AO_CREATE_BEFORE_BP_START() throws Exception {
-        
+
         log.info("Starting testENT_REPAIR_AO_CREATE_BEFORE_BP_START");
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
-               
+
 
                 // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
                 Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
                 clock.addDeltaFromReality(it.toDurationMillis());
-                SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+                final SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
                 // MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
                 it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
                 clock.addDeltaFromReality(it.toDurationMillis());
 
-                BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+                final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
                 sortEventsOnBundle(bundleRepair);
-                
+
                 // Quick check
-                SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+                final SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
                 assertEquals(bpRepair.getExistingEvents().size(), 2);
-                
-                SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
+
+                final SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
                 assertEquals(aoRepair.getExistingEvents().size(), 2);
-                
 
-                List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
-                des.add(createDeletedEvent(aoRepair.getExistingEvents().get(0).getEventId()));        
+
+                final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+                des.add(createDeletedEvent(aoRepair.getExistingEvents().get(0).getEventId()));
                 des.add(createDeletedEvent(aoRepair.getExistingEvents().get(1).getEventId()));
 
-                DateTime aoRecreateDate = aoSubscription.getStartDate().minusDays(5);
-                PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.DISCOUNT);
-                NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, aoRecreateDate, spec);
-                
-                SubscriptionTimeline saoRepair = createSubscriptionRepair(aoSubscription.getId(), des, Collections.singletonList(ne));
-                
-                BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
-                
-                boolean dryRun = true;
+                final DateTime aoRecreateDate = aoSubscription.getStartDate().minusDays(5);
+                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.DISCOUNT);
+                final NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, aoRecreateDate, spec);
+
+                final SubscriptionTimeline saoRepair = createSubscriptionRepair(aoSubscription.getId(), des, Collections.singletonList(ne));
+
+                final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
+
+                final boolean dryRun = true;
                 repairApi.repairBundle(bRepair, dryRun, context);
             }
         }, ErrorCode.ENT_REPAIR_AO_CREATE_BEFORE_BP_START);
     }
-    
-    @Test(groups={"fast"})
+
+    @Test(groups = {"fast"})
     public void testENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING() throws Exception {
-        
+
         log.info("Starting testENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING");
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
-                
+
 
                 // MOVE CLOCK A LITTLE BIT-- STILL IN TRIAL
                 Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
                 clock.addDeltaFromReality(it.toDurationMillis());
-                SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+                final SubscriptionData aoSubscription = createSubscription("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
                 // MOVE CLOCK A LITTLE BIT MORE -- STILL IN TRIAL
                 it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
@@ -288,80 +288,80 @@ public class TestRepairWithError extends TestApiBaseRepair {
 
                 BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
                 sortEventsOnBundle(bundleRepair);
-                
+
                 // Quick check
-                SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
+                final SubscriptionTimeline bpRepair = getSubscriptionRepair(baseSubscription.getId(), bundleRepair);
                 assertEquals(bpRepair.getExistingEvents().size(), 2);
-                
-                SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
+
+                final SubscriptionTimeline aoRepair = getSubscriptionRepair(aoSubscription.getId(), bundleRepair);
                 assertEquals(aoRepair.getExistingEvents().size(), 2);
-                
 
-                List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+
+                final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
                 //des.add(createDeletedEvent(aoRepair.getExistingEvents().get(1).getEventId()));        
-                DateTime aoCancelDate = aoSubscription.getStartDate().plusDays(10);
-                
-                NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, aoCancelDate, null);
-                
-                SubscriptionTimeline saoRepair = createSubscriptionRepair(aoSubscription.getId(), des, Collections.singletonList(ne));
-                
-                bundleRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
-                
-                boolean dryRun = true;
+                final DateTime aoCancelDate = aoSubscription.getStartDate().plusDays(10);
+
+                final NewEvent ne = createNewEvent(SubscriptionTransitionType.CANCEL, aoCancelDate, null);
+
+                final SubscriptionTimeline saoRepair = createSubscriptionRepair(aoSubscription.getId(), des, Collections.singletonList(ne));
+
+                bundleRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(saoRepair));
+
+                final boolean dryRun = true;
                 repairApi.repairBundle(bundleRepair, dryRun, context);
             }
         }, ErrorCode.ENT_REPAIR_NEW_EVENT_BEFORE_LAST_AO_REMAINING);
     }
 
 
-    @Test(groups={"fast"})
+    @Test(groups = {"fast"})
     public void testENT_REPAIR_BP_RECREATE_MISSING_AO() throws Exception {
-        
+
         log.info("Starting testENT_REPAIR_BP_RECREATE_MISSING_AO");
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
 
-              //testListener.pushExpectedEvent(NextEvent.PHASE);
+                //testListener.pushExpectedEvent(NextEvent.PHASE);
 
-                Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
+                final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(4));
                 clock.addDeltaFromReality(it.toDurationMillis());
                 //assertTrue(testListener.isCompleted(5000));
 
-                SubscriptionData aoSubscription = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
-                
-                BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
+                final SubscriptionData aoSubscription = createSubscription("Laser-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+
+                final BundleTimeline bundleRepair = repairApi.getBundleRepair(bundle.getId());
                 sortEventsOnBundle(bundleRepair);
-                
-                DateTime newCreateTime = baseSubscription.getStartDate().plusDays(3);
 
-                PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
+                final DateTime newCreateTime = baseSubscription.getStartDate().plusDays(3);
 
-                NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, newCreateTime, spec);
-                List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
+                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Pistol", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
+
+                final NewEvent ne = createNewEvent(SubscriptionTransitionType.CREATE, newCreateTime, spec);
+                final List<DeletedEvent> des = new LinkedList<SubscriptionTimeline.DeletedEvent>();
                 des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(0).getEventId()));
                 des.add(createDeletedEvent(bundleRepair.getSubscriptions().get(0).getExistingEvents().get(1).getEventId()));
 
-                SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
-                
+                final SubscriptionTimeline sRepair = createSubscriptionRepair(baseSubscription.getId(), des, Collections.singletonList(ne));
+
                 // FIRST ISSUE DRY RUN
-                BundleTimeline bRepair =  createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
-                
-                boolean dryRun = true;
+                final BundleTimeline bRepair = createBundleRepair(bundle.getId(), bundleRepair.getViewId(), Collections.singletonList(sRepair));
+
+                final boolean dryRun = true;
                 repairApi.repairBundle(bRepair, dryRun, context);
             }
         }, ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO);
     }
-    
+
     //
     // CAN'T seem to trigger such case easily, other errors trigger before...
     //
-    @Test(groups={"fast"}, enabled=false)
+    @Test(groups = {"fast"}, enabled = false)
     public void testENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE() throws Exception {
-        
+
         log.info("Starting testENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE");
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
@@ -405,17 +405,17 @@ public class TestRepairWithError extends TestApiBaseRepair {
             }
         }, ErrorCode.ENT_REPAIR_BP_RECREATE_MISSING_AO_CREATE);
     }
-    
-    @Test(groups={"fast"}, enabled=false)
+
+    @Test(groups = {"fast"}, enabled = false)
     public void testENT_REPAIR_MISSING_AO_DELETE_EVENT() throws Exception {
-        
+
         log.info("Starting testENT_REPAIR_MISSING_AO_DELETE_EVENT");
-        
+
         test.withException(new TestWithExceptionCallback() {
             @Override
             public void doTest() throws EntitlementRepairException, EntitlementUserApiException {
 
-                
+
                 /*
                 // MOVE CLOCK -- JUST BEFORE END OF TRIAL
                  *                 
@@ -457,7 +457,7 @@ public class TestRepairWithError extends TestApiBaseRepair {
                 boolean dryRun = false;
                 repairApi.repairBundle(bundleRepair, dryRun, context);
                 */
-                }
+            }
         }, ErrorCode.ENT_REPAIR_MISSING_AO_DELETE_EVENT);
     }
 
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
index 9aede3c..68b1978 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiAddOn.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
 import java.util.List;
 
 import org.joda.time.DateTime;
@@ -48,6 +43,11 @@ import com.ning.billing.entitlement.api.user.SubscriptionStatusDryRun.DryRunChan
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 import com.ning.billing.util.clock.DefaultClock;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
 public class TestUserApiAddOn extends TestApiBase {
 
     @Override
@@ -55,26 +55,26 @@ public class TestUserApiAddOn extends TestApiBase {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testCreateCancelAddon() {
 
         log.info("Starting testCreateCancelAddon");
 
         try {
-            String baseProduct = "Shotgun";
-            BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-            String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String baseProduct = "Shotgun";
+            final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+            final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             createSubscription(baseProduct, baseTerm, basePriceList);
 
-            String aoProduct = "Telescopic-Scope";
-            BillingPeriod aoTerm = BillingPeriod.MONTHLY;
-            String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String aoProduct = "Telescopic-Scope";
+            final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
+            final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
-            SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
+            final SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
             assertEquals(aoSubscription.getState(), SubscriptionState.ACTIVE);
 
-            DateTime now = clock.getUTCNow();
+            final DateTime now = clock.getUTCNow();
             aoSubscription.cancel(now, false, context);
 
             testListener.reset();
@@ -89,23 +89,23 @@ public class TestUserApiAddOn extends TestApiBase {
         }
     }
 
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testCancelBPWithAddon() {
 
         log.info("Starting testCancelBPWithAddon");
 
         try {
 
-            String baseProduct = "Shotgun";
-            BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-            String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String baseProduct = "Shotgun";
+            final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+            final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE BP
             SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
 
-            String aoProduct = "Telescopic-Scope";
-            BillingPeriod aoTerm = BillingPeriod.MONTHLY;
-            String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String aoProduct = "Telescopic-Scope";
+            final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
+            final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
 
@@ -119,10 +119,10 @@ public class TestUserApiAddOn extends TestApiBase {
             assertTrue(testListener.isCompleted(5000));
 
             // SET CTD TO CANCEL IN FUTURE
-            DateTime now = clock.getUTCNow();
-            Duration ctd = getDurationMonth(1);
+            final DateTime now = clock.getUTCNow();
+            final Duration ctd = getDurationMonth(1);
             // Why not just use clock.getUTCNow().plusMonths(1) ?
-            DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
             billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, context);
             baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
 
@@ -138,7 +138,7 @@ public class TestUserApiAddOn extends TestApiBase {
             testListener.reset();
             testListener.pushExpectedEvent(NextEvent.CANCEL);
             testListener.pushExpectedEvent(NextEvent.CANCEL);
-            
+
             it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
@@ -155,23 +155,23 @@ public class TestUserApiAddOn extends TestApiBase {
     }
 
 
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testChangeBPWithAddonIncluded() {
 
         log.info("Starting testChangeBPWithAddonIncluded");
 
         try {
 
-            String baseProduct = "Shotgun";
-            BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-            String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String baseProduct = "Shotgun";
+            final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+            final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE BP
             SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
 
-            String aoProduct = "Telescopic-Scope";
-            BillingPeriod aoTerm = BillingPeriod.MONTHLY;
-            String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String aoProduct = "Telescopic-Scope";
+            final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
+            final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
 
@@ -180,31 +180,31 @@ public class TestUserApiAddOn extends TestApiBase {
             testListener.pushExpectedEvent(NextEvent.PHASE);
 
             // MOVE CLOCK AFTER TRIAL + AO DISCOUNT
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(2));
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(2));
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
 
             // SET CTD TO CHANGE IN FUTURE
-            DateTime now = clock.getUTCNow();
-            Duration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
+            final DateTime now = clock.getUTCNow();
+            final Duration ctd = getDurationMonth(1);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
             billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, context);
             baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
 
             // CHANGE IMMEDIATELY WITH TO BP WITH NON INCLUDED ADDON
-            String newBaseProduct = "Assault-Rifle";
-            BillingPeriod newBaseTerm = BillingPeriod.MONTHLY;
-            String newBasePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String newBaseProduct = "Assault-Rifle";
+            final BillingPeriod newBaseTerm = BillingPeriod.MONTHLY;
+            final String newBasePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
-            List<SubscriptionStatusDryRun> aoStatus = entitlementApi.getDryRunChangePlanStatus(baseSubscription.getId(), newBaseProduct, now);
+            final List<SubscriptionStatusDryRun> aoStatus = entitlementApi.getDryRunChangePlanStatus(baseSubscription.getId(), newBaseProduct, now);
             assertEquals(aoStatus.size(), 1);
             assertEquals(aoStatus.get(0).getId(), aoSubscription.getId());
             assertEquals(aoStatus.get(0).getProductName(), aoProduct);
-            assertEquals(aoStatus.get(0).getBillingPeriod(), aoTerm);            
-            assertEquals(aoStatus.get(0).getPhaseType(), aoSubscription.getCurrentPhase().getPhaseType());                        
+            assertEquals(aoStatus.get(0).getBillingPeriod(), aoTerm);
+            assertEquals(aoStatus.get(0).getPhaseType(), aoSubscription.getCurrentPhase().getPhaseType());
             assertEquals(aoStatus.get(0).getPriceList(), aoSubscription.getCurrentPriceList().getName());
-            assertEquals(aoStatus.get(0).getReason(), DryRunChangeReason.AO_INCLUDED_IN_NEW_PLAN);            
-            
+            assertEquals(aoStatus.get(0).getReason(), DryRunChangeReason.AO_INCLUDED_IN_NEW_PLAN);
+
             testListener.reset();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
             testListener.pushExpectedEvent(NextEvent.CANCEL);
@@ -221,23 +221,23 @@ public class TestUserApiAddOn extends TestApiBase {
         }
     }
 
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testChangeBPWithAddonNonAvailable() {
 
         log.info("Starting testChangeBPWithAddonNonAvailable");
 
         try {
 
-            String baseProduct = "Shotgun";
-            BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-            String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String baseProduct = "Shotgun";
+            final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+            final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE BP
             SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
 
-            String aoProduct = "Telescopic-Scope";
-            BillingPeriod aoTerm = BillingPeriod.MONTHLY;
-            String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String aoProduct = "Telescopic-Scope";
+            final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
+            final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
 
@@ -251,26 +251,26 @@ public class TestUserApiAddOn extends TestApiBase {
             assertTrue(testListener.isCompleted(5000));
 
             // SET CTD TO CANCEL IN FUTURE
-            DateTime now = clock.getUTCNow();
-            Duration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
+            final DateTime now = clock.getUTCNow();
+            final Duration ctd = getDurationMonth(1);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(now, ctd);
             billingApi.setChargedThroughDate(baseSubscription.getId(), newChargedThroughDate, context);
             baseSubscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(baseSubscription.getId());
 
             // CHANGE IMMEDIATELY WITH TO BP WITH NON AVAILABLE ADDON
-            String newBaseProduct = "Pistol";
-            BillingPeriod newBaseTerm = BillingPeriod.MONTHLY;
-            String newBasePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String newBaseProduct = "Pistol";
+            final BillingPeriod newBaseTerm = BillingPeriod.MONTHLY;
+            final String newBasePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
-            List<SubscriptionStatusDryRun> aoStatus = entitlementApi.getDryRunChangePlanStatus(baseSubscription.getId(), newBaseProduct, now);
+            final List<SubscriptionStatusDryRun> aoStatus = entitlementApi.getDryRunChangePlanStatus(baseSubscription.getId(), newBaseProduct, now);
             assertEquals(aoStatus.size(), 1);
             assertEquals(aoStatus.get(0).getId(), aoSubscription.getId());
             assertEquals(aoStatus.get(0).getProductName(), aoProduct);
-            assertEquals(aoStatus.get(0).getBillingPeriod(), aoTerm);   
-            assertEquals(aoStatus.get(0).getPhaseType(), aoSubscription.getCurrentPhase().getPhaseType());                                    
+            assertEquals(aoStatus.get(0).getBillingPeriod(), aoTerm);
+            assertEquals(aoStatus.get(0).getPhaseType(), aoSubscription.getCurrentPhase().getPhaseType());
             assertEquals(aoStatus.get(0).getPriceList(), aoSubscription.getCurrentPriceList().getName());
-            assertEquals(aoStatus.get(0).getReason(), DryRunChangeReason.AO_NOT_AVAILABLE_IN_NEW_PLAN);            
-            
+            assertEquals(aoStatus.get(0).getReason(), DryRunChangeReason.AO_NOT_AVAILABLE_IN_NEW_PLAN);
+
             baseSubscription.changePlan(newBaseProduct, newBaseTerm, newBasePriceList, now, context);
 
             // REFETCH AO SUBSCRIPTION AND CHECK THIS IS ACTIVE
@@ -298,22 +298,22 @@ public class TestUserApiAddOn extends TestApiBase {
     }
 
 
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testAddonCreateWithBundleAlign() {
 
         log.info("Starting testAddonCreateWithBundleAlign");
 
         try {
-            String aoProduct = "Telescopic-Scope";
-            BillingPeriod aoTerm = BillingPeriod.MONTHLY;
-            String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String aoProduct = "Telescopic-Scope";
+            final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
+            final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // This is just to double check our test catalog gives us what we want before we start the test
-            PlanSpecifier planSpecifier = new PlanSpecifier(aoProduct,
-                    ProductCategory.ADD_ON,
-                    aoTerm,
-                    aoPriceList);
-            PlanAlignmentCreate alignement = catalog.planCreateAlignment(planSpecifier, clock.getUTCNow());
+            final PlanSpecifier planSpecifier = new PlanSpecifier(aoProduct,
+                                                            ProductCategory.ADD_ON,
+                                                            aoTerm,
+                                                            aoPriceList);
+            final PlanAlignmentCreate alignement = catalog.planCreateAlignment(planSpecifier, clock.getUTCNow());
             assertEquals(alignement, PlanAlignmentCreate.START_OF_BUNDLE);
 
             testAddonCreateInternal(aoProduct, aoTerm, aoPriceList, alignement);
@@ -324,22 +324,22 @@ public class TestUserApiAddOn extends TestApiBase {
         }
     }
 
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testAddonCreateWithSubscriptionAlign() {
 
         log.info("Starting testAddonCreateWithSubscriptionAlign");
 
         try {
-            String aoProduct = "Laser-Scope";
-            BillingPeriod aoTerm = BillingPeriod.MONTHLY;
-            String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String aoProduct = "Laser-Scope";
+            final BillingPeriod aoTerm = BillingPeriod.MONTHLY;
+            final String aoPriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // This is just to double check our test catalog gives us what we want before we start the test
-            PlanSpecifier planSpecifier = new PlanSpecifier(aoProduct,
-                    ProductCategory.ADD_ON,
-                    aoTerm,
-                    aoPriceList);
-            PlanAlignmentCreate alignement = catalog.planCreateAlignment(planSpecifier, clock.getUTCNow());
+            final PlanSpecifier planSpecifier = new PlanSpecifier(aoProduct,
+                                                            ProductCategory.ADD_ON,
+                                                            aoTerm,
+                                                            aoPriceList);
+            final PlanAlignmentCreate alignement = catalog.planCreateAlignment(planSpecifier, clock.getUTCNow());
             assertEquals(alignement, PlanAlignmentCreate.START_OF_SUBSCRIPTION);
 
             testAddonCreateInternal(aoProduct, aoTerm, aoPriceList, alignement);
@@ -351,30 +351,30 @@ public class TestUserApiAddOn extends TestApiBase {
     }
 
 
-    private void testAddonCreateInternal(String aoProduct, BillingPeriod aoTerm, String aoPriceList, PlanAlignmentCreate expAlignement) {
+    private void testAddonCreateInternal(final String aoProduct, final BillingPeriod aoTerm, final String aoPriceList, final PlanAlignmentCreate expAlignement) {
 
         try {
 
-            String baseProduct = "Shotgun";
-            BillingPeriod baseTerm = BillingPeriod.MONTHLY;
-            String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String baseProduct = "Shotgun";
+            final BillingPeriod baseTerm = BillingPeriod.MONTHLY;
+            final String basePriceList = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE BP
-            SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
+            final SubscriptionData baseSubscription = createSubscription(baseProduct, baseTerm, basePriceList);
 
             // MOVE CLOCK 14 DAYS LATER
             Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(14));
             clock.addDeltaFromReality(it.toDurationMillis());
-  
+
             // CREATE ADDON
-            DateTime beforeAOCreation = clock.getUTCNow();
+            final DateTime beforeAOCreation = clock.getUTCNow();
             SubscriptionData aoSubscription = createSubscription(aoProduct, aoTerm, aoPriceList);
-            DateTime afterAOCreation = clock.getUTCNow();
+            final DateTime afterAOCreation = clock.getUTCNow();
 
             // CHECK EVERYTHING
             Plan aoCurrentPlan = aoSubscription.getCurrentPlan();
             assertNotNull(aoCurrentPlan);
-            assertEquals(aoCurrentPlan.getProduct().getName(),aoProduct);
+            assertEquals(aoCurrentPlan.getProduct().getName(), aoProduct);
             assertEquals(aoCurrentPlan.getProduct().getCategory(), ProductCategory.ADD_ON);
             assertEquals(aoCurrentPlan.getBillingPeriod(), aoTerm);
 
@@ -410,7 +410,7 @@ public class TestUserApiAddOn extends TestApiBase {
 
             aoCurrentPlan = aoSubscription.getCurrentPlan();
             assertNotNull(aoCurrentPlan);
-            assertEquals(aoCurrentPlan.getProduct().getName(),aoProduct);
+            assertEquals(aoCurrentPlan.getProduct().getName(), aoProduct);
             assertEquals(aoCurrentPlan.getProduct().getCategory(), ProductCategory.ADD_ON);
             assertEquals(aoCurrentPlan.getBillingPeriod(), aoTerm);
 
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
index 7fb06e0..afebb34 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
 import org.testng.Assert;
@@ -36,6 +31,11 @@ import com.ning.billing.entitlement.api.TestApiBase;
 import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
 import com.ning.billing.util.clock.DefaultClock;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
 public abstract class TestUserApiCancel extends TestApiBase {
 
     protected void testCancelSubscriptionIMM() {
@@ -44,22 +44,22 @@ public abstract class TestUserApiCancel extends TestApiBase {
 
         try {
 
-            DateTime init = clock.getUTCNow();
+            final DateTime init = clock.getUTCNow();
 
-            String prod = "Shotgun";
-            BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String prod = "Shotgun";
+            final BillingPeriod term = BillingPeriod.MONTHLY;
+            final String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
-            SubscriptionData subscription = createSubscription(prod, term, planSet);
+            final SubscriptionData subscription = createSubscription(prod, term, planSet);
             PlanPhase currentPhase = subscription.getCurrentPhase();
             assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
 
             // ADVANCE TIME still in trial
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(3));
             clock.addDeltaFromReality(it.toDurationMillis());
 
-            DateTime future = clock.getUTCNow();
+            final DateTime future = clock.getUTCNow();
             testListener.pushExpectedEvent(NextEvent.CANCEL);
 
             // CANCEL in trial period to get IMM policy
@@ -82,9 +82,9 @@ public abstract class TestUserApiCancel extends TestApiBase {
 
         try {
 
-            String prod = "Shotgun";
-            BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String prod = "Shotgun";
+            final BillingPeriod term = BillingPeriod.MONTHLY;
+            final String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
             SubscriptionData subscription = createSubscription(prod, term, planSet);
@@ -92,7 +92,7 @@ public abstract class TestUserApiCancel extends TestApiBase {
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             // NEXT PHASE
-            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            final DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             checkNextPhaseChange(subscription, 1, expectedPhaseTrialChange);
 
             // MOVE TO NEXT PHASE
@@ -105,8 +105,8 @@ public abstract class TestUserApiCancel extends TestApiBase {
             assertEquals(trialPhase.getPhaseType(), PhaseType.EVERGREEN);
 
             // SET CTD + RE READ SUBSCRIPTION + CHANGE PLAN
-            Duration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
+            final Duration ctd = getDurationMonth(1);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
@@ -121,10 +121,10 @@ public abstract class TestUserApiCancel extends TestApiBase {
             testListener.pushExpectedEvent(NextEvent.CANCEL);
             it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
             clock.addDeltaFromReality(it.toDurationMillis());
-            DateTime future = clock.getUTCNow();
+            final DateTime future = clock.getUTCNow();
             assertTrue(testListener.isCompleted(5000));
 
-            PlanPhase currentPhase = subscription.getCurrentPhase();
+            final PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNull(currentPhase);
             checkNextPhaseChange(subscription, 0, null);
 
@@ -141,23 +141,23 @@ public abstract class TestUserApiCancel extends TestApiBase {
 
         try {
 
-            String prod = "Shotgun";
-            BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String prod = "Shotgun";
+            final BillingPeriod term = BillingPeriod.MONTHLY;
+            final String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
-            SubscriptionData subscription = createSubscription(prod, term, planSet);
+            final SubscriptionData subscription = createSubscription(prod, term, planSet);
             PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             // NEXT PHASE
-            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            final DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             checkNextPhaseChange(subscription, 1, expectedPhaseTrialChange);
 
             // MOVE TO NEXT PHASE
             testListener.pushExpectedEvent(NextEvent.PHASE);
-            
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
             trialPhase = subscription.getCurrentPhase();
@@ -169,7 +169,7 @@ public abstract class TestUserApiCancel extends TestApiBase {
             subscription.cancel(clock.getUTCNow(), false, context);
             assertTrue(testListener.isCompleted(5000));
 
-            PlanPhase currentPhase = subscription.getCurrentPhase();
+            final PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNull(currentPhase);
             checkNextPhaseChange(subscription, 0, null);
 
@@ -188,17 +188,17 @@ public abstract class TestUserApiCancel extends TestApiBase {
 
         try {
 
-            String prod = "Shotgun";
-            BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String prod = "Shotgun";
+            final BillingPeriod term = BillingPeriod.MONTHLY;
+            final String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
             SubscriptionData subscription = createSubscription(prod, term, planSet);
-            PlanPhase trialPhase = subscription.getCurrentPhase();
+            final PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             // NEXT PHASE
-            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            final DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             checkNextPhaseChange(subscription, 1, expectedPhaseTrialChange);
 
             // MOVE TO NEXT PHASE
@@ -210,8 +210,8 @@ public abstract class TestUserApiCancel extends TestApiBase {
             assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
 
             // SET CTD + RE READ SUBSCRIPTION + CHANGE PLAN
-            Duration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
+            final Duration ctd = getDurationMonth(1);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
@@ -219,14 +219,14 @@ public abstract class TestUserApiCancel extends TestApiBase {
             subscription.cancel(clock.getUTCNow(), false, context);
 
             subscription.uncancel(context);
-            
+
             // MOVE TO EOT + RECHECK
-            testListener.pushExpectedEvent(NextEvent.UNCANCEL);            
+            testListener.pushExpectedEvent(NextEvent.UNCANCEL);
             it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
 
-            Plan currentPlan = subscription.getCurrentPlan();
+            final Plan currentPlan = subscription.getCurrentPlan();
             assertEquals(currentPlan.getProduct().getName(), prod);
             currentPhase = subscription.getCurrentPhase();
             assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
index 625002a..4b3f54a 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
@@ -33,25 +33,25 @@ public class TestUserApiCancelMemory extends TestUserApiCancel {
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCancelSubscriptionIMM() {
         super.testCancelSubscriptionIMM();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCancelSubscriptionEOTWithChargeThroughDate() throws EntitlementBillingApiException {
         super.testCancelSubscriptionEOTWithChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCancelSubscriptionEOTWithNoChargeThroughDate() {
         super.testCancelSubscriptionEOTWithNoChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testUncancel() throws EntitlementBillingApiException {
         super.testUncancel();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
index 6d02736..2bd3299 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
@@ -27,15 +27,14 @@ import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 public class TestUserApiCancelSql extends TestUserApiCancel {
 
 
-    private final int MAX_STRESS_ITERATIONS = 10;
-
     @Override
     public Injector getInjector() {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
-    @Test(enabled= false, groups={"stress"})
+    @Test(enabled = false, groups = {"stress"})
     public void stressTest() throws Exception {
+        final int MAX_STRESS_ITERATIONS = 10;
         for (int i = 0; i < MAX_STRESS_ITERATIONS; i++) {
             cleanupTest();
             setupTest();
@@ -50,25 +49,25 @@ public class TestUserApiCancelSql extends TestUserApiCancel {
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testCancelSubscriptionIMM() {
         super.testCancelSubscriptionIMM();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testCancelSubscriptionEOTWithChargeThroughDate() throws EntitlementBillingApiException {
         super.testCancelSubscriptionEOTWithChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testCancelSubscriptionEOTWithNoChargeThroughDate() {
         super.testCancelSubscriptionEOTWithNoChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testUncancel() throws EntitlementBillingApiException {
         super.testUncancel();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
index b1d2c0b..5591238 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -42,50 +37,53 @@ import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.user.ApiEvent;
 import com.ning.billing.util.clock.DefaultClock;
 
-public abstract class TestUserApiChangePlan extends TestApiBase {
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
 
+public abstract class TestUserApiChangePlan extends TestApiBase {
 
 
-    private void checkChangePlan(SubscriptionData subscription, String expProduct, ProductCategory expCategory,
-            BillingPeriod expBillingPeriod, PhaseType expPhase) {
+    private void checkChangePlan(final SubscriptionData subscription, final String expProduct, final ProductCategory expCategory,
+                                 final BillingPeriod expBillingPeriod, final PhaseType expPhase) {
 
-        Plan currentPlan = subscription.getCurrentPlan();
+        final Plan currentPlan = subscription.getCurrentPlan();
         assertNotNull(currentPlan);
-        assertEquals(currentPlan.getProduct().getName(),expProduct);
+        assertEquals(currentPlan.getProduct().getName(), expProduct);
         assertEquals(currentPlan.getProduct().getCategory(), expCategory);
         assertEquals(currentPlan.getBillingPeriod(), expBillingPeriod);
 
-        PlanPhase currentPhase = subscription.getCurrentPhase();
+        final PlanPhase currentPhase = subscription.getCurrentPhase();
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), expPhase);
     }
 
 
-
     protected void testChangePlanBundleAlignEOTWithNoChargeThroughDate() {
         tChangePlanBundleAlignEOTWithNoChargeThroughDate("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, "Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
     }
 
 
-    private void tChangePlanBundleAlignEOTWithNoChargeThroughDate(String fromProd, BillingPeriod fromTerm, String fromPlanSet,
-        String toProd, BillingPeriod toTerm, String toPlanSet) {
+    private void tChangePlanBundleAlignEOTWithNoChargeThroughDate(final String fromProd, final BillingPeriod fromTerm, final String fromPlanSet,
+                                                                  final String toProd, final BillingPeriod toTerm, final String toPlanSet) {
 
         log.info("Starting testChangePlanBundleAlignEOTWithNoChargeThroughDate");
 
         try {
 
             // CREATE
-            SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
+            final SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
 
             // MOVE TO NEXT PHASE
             PlanPhase currentPhase = subscription.getCurrentPhase();
             testListener.pushExpectedEvent(NextEvent.PHASE);
-            
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
             clock.addDeltaFromReality(it.toDurationMillis());
 
-            DateTime futureNow = clock.getUTCNow();
-            DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
+            final DateTime futureNow = clock.getUTCNow();
+            final DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
             assertTrue(futureNow.isAfter(nextExpectedPhaseChange));
             assertTrue(testListener.isCompleted(5000));
 
@@ -110,16 +108,16 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
         testChangePlanBundleAlignEOTWithChargeThroughDate("Shotgun", BillingPeriod.ANNUAL, "gunclubDiscount", "Pistol", BillingPeriod.ANNUAL, "gunclubDiscount");
     }
 
-    private void testChangePlanBundleAlignEOTWithChargeThroughDate(String fromProd, BillingPeriod fromTerm, String fromPlanSet,
-            String toProd, BillingPeriod toTerm, String toPlanSet) throws EntitlementBillingApiException {
+    private void testChangePlanBundleAlignEOTWithChargeThroughDate(final String fromProd, final BillingPeriod fromTerm, final String fromPlanSet,
+                                                                   final String toProd, final BillingPeriod toTerm, final String toPlanSet) throws EntitlementBillingApiException {
+
 
-        
         try {
 
             // CREATE
             SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
-            PlanPhase trialPhase = subscription.getCurrentPhase();
-            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            final PlanPhase trialPhase = subscription.getCurrentPhase();
+            final DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
 
@@ -133,8 +131,8 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
 
 
             // SET CTD
-            Duration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
+            final Duration ctd = getDurationMonth(1);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
 
             // RE READ SUBSCRIPTION + CHANGE PLAN
@@ -150,11 +148,11 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             checkChangePlan(subscription, fromProd, ProductCategory.BASE, fromTerm, PhaseType.DISCOUNT);
 
             // NEXT PHASE
-            DateTime nextExpectedPhaseChange = DefaultClock.addDuration(expectedPhaseTrialChange, currentPhase.getDuration());
+            final DateTime nextExpectedPhaseChange = DefaultClock.addDuration(expectedPhaseTrialChange, currentPhase.getDuration());
             checkNextPhaseChange(subscription, 2, nextExpectedPhaseChange);
 
             // ALSO VERIFY PENDING CHANGE EVENT
-            List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
+            final List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
             assertTrue(events.get(0) instanceof ApiEvent);
 
 
@@ -180,14 +178,14 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
     }
 
 
-    private void tChangePlanBundleAlignIMM(String fromProd, BillingPeriod fromTerm, String fromPlanSet,
-            String toProd, BillingPeriod toTerm, String toPlanSet) {
+    private void tChangePlanBundleAlignIMM(final String fromProd, final BillingPeriod fromTerm, final String fromPlanSet,
+                                           final String toProd, final BillingPeriod toTerm, final String toPlanSet) {
 
         log.info("Starting testChangePlanBundleAlignIMM");
 
         try {
 
-            SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
+            final SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
 
             testListener.pushExpectedEvent(NextEvent.CHANGE);
 
@@ -200,15 +198,15 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
 
             assertTrue(testListener.isCompleted(5000));
 
-            PlanPhase currentPhase = subscription.getCurrentPhase();
-            DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
+            final PlanPhase currentPhase = subscription.getCurrentPhase();
+            final DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
             checkNextPhaseChange(subscription, 1, nextExpectedPhaseChange);
 
             // NEXT PHASE
             testListener.pushExpectedEvent(NextEvent.PHASE);
             it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(30));
             clock.addDeltaFromReality(it.toDurationMillis());
-            DateTime futureNow = clock.getUTCNow();
+            final DateTime futureNow = clock.getUTCNow();
 
             assertTrue(futureNow.isAfter(nextExpectedPhaseChange));
             assertTrue(testListener.isCompleted(5000));
@@ -225,16 +223,16 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
         tChangePlanChangePlanAlignEOTWithChargeThroughDate("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, "Assault-Rifle", BillingPeriod.ANNUAL, "rescue");
     }
 
-    private void tChangePlanChangePlanAlignEOTWithChargeThroughDate(String fromProd, BillingPeriod fromTerm, String fromPlanSet,
-            String toProd, BillingPeriod toTerm, String toPlanSet) throws EntitlementBillingApiException {
+    private void tChangePlanChangePlanAlignEOTWithChargeThroughDate(final String fromProd, final BillingPeriod fromTerm, final String fromPlanSet,
+                                                                    final String toProd, final BillingPeriod toTerm, final String toPlanSet) throws EntitlementBillingApiException {
 
         try {
 
             DateTime currentTime = clock.getUTCNow();
 
             SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
-            PlanPhase trialPhase = subscription.getCurrentPhase();
-            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            final PlanPhase trialPhase = subscription.getCurrentPhase();
+            final DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             // MOVE TO NEXT PHASE
@@ -246,8 +244,8 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             assertTrue(testListener.isCompleted(5000));
 
             // SET CTD
-            Duration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
+            final Duration ctd = getDurationMonth(1);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
 
             // RE READ SUBSCRIPTION + CHECK CURRENT PHASE
@@ -276,7 +274,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             assertTrue(testListener.isCompleted(5000));
 
             // CHECK CORRECT PRODUCT, PHASE, PLAN SET
-            String currentProduct =  subscription.getCurrentPlan().getProduct().getName();
+            final String currentProduct = subscription.getCurrentPlan().getProduct().getName();
             assertNotNull(currentProduct);
             assertEquals(currentProduct, toProd);
             currentPhase = subscription.getCurrentPhase();
@@ -292,7 +290,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             assertFalse(testListener.isCompleted(3000));
             testListener.reset();
 
-            DateTime nextExpectedPhaseChange = DefaultClock.addDuration(newChargedThroughDate, currentPhase.getDuration());
+            final DateTime nextExpectedPhaseChange = DefaultClock.addDuration(newChargedThroughDate, currentPhase.getDuration());
             checkNextPhaseChange(subscription, 1, nextExpectedPhaseChange);
 
             // MOVE TIME RIGHT AFTER NEXT EXPECTED PHASE CHANGE
@@ -314,23 +312,23 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
         log.info("Starting testMultipleChangeLastIMM");
         try {
             SubscriptionData subscription = createSubscription("Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
-            PlanPhase trialPhase = subscription.getCurrentPhase();
+            final PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             // MOVE TO NEXT PHASE
             testListener.pushExpectedEvent(NextEvent.PHASE);
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
             clock.addDeltaFromReality(it.toDurationMillis());
 
             assertTrue(testListener.isCompleted(5000));
 
             // SET CTD
-            List<Duration> durationList = new ArrayList<Duration>();
+            final List<Duration> durationList = new ArrayList<Duration>();
             durationList.add(trialPhase.getDuration());
             //durationList.add(subscription.getCurrentPhase().getDuration());
-            DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
-            Duration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
+            final DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
+            final Duration ctd = getDurationMonth(1);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
@@ -346,16 +344,16 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow(), context);
             assertTrue(testListener.isCompleted(5000));
 
-            Plan currentPlan = subscription.getCurrentPlan();
+            final Plan currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
             assertEquals(currentPlan.getProduct().getName(), "Assault-Rifle");
             assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
             assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.ANNUAL);
 
-            PlanPhase currentPhase = subscription.getCurrentPhase();
+            final PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
-            
+
             assertListenerStatus();
         } catch (EntitlementUserApiException e) {
             Assert.fail(e.getMessage());
@@ -368,7 +366,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
         try {
 
             SubscriptionData subscription = createSubscription("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount");
-            PlanPhase trialPhase = subscription.getCurrentPhase();
+            final PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             testListener.pushExpectedEvent(NextEvent.PHASE);
@@ -377,11 +375,11 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             assertTrue(testListener.isCompleted(5000));
 
             // SET CTD
-            List<Duration> durationList = new ArrayList<Duration>();
+            final List<Duration> durationList = new ArrayList<Duration>();
             durationList.add(trialPhase.getDuration());
-            DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
-            Duration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
+            final DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
+            final Duration ctd = getDurationMonth(1);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
@@ -428,7 +426,6 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
 
 
-
             // MOVE TO NEXT PHASE
             testListener.pushExpectedEvent(NextEvent.PHASE);
             it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(6));
@@ -454,9 +451,9 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
 
 
     protected void testCorrectPhaseAlignmentOnChange() {
-        
+
         log.info("Starting testCorrectPhaseAlignmentOnChange");
-        
+
         try {
 
             SubscriptionData subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
@@ -466,7 +463,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             // MOVE 2 DAYS AHEAD
             Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(2));
             clock.addDeltaFromReality(it.toDurationMillis());
-    
+
 
             // CHANGE IMMEDIATE TO A 3 PHASES PLAN
             testListener.reset();
@@ -476,7 +473,7 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
             testListener.reset();
 
             // CHECK EVERYTHING LOOKS CORRECT
-            Plan currentPlan = subscription.getCurrentPlan();
+            final Plan currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
             assertEquals(currentPlan.getProduct().getName(), "Assault-Rifle");
             assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
@@ -497,9 +494,9 @@ public abstract class TestUserApiChangePlan extends TestApiBase {
 
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
-            DateTime expectedNextPhaseDate =  subscription.getStartDate().plusDays(30).plusMonths(6);
-            SubscriptionEvent nextPhase = subscription.getPendingTransition();
-            DateTime nextPhaseEffectiveDate = nextPhase.getEffectiveTransitionTime();
+            final DateTime expectedNextPhaseDate = subscription.getStartDate().plusDays(30).plusMonths(6);
+            final SubscriptionEvent nextPhase = subscription.getPendingTransition();
+            final DateTime nextPhaseEffectiveDate = nextPhase.getEffectiveTransitionTime();
 
             assertEquals(nextPhaseEffectiveDate, expectedNextPhaseDate);
 
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
index 0da1169..6bc6864 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
@@ -33,38 +33,38 @@ public class TestUserApiChangePlanMemory extends TestUserApiChangePlan {
 
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testChangePlanBundleAlignEOTWithNoChargeThroughDate() {
-         super.testChangePlanBundleAlignEOTWithNoChargeThroughDate();
+        super.testChangePlanBundleAlignEOTWithNoChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testChangePlanBundleAlignEOTWithChargeThroughDate() throws EntitlementBillingApiException {
         super.testChangePlanBundleAlignEOTWithChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testChangePlanBundleAlignIMM() {
         super.testChangePlanBundleAlignIMM();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testMultipleChangeLastIMM() throws EntitlementBillingApiException {
         super.testMultipleChangeLastIMM();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testMultipleChangeLastEOT() throws EntitlementBillingApiException {
         super.testMultipleChangeLastEOT();
     }
 
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCorrectPhaseAlignmentOnChange() {
         super.testCorrectPhaseAlignmentOnChange();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
index 1039b85..bec359b 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
@@ -26,15 +26,14 @@ import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 
 public class TestUserApiChangePlanSql extends TestUserApiChangePlan {
 
-    private final int MAX_STRESS_ITERATIONS = 10;
-
     @Override
     public Injector getInjector() {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
-    @Test(enabled= false, groups={"stress"})
+    @Test(enabled = false, groups = {"stress"})
     public void stressTest() throws Exception {
+        final int MAX_STRESS_ITERATIONS = 10;
         for (int i = 0; i < MAX_STRESS_ITERATIONS; i++) {
             cleanupTest();
             setupTest();
@@ -55,44 +54,44 @@ public class TestUserApiChangePlanSql extends TestUserApiChangePlan {
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testCorrectPhaseAlignmentOnChange() {
         super.testCorrectPhaseAlignmentOnChange();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testChangePlanBundleAlignEOTWithNoChargeThroughDate() {
         super.testChangePlanBundleAlignEOTWithNoChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testChangePlanBundleAlignEOTWithChargeThroughDate() throws EntitlementBillingApiException {
         super.testChangePlanBundleAlignEOTWithChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testChangePlanBundleAlignIMM() {
         super.testChangePlanBundleAlignIMM();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testMultipleChangeLastIMM() throws EntitlementBillingApiException {
         super.testMultipleChangeLastIMM();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testMultipleChangeLastEOT() throws EntitlementBillingApiException {
         super.testMultipleChangeLastEOT();
     }
 
     // rescue not implemented yet
     @Override
-    @Test(enabled=false, groups={"slow"})
+    @Test(enabled = false, groups = {"slow"})
     public void testChangePlanChangePlanAlignEOTWithChargeThroughDate() throws EntitlementBillingApiException {
         super.testChangePlanChangePlanAlignEOTWithChargeThroughDate();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
index 6517044..510f55b 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
@@ -17,10 +17,6 @@
 package com.ning.billing.entitlement.api.user;
 
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import java.util.List;
 
 import org.joda.time.DateTime;
@@ -41,28 +37,32 @@ import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
 import com.ning.billing.util.clock.DefaultClock;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 public abstract class TestUserApiCreate extends TestApiBase {
 
-    private static Logger log = LoggerFactory.getLogger(TestUserApiCreate.class);
+    private static final Logger log = LoggerFactory.getLogger(TestUserApiCreate.class);
 
     public void testCreateWithRequestedDate() {
         log.info("Starting testCreateWithRequestedDate");
         try {
 
-            DateTime init = clock.getUTCNow();
-            DateTime requestedDate = init.minusYears(1);
+            final DateTime init = clock.getUTCNow();
+            final DateTime requestedDate = init.minusYears(1);
 
-            String productName = "Shotgun";
-            BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String productName = "Shotgun";
+            final BillingPeriod term = BillingPeriod.MONTHLY;
+            final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
 
             testListener.pushExpectedEvent(NextEvent.PHASE);
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
 
-            SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                    getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
+            final SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
+                                                                                                 getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
             assertNotNull(subscription);
 
             assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -73,9 +73,9 @@ public abstract class TestUserApiCreate extends TestApiBase {
             assertTrue(testListener.isCompleted(5000));
 
             assertListenerStatus();
-            
+
         } catch (EntitlementUserApiException e) {
-        	log.error("Unexpected exception",e);
+            log.error("Unexpected exception", e);
             Assert.fail(e.getMessage());
         }
     }
@@ -86,16 +86,16 @@ public abstract class TestUserApiCreate extends TestApiBase {
         try {
 
 
-            DateTime init = clock.getUTCNow();
+            final DateTime init = clock.getUTCNow();
 
-            String productName = "Shotgun";
-            BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String productName = "Shotgun";
+            final BillingPeriod term = BillingPeriod.MONTHLY;
+            final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
-            SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                    getProductSpecifier(productName, planSetName, term, PhaseType.EVERGREEN), clock.getUTCNow(), context);
+            final SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
+                                                                                                 getProductSpecifier(productName, planSetName, term, PhaseType.EVERGREEN), clock.getUTCNow(), context);
             assertNotNull(subscription);
 
             assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -104,18 +104,18 @@ public abstract class TestUserApiCreate extends TestApiBase {
             assertDateWithin(subscription.getStartDate(), init, clock.getUTCNow());
             assertDateWithin(subscription.getBundleStartDate(), init, clock.getUTCNow());
 
-            Plan currentPlan = subscription.getCurrentPlan();
+            final Plan currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
             assertEquals(currentPlan.getProduct().getName(), productName);
             assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
             assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
 
-            PlanPhase currentPhase = subscription.getCurrentPhase();
+            final PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
 
             assertListenerStatus();
-            
+
         } catch (EntitlementUserApiException e) {
             Assert.fail(e.getMessage());
         }
@@ -126,17 +126,17 @@ public abstract class TestUserApiCreate extends TestApiBase {
         log.info("Starting testSimpleCreateSubscription");
         try {
 
-            DateTime init = clock.getUTCNow();
+            final DateTime init = clock.getUTCNow();
 
-            String productName = "Shotgun";
-            BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String productName = "Shotgun";
+            final BillingPeriod term = BillingPeriod.MONTHLY;
+            final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
-            SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                    getProductSpecifier(productName, planSetName, term, null),
-                    clock.getUTCNow(), context);
+            final SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
+                                                                                                 getProductSpecifier(productName, planSetName, term, null),
+                                                                                                 clock.getUTCNow(), context);
             assertNotNull(subscription);
 
             assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -145,31 +145,31 @@ public abstract class TestUserApiCreate extends TestApiBase {
             assertDateWithin(subscription.getStartDate(), init, clock.getUTCNow());
             assertDateWithin(subscription.getBundleStartDate(), init, clock.getUTCNow());
 
-            Plan currentPlan = subscription.getCurrentPlan();
+            final Plan currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
             assertEquals(currentPlan.getProduct().getName(), productName);
             assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
             assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
 
-            PlanPhase currentPhase = subscription.getCurrentPhase();
+            final PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
             assertTrue(testListener.isCompleted(5000));
 
-            List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
+            final List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
             assertNotNull(events);
             printEvents(events);
             assertTrue(events.size() == 1);
             assertTrue(events.get(0) instanceof PhaseEvent);
-            DateTime nextPhaseChange = ((PhaseEvent ) events.get(0)).getEffectiveDate();
-            DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
+            final DateTime nextPhaseChange = ((PhaseEvent) events.get(0)).getEffectiveDate();
+            final DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
             assertEquals(nextPhaseChange, nextExpectedPhaseChange);
 
             testListener.pushExpectedEvent(NextEvent.PHASE);
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
             clock.addDeltaFromReality(it.toDurationMillis());
 
-            DateTime futureNow = clock.getUTCNow();
+            final DateTime futureNow = clock.getUTCNow();
             assertTrue(futureNow.isAfter(nextPhaseChange));
 
             assertTrue(testListener.isCompleted(5000));
@@ -186,15 +186,15 @@ public abstract class TestUserApiCreate extends TestApiBase {
         log.info("Starting testSimpleSubscriptionThroughPhases");
         try {
 
-            String productName = "Pistol";
-            BillingPeriod term = BillingPeriod.ANNUAL;
-            String planSetName = "gunclubDiscount";
+            final String productName = "Pistol";
+            final BillingPeriod term = BillingPeriod.ANNUAL;
+            final String planSetName = "gunclubDiscount";
 
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
             // CREATE SUBSCRIPTION
             SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                    getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), context);
+                                                                                                 getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), context);
             assertNotNull(subscription);
 
             PlanPhase currentPhase = subscription.getCurrentPhase();
@@ -210,7 +210,7 @@ public abstract class TestUserApiCreate extends TestApiBase {
             currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
-            
+
 
             // MOVE TO EVERGREEN PHASE + RE-READ SUBSCRIPTION
             testListener.pushExpectedEvent(NextEvent.PHASE);
@@ -234,14 +234,14 @@ public abstract class TestUserApiCreate extends TestApiBase {
         log.info("Starting testSubscriptionWithAddOn");
         try {
 
-            String productName = "Shotgun";
-            BillingPeriod term = BillingPeriod.ANNUAL;
-            String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+            final String productName = "Shotgun";
+            final BillingPeriod term = BillingPeriod.ANNUAL;
+            final String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
-            SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                    getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), context);
+            final SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
+                                                                                                 getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), context);
             assertNotNull(subscription);
 
             assertListenerStatus();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
index e4969f1..d671d2a 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
@@ -32,31 +32,31 @@ public class TestUserApiCreateMemory extends TestUserApiCreate {
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCreateWithRequestedDate() {
         super.testCreateWithRequestedDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCreateWithInitialPhase() {
         super.testSimpleSubscriptionThroughPhases();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testSimpleCreateSubscription() {
         super.testSimpleCreateSubscription();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     protected void testSimpleSubscriptionThroughPhases() {
         super.testSimpleSubscriptionThroughPhases();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     protected void testSubscriptionWithAddOn() {
         super.testSubscriptionWithAddOn();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
index c890da7..135e98c 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
@@ -31,31 +31,31 @@ public class TestUserApiCreateSql extends TestUserApiCreate {
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testCreateWithRequestedDate() {
         super.testCreateWithRequestedDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testCreateWithInitialPhase() {
         super.testCreateWithInitialPhase();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     public void testSimpleCreateSubscription() {
         super.testSimpleCreateSubscription();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     protected void testSimpleSubscriptionThroughPhases() {
         super.testSimpleSubscriptionThroughPhases();
     }
 
     @Override
-    @Test(enabled=false, groups={"slow"})
+    @Test(enabled = false, groups = {"slow"})
     protected void testSubscriptionWithAddOn() {
         super.testSubscriptionWithAddOn();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
index 0973666..49e7a59 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
@@ -45,6 +40,11 @@ import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 import com.ning.billing.util.clock.DefaultClock;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 public class TestUserApiDemos extends TestApiBase {
 
     @Override
@@ -53,21 +53,21 @@ public class TestUserApiDemos extends TestApiBase {
     }
 
     /**
-     *  Initial demo for BP entitlement:
-     *  1. Create a Subscription
-     *  2. ChangePlan while in trial
-     *     -> Change is IMM
-     *     -> Trial is still 30 days long
-     *  3. Move through 2nd Phase
-     *  4. ChangePlan EOT
-     *     -> Show Change pending
-     *  5. Other ChangePlan EOT
-     *     -> Show it supercedes the first one
-     *  6. Move to EOT
-     *  7. Move to next Phase
-     *  8. Cancel EOT
+     * Initial demo for BP entitlement:
+     * 1. Create a Subscription
+     * 2. ChangePlan while in trial
+     * -> Change is IMM
+     * -> Trial is still 30 days long
+     * 3. Move through 2nd Phase
+     * 4. ChangePlan EOT
+     * -> Show Change pending
+     * 5. Other ChangePlan EOT
+     * -> Show it supercedes the first one
+     * 6. Move to EOT
+     * 7. Move to next Phase
+     * 8. Cancel EOT
      */
-    @Test(enabled=true, groups="demos")
+    @Test(enabled = true, groups = "demos")
     public void testDemo1() throws EntitlementBillingApiException {
 
         log.info("Starting testSubscriptionWithAddOn");
@@ -76,7 +76,7 @@ public class TestUserApiDemos extends TestApiBase {
 
             /* STEP 1. CREATE SUBSCRIPTION */
             SubscriptionData subscription = createSubscription("Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
-            PlanPhase trialPhase = subscription.getCurrentPhase();
+            final PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             displayState(subscription.getId(), "STEP 1. CREATED SUBSCRIPTION");
@@ -97,12 +97,12 @@ public class TestUserApiDemos extends TestApiBase {
             displayState(subscription.getId(), "STEP 3. MOVE TO DISCOUNT PHASE");
 
             /* STEP 4. SET CTD AND CHANGE PLAN EOT */
-            List<Duration> durationList = new ArrayList<Duration>();
+            final List<Duration> durationList = new ArrayList<Duration>();
             durationList.add(trialPhase.getDuration());
-            DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
+            final DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
 
-            Duration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
+            final Duration ctd = getDurationMonth(1);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
@@ -174,36 +174,36 @@ public class TestUserApiDemos extends TestApiBase {
     }
 
 
-    private void displayState(UUID subscriptionId, String stepMsg) {
+    private void displayState(final UUID subscriptionId, final String stepMsg) {
 
         System.out.println("");
         System.out.println("******\t STEP " + stepMsg + " **************");
         try {
-            SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscriptionId);
+            final SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscriptionId);
 
 
-            Plan currentPlan = subscription.getCurrentPlan();
-            PlanPhase currentPhase = subscription.getCurrentPhase();
-            String priceList = subscription.getCurrentPriceList().getName();
+            final Plan currentPlan = subscription.getCurrentPlan();
+            final PlanPhase currentPhase = subscription.getCurrentPhase();
+            final String priceList = subscription.getCurrentPriceList().getName();
 
             System.out.println("");
             System.out.println("\t CURRENT TIME = " + clock.getUTCNow());
             System.out.println("");
-            System.out.println("\t CURRENT STATE = " +  subscription.getState());
-            System.out.println("\t CURRENT PRODUCT = " +  ((currentPlan == null) ? "NONE" : currentPlan.getProduct().getName()));
-            System.out.println("\t CURRENT TERM = " +  ((currentPlan == null) ? "NONE" : currentPlan.getBillingPeriod().toString()));
-            System.out.println("\t CURRENT PHASE = " +  ((currentPhase == null) ? "NONE" : currentPhase.getPhaseType()));
+            System.out.println("\t CURRENT STATE = " + subscription.getState());
+            System.out.println("\t CURRENT PRODUCT = " + ((currentPlan == null) ? "NONE" : currentPlan.getProduct().getName()));
+            System.out.println("\t CURRENT TERM = " + ((currentPlan == null) ? "NONE" : currentPlan.getBillingPeriod().toString()));
+            System.out.println("\t CURRENT PHASE = " + ((currentPhase == null) ? "NONE" : currentPhase.getPhaseType()));
             System.out.println("\t CURRENT PRICE LIST = " + ((priceList == null) ? "NONE" : priceList));
-            System.out.println("\t CURRENT \'SLUG\' = " +  ((currentPhase == null) ? "NONE" : currentPhase.getName()));
+            System.out.println("\t CURRENT \'SLUG\' = " + ((currentPhase == null) ? "NONE" : currentPhase.getName()));
 
         } catch (EntitlementUserApiException e) {
-            System.out.println("No subscription found for id:"  + subscriptionId );
+            System.out.println("No subscription found for id:" + subscriptionId);
         }
         System.out.println("");
 
     }
 
-    @Test(enabled= true, groups={"stress"})
+    @Test(enabled = true, groups = {"stress"})
     public void stressTest() throws Exception {
         for (int i = 0; i < 100; i++) {
             cleanupTest();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
index c56e0e0..fa947f1 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
@@ -16,13 +16,8 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import java.util.UUID;
-
 import javax.annotation.Nullable;
+import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
@@ -42,6 +37,10 @@ import com.ning.billing.entitlement.api.TestApiBase;
 import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 import com.ning.billing.util.clock.DefaultClock;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
 public class TestUserApiError extends TestApiBase {
 
 
@@ -51,11 +50,11 @@ public class TestUserApiError extends TestApiBase {
     }
 
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCreateSubscriptionBadCatalog() {
-        
+
         log.info("Starting testCreateSubscriptionBadCatalog");
-        
+
         // WRONG PRODUCTS
         tCreateSubscriptionInternal(bundle.getId(), null, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.CAT_NULL_PRODUCT_NAME);
         tCreateSubscriptionInternal(bundle.getId(), "Whatever", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.CAT_NO_SUCH_PRODUCT);
@@ -70,19 +69,19 @@ public class TestUserApiError extends TestApiBase {
 
     }
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCreateSubscriptionNoBundle() {
         log.info("Starting testCreateSubscriptionNoBundle");
         tCreateSubscriptionInternal(null, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_NO_BUNDLE);
     }
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCreateSubscriptionNoBP() {
         log.info("Starting testCreateSubscriptionNoBP");
         tCreateSubscriptionInternal(bundle.getId(), "Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_NO_BP);
     }
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCreateSubscriptionBPExists() {
         log.info("Starting testCreateSubscriptionBPExists");
         try {
@@ -94,11 +93,11 @@ public class TestUserApiError extends TestApiBase {
         }
     }
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testRecreateSubscriptionBPNotCancelled() {
         log.info("Starting testRecreateSubscriptionBPNotCancelled");
         try {
-            SubscriptionData subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
+            final SubscriptionData subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
             try {
                 subscription.recreate(getProductSpecifier("Pistol", PriceListSet.DEFAULT_PRICELIST_NAME, BillingPeriod.MONTHLY, null), clock.getUTCNow(), context);
                 Assert.assertFalse(true);
@@ -111,12 +110,12 @@ public class TestUserApiError extends TestApiBase {
         }
     }
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCreateSubscriptionAddOnNotAvailable() {
         log.info("Starting testCreateSubscriptionAddOnNotAvailable");
         try {
-            UUID accountId = UUID.randomUUID();
-            SubscriptionBundle aoBundle = entitlementApi.createBundleForAccount(accountId, "myAOBundle", context);
+            final UUID accountId = UUID.randomUUID();
+            final SubscriptionBundle aoBundle = entitlementApi.createBundleForAccount(accountId, "myAOBundle", context);
             createSubscriptionWithBundle(aoBundle.getId(), "Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
             tCreateSubscriptionInternal(aoBundle.getId(), "Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_AO_NOT_AVAILABLE);
         } catch (Exception e) {
@@ -125,12 +124,12 @@ public class TestUserApiError extends TestApiBase {
         }
     }
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testCreateSubscriptionAddOnIncluded() {
         log.info("Starting testCreateSubscriptionAddOnIncluded");
         try {
-            UUID accountId = UUID.randomUUID();
-            SubscriptionBundle aoBundle = entitlementApi.createBundleForAccount(accountId, "myAOBundle", context);
+            final UUID accountId = UUID.randomUUID();
+            final SubscriptionBundle aoBundle = entitlementApi.createBundleForAccount(accountId, "myAOBundle", context);
             createSubscriptionWithBundle(aoBundle.getId(), "Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
             tCreateSubscriptionInternal(aoBundle.getId(), "Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_AO_ALREADY_INCLUDED);
         } catch (Exception e) {
@@ -140,12 +139,12 @@ public class TestUserApiError extends TestApiBase {
     }
 
 
-    private void tCreateSubscriptionInternal(@Nullable UUID bundleId, @Nullable String productName,
-            @Nullable BillingPeriod term, String planSet, ErrorCode expected)  {
+    private void tCreateSubscriptionInternal(@Nullable final UUID bundleId, @Nullable final String productName,
+                                             @Nullable final BillingPeriod term, final String planSet, final ErrorCode expected) {
         try {
             entitlementApi.createSubscription(bundleId,
-                    getProductSpecifier(productName, planSet, term, null),
-                    clock.getUTCNow(), context);
+                                              getProductSpecifier(productName, planSet, term, null),
+                                              clock.getUTCNow(), context);
             Assert.fail("Exception expected, error code: " + expected);
         } catch (EntitlementUserApiException e) {
             assertEquals(e.getCode(), expected.getCode());
@@ -158,11 +157,11 @@ public class TestUserApiError extends TestApiBase {
     }
 
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testChangeSubscriptionNonActive() {
         log.info("Starting testChangeSubscriptionNonActive");
         try {
-            Subscription subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
+            final Subscription subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
 
             testListener.pushExpectedEvent(NextEvent.CANCEL);
             subscription.cancel(clock.getUTCNow(), false, context);
@@ -183,25 +182,25 @@ public class TestUserApiError extends TestApiBase {
     }
 
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testChangeSubscriptionFutureCancelled() {
         log.info("Starting testChangeSubscriptionFutureCancelled");
         try {
             Subscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
-            PlanPhase trialPhase = subscription.getCurrentPhase();
+            final PlanPhase trialPhase = subscription.getCurrentPhase();
 
             // MOVE TO NEXT PHASE
-            PlanPhase currentPhase = subscription.getCurrentPhase();
+            final PlanPhase currentPhase = subscription.getCurrentPhase();
             testListener.pushExpectedEvent(NextEvent.PHASE);
-            Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
+            final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
             clock.addDeltaFromReality(it.toDurationMillis());
             assertTrue(testListener.isCompleted(5000));
 
 
             // SET CTD TO CANCEL IN FUTURE
-            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
-            Duration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
+            final DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            final Duration ctd = getDurationMonth(1);
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
 
             subscription = entitlementApi.getSubscriptionFromId(subscription.getId());
@@ -217,7 +216,7 @@ public class TestUserApiError extends TestApiBase {
                     assertFalse(true);
                 }
             }
-            
+
             assertListenerStatus();
         } catch (Exception e) {
             e.printStackTrace();
@@ -226,16 +225,16 @@ public class TestUserApiError extends TestApiBase {
     }
 
 
-    @Test(enabled=false, groups={"fast"})
+    @Test(enabled = false, groups = {"fast"})
     public void testCancelBadState() {
         log.info("Starting testCancelBadState");
     }
 
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled = true, groups = {"fast"})
     public void testUncancelBadState() {
         log.info("Starting testUncancelBadState");
         try {
-            Subscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
+            final Subscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
             try {
                 subscription.uncancel(context);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiPriceList.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiPriceList.java
index a1a0dc7..36d699d 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiPriceList.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiPriceList.java
@@ -19,7 +19,7 @@ package com.ning.billing.entitlement.api.user;
 import com.google.inject.Injector;
 import com.ning.billing.entitlement.api.TestApiBase;
 
-public class TestUserApiPriceList extends TestApiBase  {
+public class TestUserApiPriceList extends TestApiBase {
 
     @Override
     protected Injector getInjector() {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java
index 389ac5f..cd09fdf 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreate.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,9 +26,13 @@ import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.entitlement.api.TestApiBase;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 public abstract class TestUserApiRecreate extends TestApiBase {
 
-    private static Logger log = LoggerFactory.getLogger(TestUserApiRecreate.class);
+    private static final Logger log = LoggerFactory.getLogger(TestUserApiRecreate.class);
 
 
     protected void testRecreateWithBPCanceledThroughSubscription() {
@@ -41,7 +41,7 @@ public abstract class TestUserApiRecreate extends TestApiBase {
             testCreateAndRecreate(false);
             assertListenerStatus();
         } catch (EntitlementUserApiException e) {
-            log.error("Unexpected exception",e);
+            log.error("Unexpected exception", e);
             Assert.fail(e.getMessage());
         }
     }
@@ -52,16 +52,16 @@ public abstract class TestUserApiRecreate extends TestApiBase {
             testCreateAndRecreate(true);
             assertListenerStatus();
         } catch (EntitlementUserApiException e) {
-            log.error("Unexpected exception",e);
+            log.error("Unexpected exception", e);
             Assert.fail(e.getMessage());
         }
     }
 
 
-    private SubscriptionData testCreateAndRecreate(boolean fromUserAPi) throws EntitlementUserApiException {
+    private SubscriptionData testCreateAndRecreate(final boolean fromUserAPi) throws EntitlementUserApiException {
 
-        DateTime init = clock.getUTCNow();
-        DateTime requestedDate = init.minusYears(1);
+        final DateTime init = clock.getUTCNow();
+        final DateTime requestedDate = init.minusYears(1);
 
         String productName = "Shotgun";
         BillingPeriod term = BillingPeriod.MONTHLY;
@@ -70,7 +70,7 @@ public abstract class TestUserApiRecreate extends TestApiBase {
         testListener.pushExpectedEvent(NextEvent.PHASE);
         testListener.pushExpectedEvent(NextEvent.CREATE);
         SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
+                                                                                             getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
         assertNotNull(subscription);
         assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         assertEquals(subscription.getBundleId(), bundle.getId());
@@ -87,7 +87,7 @@ public abstract class TestUserApiRecreate extends TestApiBase {
 
             if (fromUserAPi) {
                 subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                        getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
+                                                                                    getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
             } else {
                 subscription.recreate(getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
             }
@@ -113,7 +113,7 @@ public abstract class TestUserApiRecreate extends TestApiBase {
 
         if (fromUserAPi) {
             subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(),
-                    getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
+                                                                                getProductSpecifier(productName, planSetName, term, null), requestedDate, context);
         } else {
             subscription.recreate(getProductSpecifier(productName, planSetName, term, null), clock.getUTCNow(), context);
         }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateMemory.java
index b6f97c1..b164d65 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateMemory.java
@@ -32,13 +32,13 @@ public class TestUserApiRecreateMemory extends TestUserApiRecreate {
     }
 
     @Override
-    @Test(enabled=false, groups={"fast"})
+    @Test(enabled = false, groups = {"fast"})
     protected void testRecreateWithBPCanceledThroughSubscription() {
         super.testRecreateWithBPCanceledThroughSubscription();
     }
 
     @Override
-    @Test(enabled=false, groups={"fast"})
+    @Test(enabled = false, groups = {"fast"})
     protected void testCreateWithBPCanceledFromUserApi() {
         super.testRecreateWithBPCanceledThroughSubscription();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateSql.java
index 2c1db68..7b6217c 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiRecreateSql.java
@@ -31,13 +31,13 @@ public class TestUserApiRecreateSql extends TestUserApiRecreate {
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     protected void testRecreateWithBPCanceledThroughSubscription() {
         super.testRecreateWithBPCanceledThroughSubscription();
     }
 
     @Override
-    @Test(enabled=true, groups={"slow"})
+    @Test(enabled = true, groups = {"slow"})
     protected void testCreateWithBPCanceledFromUserApi() {
         super.testRecreateWithBPCanceledThroughSubscription();
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
index 7f874de..81aa23b 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
 import org.testng.Assert;
@@ -38,6 +34,10 @@ import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
 import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 import com.ning.billing.util.clock.DefaultClock;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
 public class TestUserApiScenarios extends TestApiBase {
 
     @Override
@@ -45,14 +45,14 @@ public class TestUserApiScenarios extends TestApiBase {
         return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
-    @Test(groups={"slow"}, enabled=true)
+    @Test(groups = {"slow"}, enabled = true)
     public void testChangeIMMCancelUncancelChangeEOT() throws EntitlementBillingApiException {
 
         log.info("Starting testChangeIMMCancelUncancelChangeEOT");
 
         try {
             SubscriptionData subscription = createSubscription("Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
-            PlanPhase trialPhase = subscription.getCurrentPhase();
+            final PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             testListener.pushExpectedEvent(NextEvent.CHANGE);
@@ -66,9 +66,9 @@ public class TestUserApiScenarios extends TestApiBase {
             assertTrue(testListener.isCompleted(5000));
 
             // SET CTD
-            Duration ctd = getDurationMonth(1);
-            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
-            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
+            final Duration ctd = getDurationMonth(1);
+            final DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            final DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate, context);
             subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
@@ -83,12 +83,12 @@ public class TestUserApiScenarios extends TestApiBase {
             subscription.uncancel(context);
 
             // CHANGE EOT
-            testListener.setNonExpectedMode();            
+            testListener.setNonExpectedMode();
             testListener.pushExpectedEvent(NextEvent.CHANGE);
             subscription.changePlan("Pistol", BillingPeriod.MONTHLY, "gunclubDiscount", clock.getUTCNow(), context);
             assertFalse(testListener.isCompleted(5000));
             testListener.reset();
-            
+
             testListener.pushExpectedEvent(NextEvent.CHANGE);
             it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(1));
             clock.addDeltaFromReality(it.toDurationMillis());
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
index e21af4a..ec5c17e 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.entitlement.engine.dao;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
@@ -25,7 +26,6 @@ import java.util.Map;
 import java.util.TreeSet;
 import java.util.UUID;
 
-import org.apache.commons.lang.NotImplementedException;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
@@ -41,12 +41,13 @@ import com.ning.billing.entitlement.api.migration.AccountMigrationData;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.BundleMigrationData;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.SubscriptionMigrationData;
 import com.ning.billing.entitlement.api.timeline.SubscriptionDataRepair;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
-import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.engine.core.Engine;
+import com.ning.billing.entitlement.engine.core.EntitlementNotificationKey;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
 import com.ning.billing.entitlement.events.user.ApiEvent;
@@ -60,13 +61,12 @@ import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotifi
 
 public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlementDao {
 
-    protected final static Logger log = LoggerFactory.getLogger(EntitlementDao.class);
+    protected static final Logger log = LoggerFactory.getLogger(EntitlementDao.class);
 
     private final List<SubscriptionBundle> bundles;
     private final List<Subscription> subscriptions;
     private final TreeSet<EntitlementEvent> events;
     private final Clock clock;
-    private final EntitlementConfig config;
     private final NotificationQueueService notificationQueueService;
     private final CatalogService catalogService;
 
@@ -76,7 +76,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
                                     final CatalogService catalogService) {
         super();
         this.clock = clock;
-        this.config = config;
+        final EntitlementConfig config1 = config;
         this.catalogService = catalogService;
         this.notificationQueueService = notificationQueueService;
         this.bundles = new ArrayList<SubscriptionBundle>();
@@ -93,7 +93,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
 
     @Override
     public List<SubscriptionBundle> getSubscriptionBundleForAccount(final UUID accountId) {
-        List<SubscriptionBundle> results = new ArrayList<SubscriptionBundle>();
+        final List<SubscriptionBundle> results = new ArrayList<SubscriptionBundle>();
         for (final SubscriptionBundle cur : bundles) {
             if (cur.getAccountId().equals(accountId)) {
                 results.add(cur);
@@ -158,34 +158,24 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
     @Override
     public void createSubscription(final SubscriptionData subscription, final List<EntitlementEvent> initialEvents,
                                    final CallContext context) {
-        synchronized(events) {
+        synchronized (events) {
             events.addAll(initialEvents);
             for (final EntitlementEvent cur : initialEvents) {
-                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new NotificationKey() {
-                    @Override
-                    public String toString() {
-                        return cur.getId().toString();
-                    }
-                });
+                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new EntitlementNotificationKey(cur.getId()));
             }
         }
-        Subscription updatedSubscription = buildSubscription(null, subscription);
+        final Subscription updatedSubscription = buildSubscription(null, subscription);
         subscriptions.add(updatedSubscription);
     }
 
     @Override
     public void recreateSubscription(final UUID subscriptionId,
-            final List<EntitlementEvent> recreateEvents, final CallContext context) {
+                                     final List<EntitlementEvent> recreateEvents, final CallContext context) {
 
-        synchronized(events) {
+        synchronized (events) {
             events.addAll(recreateEvents);
             for (final EntitlementEvent cur : recreateEvents) {
-                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new NotificationKey() {
-                    @Override
-                    public String toString() {
-                        return cur.getId().toString();
-                    }
-                });
+                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new EntitlementNotificationKey(cur.getId()));
             }
         }
     }
@@ -193,7 +183,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
     @Override
     public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId) {
 
-        List<Subscription> results = new ArrayList<Subscription>();
+        final List<Subscription> results = new ArrayList<Subscription>();
         for (final Subscription cur : subscriptions) {
             if (cur.getBundleId().equals(bundleId)) {
                 results.add(buildSubscription(factory, (SubscriptionData) cur));
@@ -204,8 +194,8 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
 
     @Override
     public List<EntitlementEvent> getEventsForSubscription(final UUID subscriptionId) {
-        synchronized(events) {
-            List<EntitlementEvent> results = new LinkedList<EntitlementEvent>();
+        synchronized (events) {
+            final List<EntitlementEvent> results = new LinkedList<EntitlementEvent>();
             for (final EntitlementEvent cur : events) {
                 if (cur.getSubscriptionId().equals(subscriptionId)) {
                     results.add(cur);
@@ -217,12 +207,12 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
 
     @Override
     public List<EntitlementEvent> getPendingEventsForSubscription(final UUID subscriptionId) {
-        synchronized(events) {
-            List<EntitlementEvent> results = new LinkedList<EntitlementEvent>();
+        synchronized (events) {
+            final List<EntitlementEvent> results = new LinkedList<EntitlementEvent>();
             for (final EntitlementEvent cur : events) {
                 if (cur.isActive() &&
                         cur.getEffectiveDate().isAfter(clock.getUTCNow()) &&
-                            cur.getSubscriptionId().equals(subscriptionId)) {
+                        cur.getSubscriptionId().equals(subscriptionId)) {
                     results.add(cur);
                 }
             }
@@ -250,26 +240,25 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
     }
 
 
-
     private Subscription buildSubscription(final SubscriptionFactory factory, final SubscriptionData in) {
-    	if (factory != null) {
-    		return factory.createSubscription(new SubscriptionBuilder(in), getEventsForSubscription(in.getId()));
-    	} else {
-    		SubscriptionData subscription = new SubscriptionData(new SubscriptionBuilder(in), null, clock);
+        if (factory != null) {
+            return factory.createSubscription(new SubscriptionBuilder(in), getEventsForSubscription(in.getId()));
+        } else {
+            final SubscriptionData subscription = new SubscriptionData(new SubscriptionBuilder(in), null, clock);
             if (events.size() > 0) {
                 subscription.rebuildTransitions(getEventsForSubscription(in.getId()), catalogService.getFullCatalog());
             }
             return subscription;
-    	}
+        }
     }
 
     @Override
     public void updateChargedThroughDate(final SubscriptionData subscription, final CallContext context) {
 
         boolean found = false;
-        Iterator<Subscription> it = subscriptions.iterator();
+        final Iterator<Subscription> it = subscriptions.iterator();
         while (it.hasNext()) {
-            Subscription cur = it.next();
+            final Subscription cur = it.next();
             if (cur.getId().equals(subscription.getId())) {
                 found = true;
                 it.remove();
@@ -284,7 +273,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
     @Override
     public void cancelSubscription(final UUID subscriptionId, final EntitlementEvent cancelEvent,
                                    final CallContext context, final int seqId) {
-        synchronized(events) {
+        synchronized (events) {
             cancelNextPhaseEvent(subscriptionId);
             insertEvent(cancelEvent);
         }
@@ -293,47 +282,37 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
     @Override
     public void changePlan(final UUID subscriptionId, final List<EntitlementEvent> changeEvents,
                            final CallContext context) {
-        synchronized(events) {
+        synchronized (events) {
             cancelNextChangeEvent(subscriptionId);
             cancelNextPhaseEvent(subscriptionId);
             events.addAll(changeEvents);
             for (final EntitlementEvent cur : changeEvents) {
-                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new NotificationKey() {
-                    @Override
-                    public String toString() {
-                        return cur.getId().toString();
-                    }
-                });
+                recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new EntitlementNotificationKey(cur.getId()));
             }
         }
     }
 
     private void insertEvent(final EntitlementEvent event) {
-        synchronized(events) {
+        synchronized (events) {
             events.add(event);
-            recordFutureNotificationFromTransaction(null, event.getEffectiveDate(), new NotificationKey() {
-                @Override
-                public String toString() {
-                    return event.getId().toString();
-                }
-            });
+            recordFutureNotificationFromTransaction(null, event.getEffectiveDate(), new EntitlementNotificationKey(event.getId()));
         }
     }
 
-    
+
     private void cancelNextPhaseEvent(final UUID subscriptionId) {
 
-        Subscription curSubscription = getSubscriptionFromId(null, subscriptionId);
+        final Subscription curSubscription = getSubscriptionFromId(null, subscriptionId);
         if (curSubscription.getCurrentPhase() == null ||
                 curSubscription.getCurrentPhase().getDuration().getUnit() == TimeUnit.UNLIMITED) {
             return;
         }
 
-        synchronized(events) {
+        synchronized (events) {
 
-            Iterator<EntitlementEvent> it = events.descendingIterator();
+            final Iterator<EntitlementEvent> it = events.descendingIterator();
             while (it.hasNext()) {
-                EntitlementEvent cur = it.next();
+                final EntitlementEvent cur = it.next();
                 if (cur.getSubscriptionId() != subscriptionId) {
                     continue;
                 }
@@ -350,11 +329,11 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
 
     private void cancelNextChangeEvent(final UUID subscriptionId) {
 
-        synchronized(events) {
+        synchronized (events) {
 
-            Iterator<EntitlementEvent> it = events.descendingIterator();
+            final Iterator<EntitlementEvent> it = events.descendingIterator();
             while (it.hasNext()) {
-                EntitlementEvent cur = it.next();
+                final EntitlementEvent cur = it.next();
                 if (cur.getSubscriptionId() != subscriptionId) {
                     continue;
                 }
@@ -374,9 +353,9 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
 
         synchronized (events) {
             boolean foundCancel = false;
-            Iterator<EntitlementEvent> it = events.descendingIterator();
+            final Iterator<EntitlementEvent> it = events.descendingIterator();
             while (it.hasNext()) {
-                EntitlementEvent cur = it.next();
+                final EntitlementEvent cur = it.next();
                 if (cur.getSubscriptionId() != subscriptionId) {
                     continue;
                 }
@@ -398,20 +377,15 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
 
     @Override
     public void migrate(final UUID accountId, final AccountMigrationData accountData, final CallContext context) {
-        synchronized(events) {
+        synchronized (events) {
 
             for (final BundleMigrationData curBundle : accountData.getData()) {
-                SubscriptionBundleData bundleData = curBundle.getData();
+                final SubscriptionBundleData bundleData = curBundle.getData();
                 for (final SubscriptionMigrationData curSubscription : curBundle.getSubscriptions()) {
-                    SubscriptionData subData = curSubscription.getData();
+                    final SubscriptionData subData = curSubscription.getData();
                     for (final EntitlementEvent curEvent : curSubscription.getInitialEvents()) {
                         events.add(curEvent);
-                        recordFutureNotificationFromTransaction(null, curEvent.getEffectiveDate(), new NotificationKey() {
-                            @Override
-                            public String toString() {
-                                return curEvent.getId().toString();
-                            }
-                        });
+                        recordFutureNotificationFromTransaction(null, curEvent.getEffectiveDate(), new EntitlementNotificationKey(curEvent.getId()));
 
                     }
                     subscriptions.add(subData);
@@ -423,7 +397,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
 
     @Override
     public EntitlementEvent getEventById(final UUID eventId) {
-        synchronized(events) {
+        synchronized (events) {
             for (final EntitlementEvent cur : events) {
                 if (cur.getId().equals(eventId)) {
                     return cur;
@@ -435,22 +409,24 @@ public class MockEntitlementDaoMemory implements EntitlementDao, MockEntitlement
 
     private void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime effectiveDate, final NotificationKey notificationKey) {
         try {
-            NotificationQueue subscriptionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
-                Engine.NOTIFICATION_QUEUE_NAME);
+            final NotificationQueue subscriptionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
+                                                                                                     Engine.NOTIFICATION_QUEUE_NAME);
             subscriptionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, notificationKey);
         } catch (NoSuchNotificationQueue e) {
             throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);            
         }
     }
 
     @Override
-    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(UUID bundleId) {
+    public Map<UUID, List<EntitlementEvent>> getEventsForBundle(final UUID bundleId) {
         // TODO Auto-generated method stub
         return null;
     }
 
     @Override
-    public void repair(UUID accountId, UUID bundleId, List<SubscriptionDataRepair> inRepair,
-            CallContext context) {
+    public void repair(final UUID accountId, final UUID bundleId, final List<SubscriptionDataRepair> inRepair,
+                       final CallContext context) {
     }
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
index 71f3168..929f03d 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoSql.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.entitlement.engine.dao;
 
-import com.ning.billing.util.bus.Bus;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.Transaction;
 import org.skife.jdbi.v2.TransactionStatus;
@@ -26,8 +25,8 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
 import com.google.inject.Inject;
 import com.ning.billing.entitlement.engine.addon.AddonUtils;
+import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.clock.Clock;
-
 import com.ning.billing.util.notificationq.NotificationQueueService;
 
 public class MockEntitlementDaoSql extends AuditedEntitlementDao implements MockEntitlementDao {
@@ -35,7 +34,7 @@ public class MockEntitlementDaoSql extends AuditedEntitlementDao implements Mock
     private final ResetSqlDao resetDao;
 
     @Inject
-    public MockEntitlementDaoSql(IDBI dbi, Clock clock, AddonUtils addonUtils, NotificationQueueService notificationQueueService,
+    public MockEntitlementDaoSql(final IDBI dbi, final Clock clock, final AddonUtils addonUtils, final NotificationQueueService notificationQueueService,
                                  final Bus eventBus) {
         super(dbi, clock, addonUtils, notificationQueueService, eventBus);
         this.resetDao = dbi.onDemand(ResetSqlDao.class);
@@ -47,7 +46,7 @@ public class MockEntitlementDaoSql extends AuditedEntitlementDao implements Mock
         resetDao.inTransaction(new Transaction<Void, ResetSqlDao>() {
 
             @Override
-            public Void inTransaction(ResetSqlDao dao, TransactionStatus status)
+            public Void inTransaction(final ResetSqlDao dao, final TransactionStatus status)
                     throws Exception {
                 resetDao.resetEvents();
                 resetDao.resetSubscriptions();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
index d541d63..844bf90 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModule.java
@@ -20,12 +20,11 @@ import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.catalog.glue.CatalogModule;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.glue.MockClockModule;
-import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.CallContextModule;
 
 public class MockEngineModule extends DefaultEntitlementModule {
 
-   
+
     @Override
     protected void configure() {
         super.configure();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
index 4cfeb9d..51a55a0 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/MockEngineModuleSql.java
@@ -17,25 +17,21 @@
 package com.ning.billing.entitlement.glue;
 
 
-import com.google.inject.name.Names;
-
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
 
-
+import com.google.inject.name.Names;
 import com.ning.billing.dbi.DBIProvider;
 import com.ning.billing.dbi.DbiConfig;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.entitlement.api.timeline.RepairEntitlementLifecycleDao;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.engine.dao.MockEntitlementDaoSql;
-
 import com.ning.billing.entitlement.engine.dao.RepairEntitlementDao;
-
 import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.glue.BusModule.BusType;
 import com.ning.billing.util.glue.CustomFieldModule;
 import com.ning.billing.util.glue.NotificationQueueModule;
-import com.ning.billing.util.glue.BusModule.BusType;
 
 public class MockEngineModuleSql extends MockEngineModule {
 
@@ -47,7 +43,7 @@ public class MockEngineModuleSql extends MockEngineModule {
         bind(RepairEntitlementLifecycleDao.class).annotatedWith(Names.named(REPAIR_NAMED)).to(RepairEntitlementDao.class);
         bind(RepairEntitlementDao.class).asEagerSingleton();
     }
-    
+
 
     protected void installDBI() {
         final MysqlTestingHelper helper = new MysqlTestingHelper();

invoice/pom.xml 19(+7 -12)

diff --git a/invoice/pom.xml b/invoice/pom.xml
index b3528fe..07f9191 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -8,13 +8,12 @@
     OR CONDITIONS OF ANY KIND, either express or implied. See the ~ License for 
     the specific language governing permissions and limitations ~ under the License. -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-invoice</artifactId>
@@ -61,15 +60,16 @@
             <artifactId>joda-time</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.skife.config</groupId>
             <artifactId>config-magic</artifactId>
         </dependency>
         <!-- TEST SCOPE -->
         <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-util</artifactId>
             <type>test-jar</type>
@@ -97,11 +97,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>com.jayway.awaitility</groupId>
             <artifactId>awaitility</artifactId>
             <scope>test</scope>
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
index fca4789..a93ee28 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
@@ -80,16 +80,16 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public void processChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
-        dao.postChargeback(invoicePaymentId, amount, context);
+    public InvoicePayment processChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
+        return dao.postChargeback(invoicePaymentId, amount, context);
     }
 
     @Override
-    public void processChargeback(final UUID invoicePaymentId, final CallContext context) throws InvoiceApiException {
+    public InvoicePayment processChargeback(final UUID invoicePaymentId, final CallContext context) throws InvoiceApiException {
         // use the invoicePaymentId to get the amount remaining on the payment
         // (preventing charge backs totalling more than the payment)
         final BigDecimal amount = dao.getRemainingAmountPaid(invoicePaymentId);
-        processChargeback(invoicePaymentId, amount, context);
+        return processChargeback(invoicePaymentId, amount, context);
     }
 
     @Override
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
index e6dc189..4245ba8 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.invoice.api.user;
 
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
@@ -23,6 +24,10 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 
 import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.InvoiceDispatcher;
 import com.ning.billing.invoice.api.Invoice;
@@ -31,17 +36,22 @@ import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.invoice.dao.InvoiceDao;
+import com.ning.billing.invoice.template.HtmlInvoiceGenerator;
 import com.ning.billing.util.api.TagApiException;
 import com.ning.billing.util.callcontext.CallContext;
 
 public class DefaultInvoiceUserApi implements InvoiceUserApi {
     private final InvoiceDao dao;
     private final InvoiceDispatcher dispatcher;
+    private final AccountUserApi accountUserApi;
+    private final HtmlInvoiceGenerator generator;
 
     @Inject
-    public DefaultInvoiceUserApi(final InvoiceDao dao, final InvoiceDispatcher dispatcher) {
+    public DefaultInvoiceUserApi(final InvoiceDao dao, final InvoiceDispatcher dispatcher, final AccountUserApi accountUserApi, final HtmlInvoiceGenerator generator) {
         this.dao = dao;
         this.dispatcher = dispatcher;
+        this.accountUserApi = accountUserApi;
+        this.generator = generator;
     }
 
     @Override
@@ -79,7 +89,12 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
     public Invoice triggerInvoiceGeneration(final UUID accountId,
                                             final DateTime targetDate, final boolean dryRun,
                                             final CallContext context) throws InvoiceApiException {
-        return dispatcher.processAccount(accountId, targetDate, dryRun, context);
+        Invoice result = dispatcher.processAccount(accountId, targetDate, dryRun, context);
+        if (result == null) {
+            throw new InvoiceApiException(ErrorCode.INVOICE_NOTHING_TO_DO, accountId, targetDate);
+        } else {
+            return result;
+        }
     }
 
     @Override
@@ -102,4 +117,15 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                                     final Currency currency, final CallContext context) throws InvoiceApiException {
         return dao.insertCredit(accountId, amount, effectiveDate, currency, context);
     }
+
+    @Override
+    public String getInvoiceAsHTML(final UUID invoiceId) throws AccountApiException, IOException, InvoiceApiException {
+        final Invoice invoice = getInvoice(invoiceId);
+        if (invoice == null) {
+            throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, invoiceId);
+        }
+
+        final Account account = accountUserApi.getAccountById(invoice.getAccountId());
+        return generator.generateInvoice(account, invoice);
+    }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
index 22ddb71..7102051 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
@@ -255,7 +255,7 @@ public class DefaultInvoiceDao implements InvoiceDao {
 
     @Override
     public InvoicePayment getInvoicePayment(final UUID paymentAttemptId) {
-        return invoicePaymentSqlDao.getInvoicePayment(paymentAttemptId);
+        return invoicePaymentSqlDao.getInvoicePayment(paymentAttemptId.toString());
     }
 
     @Override
@@ -269,18 +269,25 @@ public class DefaultInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
-        final InvoicePayment payment = invoicePaymentSqlDao.getById(invoicePaymentId.toString());
-        if (payment == null) {
-            throw new InvoiceApiException(ErrorCode.INVOICE_PAYMENT_NOT_FOUND, invoicePaymentId.toString());
-        } else {
-            if (amount.compareTo(BigDecimal.ZERO) < 0) {
-                throw new InvoiceApiException(ErrorCode.CHARGE_BACK_AMOUNT_IS_NEGATIVE);
+    public InvoicePayment postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
+        return invoicePaymentSqlDao.inTransaction(new Transaction<InvoicePayment, InvoicePaymentSqlDao>() {
+            @Override
+            public InvoicePayment inTransaction(final InvoicePaymentSqlDao transactional, final TransactionStatus status) throws Exception {
+                final InvoicePayment payment = invoicePaymentSqlDao.getById(invoicePaymentId.toString());
+                if (payment == null) {
+                    throw new InvoiceApiException(ErrorCode.INVOICE_PAYMENT_NOT_FOUND, invoicePaymentId.toString());
+                } else {
+                    if (amount.compareTo(BigDecimal.ZERO) < 0) {
+                        throw new InvoiceApiException(ErrorCode.CHARGE_BACK_AMOUNT_IS_NEGATIVE);
+                    }
+
+                    final InvoicePayment chargeBack = payment.asChargeBack(amount, context.getCreatedDate());
+                    invoicePaymentSqlDao.create(chargeBack, context);
+
+                    return chargeBack;
+                }
             }
-
-            final InvoicePayment chargeBack = payment.asChargeBack(amount, context.getCreatedDate());
-            invoicePaymentSqlDao.create(chargeBack, context);
-        }
+        });
     }
 
     @Override
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
index fe82d6c..888295a 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
@@ -61,7 +61,7 @@ public interface InvoiceDao {
 
     void removeWrittenOff(final UUID invoiceId, final CallContext context) throws TagApiException;
 
-    void postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException;
+    InvoicePayment postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException;
 
     BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId);
 
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
index ebbdbb7..8b12f8d 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.java
@@ -78,7 +78,7 @@ public interface InvoicePaymentSqlDao extends EntitySqlDao<InvoicePayment>, Tran
     public List<InvoicePayment> getPaymentsForInvoice(@Bind("invoiceId") final String invoiceId);
 
     @SqlQuery
-    InvoicePayment getInvoicePayment(@Bind("paymentAttemptId") final UUID paymentAttemptId);
+    InvoicePayment getInvoicePayment(@Bind("paymentAttemptId") final String paymentAttemptId);
 
     @SqlUpdate
     void notifyOfPaymentAttempt(@InvoicePaymentBinder final InvoicePayment invoicePayment,
diff --git a/invoice/src/main/java/com/ning/billing/invoice/glue/DefaultInvoiceModule.java b/invoice/src/main/java/com/ning/billing/invoice/glue/DefaultInvoiceModule.java
index b0fa991..918bfa2 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/glue/DefaultInvoiceModule.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/glue/DefaultInvoiceModule.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * 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
@@ -40,6 +40,7 @@ import com.ning.billing.invoice.model.DefaultInvoiceGenerator;
 import com.ning.billing.invoice.model.InvoiceGenerator;
 import com.ning.billing.invoice.notification.DefaultNextBillingDateNotifier;
 import com.ning.billing.invoice.notification.DefaultNextBillingDatePoster;
+import com.ning.billing.invoice.notification.EmailInvoiceNotifier;
 import com.ning.billing.invoice.notification.NextBillingDateNotifier;
 import com.ning.billing.invoice.notification.NextBillingDatePoster;
 import com.ning.billing.invoice.notification.NullInvoiceNotifier;
@@ -47,36 +48,29 @@ import com.ning.billing.invoice.template.formatters.DefaultInvoiceFormatterFacto
 import com.ning.billing.util.template.translation.TranslatorConfig;
 
 public class DefaultInvoiceModule extends AbstractModule implements InvoiceModule {
+    InvoiceConfig config;
+
     protected void installInvoiceDao() {
         bind(InvoiceDao.class).to(DefaultInvoiceDao.class).asEagerSingleton();
     }
 
-    /* (non-Javadoc)
-     * @see com.ning.billing.invoice.glue.InvoiceModule#installInvoiceUserApi()
-     */
     @Override
     public void installInvoiceUserApi() {
         bind(InvoiceUserApi.class).to(DefaultInvoiceUserApi.class).asEagerSingleton();
     }
 
-    /* (non-Javadoc)
-    * @see com.ning.billing.invoice.glue.InvoiceModule#installInvoiceUserApi()
-    */
     @Override
     public void installInvoiceTestApi() {
         bind(InvoiceTestApi.class).to(DefaultInvoiceTestApi.class).asEagerSingleton();
     }
 
-    /* (non-Javadoc)
-     * @see com.ning.billing.invoice.glue.InvoiceModule#installInvoicePaymentApi()
-     */
     @Override
     public void installInvoicePaymentApi() {
         bind(InvoicePaymentApi.class).to(DefaultInvoicePaymentApi.class).asEagerSingleton();
     }
 
     protected void installConfig() {
-        final InvoiceConfig config = new ConfigurationObjectFactory(System.getProperties()).build(InvoiceConfig.class);
+        config = new ConfigurationObjectFactory(System.getProperties()).build(InvoiceConfig.class);
         bind(InvoiceConfig.class).toInstance(config);
     }
 
@@ -84,9 +78,6 @@ public class DefaultInvoiceModule extends AbstractModule implements InvoiceModul
         bind(InvoiceService.class).to(DefaultInvoiceService.class).asEagerSingleton();
     }
 
-    /* (non-Javadoc)
-    * @see com.ning.billing.invoice.glue.InvoiceModule#installInvoiceMigrationApi()
-    */
     @Override
     public void installInvoiceMigrationApi() {
         bind(InvoiceMigrationApi.class).to(DefaultInvoiceMigrationApi.class).asEagerSingleton();
@@ -97,8 +88,15 @@ public class DefaultInvoiceModule extends AbstractModule implements InvoiceModul
         bind(NextBillingDatePoster.class).to(DefaultNextBillingDatePoster.class).asEagerSingleton();
         final TranslatorConfig config = new ConfigurationObjectFactory(System.getProperties()).build(TranslatorConfig.class);
         bind(TranslatorConfig.class).toInstance(config);
-        bind(InvoiceFormatterFactory.class).to(DefaultInvoiceFormatterFactory.class).asEagerSingleton();
-        bind(InvoiceNotifier.class).to(NullInvoiceNotifier.class).asEagerSingleton();
+        bind(InvoiceFormatterFactory.class).to(config.getInvoiceFormatterFactoryClass()).asEagerSingleton();
+    }
+
+    protected void installInvoiceNotifier() {
+        if (config.isEmailNotificationsEnabled()) {
+            bind(InvoiceNotifier.class).to(EmailInvoiceNotifier.class).asEagerSingleton();
+        } else {
+            bind(InvoiceNotifier.class).to(NullInvoiceNotifier.class).asEagerSingleton();
+        }
     }
 
     protected void installInvoiceListener() {
@@ -111,8 +109,10 @@ public class DefaultInvoiceModule extends AbstractModule implements InvoiceModul
 
     @Override
     protected void configure() {
-        installInvoiceService();
         installConfig();
+
+        installInvoiceService();
+        installInvoiceNotifier();
         installNotifiers();
         installInvoiceListener();
         installInvoiceGenerator();
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
index af6dad1..7d94daa 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceDispatcher.java
@@ -126,7 +126,6 @@ public class InvoiceDispatcher {
             lock = locker.lockWithNumberOfTries(LockerService.INVOICE, accountId.toString(), NB_LOCK_TRY);
 
             return processAccountWithLock(accountId, targetDate, dryRun, context);
-
         } catch (LockFailedException e) {
             // Not good!
             log.error(String.format("Failed to process invoice for account %s, targetDate %s",
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
index 5793dec..601ebeb 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
@@ -59,7 +59,8 @@ public class InvoiceListener {
         try {
             //  Skip future uncancel event
             //  Skip events which are marked as not being the last one
-            if (transition.getTransitionType() == SubscriptionTransitionType.UNCANCEL
+            if (transition.getTransitionType() == SubscriptionTransitionType.UNCANCEL ||
+                    transition.getTransitionType() == SubscriptionTransitionType.MIGRATE_ENTITLEMENT
                     || transition.getRemainingEventsForUserOperation() > 0) {
                 return;
             }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java
index cfd2659..9c9dcb9 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/RecurringInvoiceItem.java
@@ -20,12 +20,16 @@ import java.math.BigDecimal;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
 
 public class RecurringInvoiceItem extends InvoiceItemBase {
+    private final DateTimeFormatter dateTimeFormatter = DateTimeFormat.mediumDate();
+
     private final BigDecimal rate;
     private final UUID reversedItemId;
 
@@ -78,7 +82,7 @@ public class RecurringInvoiceItem extends InvoiceItemBase {
 
     @Override
     public String getDescription() {
-        return String.format("%s from %s to %s", phaseName, startDate.toString(), endDate.toString());
+        return String.format("%s from %s to %s", phaseName, startDate.toString(dateTimeFormatter), endDate.toString(dateTimeFormatter));
     }
 
     public UUID getReversedItemId() {
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java
index 534ee0f..5c03f01 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java
@@ -30,6 +30,7 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.invoice.InvoiceListener;
 import com.ning.billing.invoice.api.DefaultInvoiceService;
+import com.ning.billing.util.notificationq.NotificationKey;
 import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
@@ -52,7 +53,7 @@ public class DefaultNextBillingDateNotifier implements NextBillingDateNotifier {
 
     @Inject
     public DefaultNextBillingDateNotifier(final NotificationQueueService notificationQueueService,
-                                          final InvoiceConfig config, final EntitlementUserApi entitlementUserApi, final InvoiceListener listener) {
+            final InvoiceConfig config, final EntitlementUserApi entitlementUserApi, final InvoiceListener listener) {
         this.notificationQueueService = notificationQueueService;
         this.config = config;
         this.entitlementUserApi = entitlementUserApi;
@@ -62,41 +63,46 @@ public class DefaultNextBillingDateNotifier implements NextBillingDateNotifier {
     @Override
     public void initialize() throws NotificationQueueAlreadyExists {
         nextBillingQueue = notificationQueueService.createNotificationQueue(DefaultInvoiceService.INVOICE_SERVICE_NAME,
-                                                                            NEXT_BILLING_DATE_NOTIFIER_QUEUE,
-                                                                            new NotificationQueueHandler() {
-                                                                                @Override
-                                                                                public void handleReadyNotification(final String notificationKey, final DateTime eventDate) {
-                                                                                    try {
-                                                                                        final UUID key = UUID.fromString(notificationKey);
-                                                                                        try {
-                                                                                            final Subscription subscription = entitlementUserApi.getSubscriptionFromId(key);
-                                                                                            if (subscription == null) {
-                                                                                                log.warn("Next Billing Date Notification Queue handled spurious notification (key: " + key + ")");
-                                                                                            } else {
-                                                                                                processEvent(key, eventDate);
-                                                                                            }
-                                                                                        } catch (EntitlementUserApiException e) {
-                                                                                            log.warn("Next Billing Date Notification Queue handled spurious notification (key: " + key + ")", e);
-                                                                                        }
-                                                                                    } catch (IllegalArgumentException e) {
-                                                                                        log.error("The key returned from the NextBillingNotificationQueue is not a valid UUID", e);
-                                                                                    }
-
-                                                                                }
-                                                                            },
-                                                                            new NotificationConfig() {
-
-                                                                                @Override
-                                                                                public long getSleepTimeMs() {
-                                                                                    return config.getSleepTimeMs();
-                                                                                }
-
-                                                                                @Override
-                                                                                public boolean isNotificationProcessingOff() {
-                                                                                    return config.isNotificationProcessingOff();
-                                                                                }
-                                                                            }
-                                                                           );
+                NEXT_BILLING_DATE_NOTIFIER_QUEUE,
+                new NotificationQueueHandler() {
+            @Override
+            public void handleReadyNotification(final NotificationKey notificationKey, final DateTime eventDate) {
+                try {
+                    
+                    if (! (notificationKey instanceof NextBillingDateNotificationKey)) {
+                        log.error("Invoice service received an unexpected event type {}", notificationKey.getClass().getName());
+                        return;
+                    }
+                    final NextBillingDateNotificationKey key = (NextBillingDateNotificationKey) notificationKey;
+                    try {
+                        final Subscription subscription = entitlementUserApi.getSubscriptionFromId(key.getUuidKey());
+                        if (subscription == null) {
+                            log.warn("Next Billing Date Notification Queue handled spurious notification (key: " + key + ")");
+                        } else {
+                            processEvent(key.getUuidKey(), eventDate);
+                        }
+                    } catch (EntitlementUserApiException e) {
+                        log.warn("Next Billing Date Notification Queue handled spurious notification (key: " + key + ")", e);
+                    }
+                } catch (IllegalArgumentException e) {
+                    log.error("The key returned from the NextBillingNotificationQueue is not a valid UUID", e);
+                }
+
+            }
+        },
+        new NotificationConfig() {
+
+            @Override
+            public long getSleepTimeMs() {
+                return config.getSleepTimeMs();
+            }
+
+            @Override
+            public boolean isNotificationProcessingOff() {
+                return config.isNotificationProcessingOff();
+            }
+        }
+        );
 
     }
 
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
index ffc08a3..f2521de 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDatePoster.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.invoice.notification;
 
+import java.io.IOException;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -51,14 +52,11 @@ public class DefaultNextBillingDatePoster implements NextBillingDatePoster {
                                                                              DefaultNextBillingDateNotifier.NEXT_BILLING_DATE_NOTIFIER_QUEUE);
             log.info("Queuing next billing date notification. id: {}, timestamp: {}", subscriptionId.toString(), futureNotificationTime.toString());
 
-            nextBillingQueue.recordFutureNotificationFromTransaction(transactionalDao, futureNotificationTime, new NotificationKey() {
-                @Override
-                public String toString() {
-                    return subscriptionId.toString();
-                }
-            });
+            nextBillingQueue.recordFutureNotificationFromTransaction(transactionalDao, futureNotificationTime, new NextBillingDateNotificationKey(subscriptionId));
         } catch (NoSuchNotificationQueue e) {
             log.error("Attempting to put items on a non-existent queue (NextBillingDateNotifier).", e);
+        } catch (IOException e) {
+            log.error("Failed to serialize notficationKey for subscriptionId {}", subscriptionId);            
         }
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java b/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
index 22926e0..4a58ab3 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
@@ -59,7 +59,7 @@ public class EmailInvoiceNotifier implements InvoiceNotifier {
 
         final String htmlBody;
         try {
-            htmlBody = generator.generateInvoice(account, invoice, "HtmlInvoiceTemplate");
+            htmlBody = generator.generateInvoice(account, invoice);
         } catch (IOException e) {
             throw new InvoiceApiException(e, ErrorCode.EMAIL_SENDING_FAILED);
         }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/template/formatters/DefaultInvoiceFormatter.java b/invoice/src/main/java/com/ning/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
index 098bde8..6ed5713 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
@@ -179,4 +179,22 @@ public class DefaultInvoiceFormatter implements InvoiceFormatter {
     public UUID getId() {
         return invoice.getId();
     }
+
+    // Expose the fields for children classes. This is useful for further customization of the invoices
+
+    protected TranslatorConfig getConfig() {
+        return config;
+    }
+
+    protected DateTimeFormatter getDateFormatter() {
+        return dateFormatter;
+    }
+
+    protected Locale getLocale() {
+        return locale;
+    }
+
+    protected Invoice getInvoice() {
+        return invoice;
+    }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/template/HtmlInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/template/HtmlInvoiceGenerator.java
index ddfe39a..f27bce7 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/template/HtmlInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/template/HtmlInvoiceGenerator.java
@@ -42,7 +42,7 @@ public class HtmlInvoiceGenerator {
         this.config = config;
     }
 
-    public String generateInvoice(final Account account, final Invoice invoice, final String templateName) throws IOException {
+    public String generateInvoice(final Account account, final Invoice invoice) throws IOException {
         final Map<String, Object> data = new HashMap<String, Object>();
         final DefaultInvoiceTranslator invoiceTranslator = new DefaultInvoiceTranslator(config);
         final Locale locale = new Locale(account.getLocale());
@@ -53,6 +53,6 @@ public class HtmlInvoiceGenerator {
         final InvoiceFormatter formattedInvoice = factory.createInvoiceFormatter(config, invoice, locale);
         data.put("invoice", formattedInvoice);
 
-        return templateEngine.executeTemplate(templateName, data);
+        return templateEngine.executeTemplate(config.getTemplateName(), data);
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/template/translator/DefaultInvoiceTranslator.java b/invoice/src/main/java/com/ning/billing/invoice/template/translator/DefaultInvoiceTranslator.java
index 9f46012..bad6d1b 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/template/translator/DefaultInvoiceTranslator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/template/translator/DefaultInvoiceTranslator.java
@@ -36,7 +36,7 @@ public class DefaultInvoiceTranslator extends DefaultTranslatorBase implements I
 
     @Override
     protected String getBundlePath() {
-        return "com/ning/billing/util/email/translation/InvoiceTranslation";
+        return config.getBundlePath();
     }
 
     @Override
@@ -86,7 +86,7 @@ public class DefaultInvoiceTranslator extends DefaultTranslatorBase implements I
 
     @Override
     public String getCompanyCityProvincePostalCode() {
-        return getTranslation(locale, "");
+        return getTranslation(locale, "companyCityProvincePostalCode");
     }
 
     @Override
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
index 3773a1c..8ccf73b 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoicePaymentSqlDao.sql.stg
@@ -27,7 +27,7 @@ batchCreateFromTransaction() ::= <<
 getByPaymentAttemptId() ::= <<
   SELECT <invoicePaymentFields()>
   FROM invoice_payments
-  WHERE payment_id = :paymentAttemptId;
+  WHERE payment_attempt_id = :paymentAttemptId;
 >>
 
 get() ::= <<
@@ -56,7 +56,7 @@ notifyOfPaymentAttempt() ::= <<
 getInvoicePayment() ::= <<
     SELECT <invoicePaymentFields()>
     FROM invoice_payments
-    WHERE payment_id = :payment_id;
+    WHERE payment_attempt_id = :paymentAttemptId;
 >>
 
 getRecordId() ::= <<
@@ -119,4 +119,4 @@ getChargebacksByAttemptPaymentId() ::= <<
     WHERE reversed_invoice_payment_id IN
         (SELECT id FROM invoice_payments WHERE payment_attempt_id = :paymentAttemptId);
 >>
-;
\ No newline at end of file
+;
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
index ee67f37..7c69562 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
@@ -77,7 +77,7 @@ CREATE TABLE invoices (
     PRIMARY KEY(record_id)
 ) ENGINE=innodb;
 CREATE UNIQUE INDEX invoices_id ON invoices(id);
-CREATE INDEX invoices_account_id ON invoices(account_id ASC);
+CREATE INDEX invoices_account_target ON invoices(account_id ASC, target_date);
 
 DROP TABLE IF EXISTS invoice_payments;
 CREATE TABLE invoice_payments (
@@ -94,6 +94,7 @@ CREATE TABLE invoice_payments (
     PRIMARY KEY(record_id)
 ) ENGINE=innodb;
 CREATE UNIQUE INDEX invoice_payments_id ON invoice_payments(id);
+CREATE INDEX invoice_payments_attempt ON invoice_payments(payment_attempt_id);
 CREATE INDEX invoice_payments_reversals ON invoice_payments(reversed_invoice_payment_id);
 
 DROP VIEW IF EXISTS invoice_payment_summary;
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java b/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java
index 0bc2d9f..27ea80c 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java
@@ -16,6 +16,8 @@
 
 package com.ning.billing.invoice.api.migration;
 
+import org.skife.config.ConfigurationObjectFactory;
+
 import com.ning.billing.invoice.MockModule;
 import com.ning.billing.invoice.api.InvoiceNotifier;
 import com.ning.billing.invoice.glue.DefaultInvoiceModule;
@@ -25,6 +27,7 @@ import com.ning.billing.invoice.notification.NullInvoiceNotifier;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 import com.ning.billing.util.email.templates.TemplateModule;
+import com.ning.billing.util.template.translation.TranslatorConfig;
 
 public class MockModuleNoEntitlement extends MockModule {
 //	@Override
@@ -50,6 +53,9 @@ public class MockModuleNoEntitlement extends MockModule {
                 ((ZombieControl) poster).addResult("insertNextBillingNotification", BrainDeadProxyFactory.ZOMBIE_VOID);
                 bind(NextBillingDatePoster.class).toInstance(poster);
                 bind(InvoiceNotifier.class).to(NullInvoiceNotifier.class).asEagerSingleton();
+
+                final TranslatorConfig config = new ConfigurationObjectFactory(System.getProperties()).build(TranslatorConfig.class);
+                bind(TranslatorConfig.class).toInstance(config);
             }
 
 
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
index a1e17e1..64ee7ac 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
@@ -21,7 +21,6 @@ import java.util.Collection;
 import java.util.List;
 import java.util.UUID;
 
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -69,6 +68,7 @@ import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.globallocker.GlobalLocker;
+import com.ning.billing.util.io.IOUtils;
 
 @Guice(modules = {MockModuleNoEntitlement.class})
 public class TestDefaultInvoiceMigrationApi extends InvoicingTestBase {
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
index e6349c9..d4feb57 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
@@ -102,7 +102,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public void processChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
+    public InvoicePayment processChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
         InvoicePayment existingPayment = null;
         for (final InvoicePayment payment : invoicePayments) {
             if (payment.getId() == invoicePaymentId) {
@@ -113,10 +113,12 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
         if (existingPayment != null) {
             invoicePayments.add(existingPayment.asChargeBack(amount, DateTime.now(DateTimeZone.UTC)));
         }
+
+        return existingPayment;
     }
 
     @Override
-    public void processChargeback(final UUID invoicePaymentId, final CallContext context) throws InvoiceApiException {
+    public InvoicePayment processChargeback(final UUID invoicePaymentId, final CallContext context) throws InvoiceApiException {
         InvoicePayment existingPayment = null;
         for (final InvoicePayment payment : invoicePayments) {
             if (payment.getId() == invoicePaymentId) {
@@ -127,6 +129,8 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
         if (existingPayment != null) {
             this.processChargeback(invoicePaymentId, existingPayment.getAmount(), context);
         }
+
+        return existingPayment;
     }
 
     @Override
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
index b0718db..637dd5a 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
@@ -18,7 +18,6 @@ package com.ning.billing.invoice.dao;
 
 import java.io.IOException;
 
-import org.apache.commons.io.IOUtils;
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.TransactionCallback;
@@ -41,6 +40,7 @@ import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.TestCallContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.tag.api.DefaultTagUserApi;
 import com.ning.billing.util.tag.api.user.TagEventBuilder;
 import com.ning.billing.util.tag.dao.AuditedTagDao;
@@ -80,6 +80,11 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
         public int getNumberOfMonthsInFuture() {
             return 36;
         }
+
+        @Override
+        public boolean isEmailNotificationsEnabled() {
+            return false;
+        }
     };
 
     @BeforeClass(alwaysRun = true)
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
index 68987f8..0564bd0 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
@@ -213,7 +213,7 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public void postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
+    public InvoicePayment postChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
         throw new UnsupportedOperationException();
     }
 
diff --git a/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java b/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java
index 5e4a2c3..1019710 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/glue/InvoiceModuleWithMocks.java
@@ -16,12 +16,17 @@
 
 package com.ning.billing.invoice.glue;
 
+import org.skife.config.ConfigurationObjectFactory;
+
 import com.ning.billing.invoice.api.InvoiceNotifier;
+import com.ning.billing.invoice.api.formatters.InvoiceFormatterFactory;
 import com.ning.billing.invoice.dao.InvoiceDao;
 import com.ning.billing.invoice.dao.MockInvoiceDao;
 import com.ning.billing.invoice.notification.NullInvoiceNotifier;
+import com.ning.billing.invoice.template.formatters.DefaultInvoiceFormatterFactory;
 import com.ning.billing.util.globallocker.GlobalLocker;
 import com.ning.billing.util.globallocker.MockGlobalLocker;
+import com.ning.billing.util.template.translation.TranslatorConfig;
 
 
 public class InvoiceModuleWithMocks extends DefaultInvoiceModule {
@@ -40,6 +45,9 @@ public class InvoiceModuleWithMocks extends DefaultInvoiceModule {
     @Override
     protected void installNotifiers() {
         bind(InvoiceNotifier.class).to(NullInvoiceNotifier.class).asEagerSingleton();
+        final TranslatorConfig config = new ConfigurationObjectFactory(System.getProperties()).build(TranslatorConfig.class);
+        bind(TranslatorConfig.class).toInstance(config);
+        bind(InvoiceFormatterFactory.class).to(DefaultInvoiceFormatterFactory.class).asEagerSingleton();
     }
 
     @Override
diff --git a/invoice/src/test/java/com/ning/billing/invoice/HtmlInvoiceGeneratorTest.java b/invoice/src/test/java/com/ning/billing/invoice/HtmlInvoiceGeneratorTest.java
index c9ca94b..2cb1ad7 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/HtmlInvoiceGeneratorTest.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/HtmlInvoiceGeneratorTest.java
@@ -44,7 +44,6 @@ import static org.testng.Assert.assertNotNull;
 @Test(groups = {"fast", "email"})
 public class HtmlInvoiceGeneratorTest {
     private HtmlInvoiceGenerator g;
-    private static final String TEST_TEMPLATE_NAME = "HtmlInvoiceTemplate";
 
     @BeforeClass
     public void setup() {
@@ -56,7 +55,7 @@ public class HtmlInvoiceGeneratorTest {
 
     @Test
     public void testGenerateInvoice() throws Exception {
-        final String output = g.generateInvoice(createAccount(), createInvoice(), TEST_TEMPLATE_NAME);
+        final String output = g.generateInvoice(createAccount(), createInvoice());
         assertNotNull(output);
         System.out.print(output);
     }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
index e56006f..f1f7614 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
@@ -21,7 +21,6 @@ import java.sql.SQLException;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
@@ -57,9 +56,11 @@ import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.email.templates.TemplateModule;
 import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.BusModule.BusType;
 import com.ning.billing.util.glue.NotificationQueueModule;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.notificationq.DummySqlTest;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
@@ -76,7 +77,6 @@ public class TestNextBillingDateNotifier {
     private InvoiceListenerMock listener;
     private NotificationQueueService notificationQueueService;
 
-
     private static final class InvoiceListenerMock extends InvoiceListener {
         int eventCount = 0;
         UUID latestSubscriptionId = null;
@@ -119,6 +119,7 @@ public class TestNextBillingDateNotifier {
                 install(new MockJunctionModule());
                 install(new MockCatalogModule());
                 install(new NotificationQueueModule());
+                install(new TemplateModule());
 
                 final MysqlTestingHelper helper = new MysqlTestingHelper();
                 bind(MysqlTestingHelper.class).toInstance(helper);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
index f864108..88401ec 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
@@ -20,7 +20,6 @@ import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,6 +62,7 @@ import com.ning.billing.util.callcontext.DefaultCallContextFactory;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.globallocker.GlobalLocker;
+import com.ning.billing.util.io.IOUtils;
 
 @Test(groups = "slow")
 @Guice(modules = {MockModule.class})
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
index 7441173..fe953c0 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
@@ -85,6 +85,11 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
             }
 
             @Override
+            public boolean isEmailNotificationsEnabled() {
+                return false;
+            }
+
+            @Override
             public boolean isNotificationProcessingOff() {
                 throw new UnsupportedOperationException();
             }

jaxrs/pom.xml 6(+3 -3)

diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index e0e04cb..d4ea8bf 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-jaxrs</artifactId>
@@ -28,7 +28,6 @@
         <dependency>
             <groupId>javax.ws.rs</groupId>
             <artifactId>jsr311-api</artifactId>
-            <!-- WHY DO WE NEED VESRION HERE ?? -->
             <version>1.1.1</version>
         </dependency>
         <dependency>
@@ -64,7 +63,8 @@
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountEmailJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountEmailJson.java
new file mode 100644
index 0000000..9a0d074
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountEmailJson.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.json;
+
+import java.util.UUID;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.ning.billing.account.api.AccountEmail;
+
+public class AccountEmailJson {
+    private final String accountId;
+    private final String email;
+
+    @JsonCreator
+    public AccountEmailJson(@JsonProperty("accountId") final String accountId, @JsonProperty("email") final String email) {
+        this.accountId = accountId;
+        this.email = email;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public AccountEmail toAccountEmail() {
+        final UUID accountEmailId = UUID.randomUUID();
+
+        return new AccountEmail() {
+            @Override
+            public UUID getAccountId() {
+                return UUID.fromString(accountId);
+            }
+
+            @Override
+            public String getEmail() {
+                return email;
+            }
+
+            @Override
+            public UUID getId() {
+                return accountEmailId;
+            }
+        };
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("AccountEmailJson");
+        sb.append("{accountId='").append(accountId).append('\'');
+        sb.append(", email='").append(email).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final AccountEmailJson that = (AccountEmailJson) o;
+
+        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+            return false;
+        }
+        if (email != null ? !email.equals(that.email) : that.email != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = accountId != null ? accountId.hashCode() : 0;
+        result = 31 * result + (email != null ? email.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java
index 84950a0..4af8944 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJson.java
@@ -22,7 +22,6 @@ import org.joda.time.DateTimeZone;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountData;
 import com.ning.billing.catalog.api.Currency;
@@ -31,29 +30,29 @@ public class AccountJson extends AccountJsonSimple {
     // STEPH Missing city, locale, postalCode from https://home.ninginc.com:8443/display/REVINFRA/Killbill+1.0+APIs
 
     private final String name;
-    
+
     private final Integer length;
-        
+
     private final String email;
-    
+
     private final Integer billCycleDay;
-    
+
     private final String currency;
-    
+
     private final String paymentMethodId;
-    
+
     private final String timeZone;
-    
+
     private final String address1;
-    
+
     private final String address2;
-    
+
     private final String company;
-    
+
     private final String state;
-    
+
     private final String country;
-    
+
     private final String phone;
 
 
@@ -97,18 +96,18 @@ public class AccountJson extends AccountJsonSimple {
             }
 
             @Override
-            public boolean isMigrated() {
+            public Boolean isMigrated() {
                 return false;
             }
 
             @Override
-            public boolean isNotifiedForInvoices() {
+            public Boolean isNotifiedForInvoices() {
                 return false;
             }
 
             @Override
             public UUID getPaymentMethodId() {
-                return paymentMethodId != null ?  UUID.fromString(paymentMethodId) : null;
+                return paymentMethodId != null ? UUID.fromString(paymentMethodId) : null;
             }
 
             @Override
@@ -118,11 +117,12 @@ public class AccountJson extends AccountJsonSimple {
 
             @Override
             public String getLocale() {
-                return null;
+                // TODO
+                return "en";
             }
 
             @Override
-            public int getFirstNameLength() {
+            public Integer getFirstNameLength() {
                 return length;
             }
 
@@ -157,7 +157,7 @@ public class AccountJson extends AccountJsonSimple {
             }
 
             @Override
-            public int getBillCycleDay() {
+            public Integer getBillCycleDay() {
                 return billCycleDay;
             }
 
@@ -389,8 +389,9 @@ public class AccountJson extends AccountJsonSimple {
             return false;
         }
         if (paymentMethodId == null) {
-            if (other.paymentMethodId != null)
+            if (other.paymentMethodId != null) {
                 return false;
+            }
         } else if (!paymentMethodId.equals(other.paymentMethodId)) {
             return false;
         }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJsonSimple.java
index 78d08ee..d1755cd 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountJsonSimple.java
@@ -17,7 +17,6 @@ package com.ning.billing.jaxrs.json;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
 
 public class AccountJsonSimple {
 
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 4f7288d..94ed09a 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
@@ -24,13 +24,11 @@ import java.util.UUID;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.entitlement.api.timeline.BundleTimeline;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.payment.api.Payment;
-import com.ning.billing.payment.api.Payment.PaymentAttempt;
 import com.ning.billing.payment.api.PaymentStatus;
 
 public class AccountTimelineJson {
@@ -38,7 +36,7 @@ public class AccountTimelineJson {
     private final List<PaymentJsonWithBundleKeys> payments;
 
     private final List<InvoiceJsonWithBundleKeys> invoices;
-    
+
     private final AccountJsonSimple account;
 
 
@@ -106,16 +104,16 @@ public class AccountTimelineJson {
         }
 
         this.payments = new LinkedList<PaymentJsonWithBundleKeys>();
-        for (Payment cur : payments) {
-        
-            String status = cur.getPaymentStatus().toString();
-            BigDecimal paidAmount = cur.getPaymentStatus() == PaymentStatus.SUCCESS ? cur.getAmount() : BigDecimal.ZERO;
+        for (final Payment cur : payments) {
+
+            final String status = cur.getPaymentStatus().toString();
+            final BigDecimal paidAmount = cur.getPaymentStatus() == PaymentStatus.SUCCESS ? cur.getAmount() : BigDecimal.ZERO;
             this.payments.add(new PaymentJsonWithBundleKeys(cur.getAmount(), paidAmount, account.getId().toString(),
-                    cur.getInvoiceId().toString(), cur.getId().toString(), 
-                    cur.getEffectiveDate(), cur.getEffectiveDate(),
-                    cur.getAttempts().size(), cur.getCurrency().toString(), status,
-                    getBundleExternalKey(cur.getInvoiceId(), invoices, bundles)));
-          }
+                                                            cur.getInvoiceId().toString(), cur.getId().toString(),
+                                                            cur.getEffectiveDate(), cur.getEffectiveDate(),
+                                                            cur.getAttempts().size(), cur.getCurrency().toString(), status,
+                                                            getBundleExternalKey(cur.getInvoiceId(), invoices, bundles)));
+        }
     }
 
     public AccountTimelineJson() {
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 18ff9d1..cead496 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
@@ -21,7 +21,6 @@ import java.util.List;
 
 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 {
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 fe7b520..c2ca338 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
@@ -22,7 +22,6 @@ import java.util.UUID;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
 import com.ning.billing.entitlement.api.timeline.BundleTimeline;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleTimelineJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleTimelineJson.java
index d0bee6a..8edc0c0 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleTimelineJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleTimelineJson.java
@@ -20,7 +20,6 @@ import java.util.List;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
 
 public class BundleTimelineJson {
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CatalogJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CatalogJsonSimple.java
new file mode 100644
index 0000000..3a8e86f
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CatalogJsonSimple.java
@@ -0,0 +1,193 @@
+/* 
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package com.ning.billing.jaxrs.json;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.catalog.api.Price;
+import com.ning.billing.catalog.api.Product;
+import com.ning.billing.catalog.api.StaticCatalog;
+
+@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
+public class CatalogJsonSimple {
+    
+    private final ProductJson [] products;
+    
+    public CatalogJsonSimple(StaticCatalog catalog) throws CatalogApiException {
+
+        Map<String, ProductJson> productMap = new HashMap<String, CatalogJsonSimple.ProductJson>();
+
+        Plan [] plans = catalog.getCurrentPlans();
+        for (Plan plan : plans) {
+
+            Product product = plan.getProduct();
+            ProductJson jProduct = productMap.get(product.getName());
+            if (jProduct == null) {
+                jProduct = new ProductJson(product.getCategory().toString(),
+                        product.getName(),
+                        toProductNames(product.getIncluded()), toProductNames(product.getAvailable()));
+                productMap.put(product.getName(), jProduct);
+            }
+
+            int i = 0 ;
+            PhaseJson [] phases = new PhaseJson[plan.getAllPhases().length];
+            for (PlanPhase phase : plan.getAllPhases()) {
+
+                Map<String, BigDecimal> prices = new HashMap<String, BigDecimal>();
+                if (phase.getRecurringPrice() != null) {
+                    for (Price cur : phase.getRecurringPrice().getPrices()) {
+                        prices.put(cur.getCurrency().toString(), cur.getValue());
+                    }
+                }
+                PhaseJson jPhase = new PhaseJson(phase.getPhaseType().toString(), prices);
+                phases[i++] = jPhase;
+            }
+            PlanJson jPlan = new PlanJson(plan.getName(), phases); 
+            jProduct.addPlan(jPlan);
+        }
+        products = productMap.values().toArray(new ProductJson[productMap.values().size()]);
+    }
+    
+    private Collection<String> toProductNames(Product [] in) {
+        return Collections2.transform(Lists.newArrayList(in), new Function<Product, String>() {
+            public String apply(Product input) {
+                return input.getName();
+            }
+        });
+    }
+    
+    @JsonCreator
+    public CatalogJsonSimple(@JsonProperty("products")  ProductJson[] products) {
+        super();
+        this.products = products;
+    }
+    
+    
+
+    public ProductJson[] getProducts() {
+        return products;
+    }
+
+
+    @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
+    public static class ProductJson {
+
+        private final String type;
+        private final String name;
+        private final String [] included;
+        private final String [] available;
+        private final List<PlanJson> plans;
+        
+
+        @JsonCreator
+        public ProductJson(@JsonProperty("type") String type,
+                @JsonProperty("name") String name,
+                @JsonProperty("plans") List<PlanJson> plans,
+                @JsonProperty("included") Collection<String> included,
+                @JsonProperty("available") Collection<String> available) {
+            super();
+            this.type = type;
+            this.name = name;
+            this.included = included.toArray(new String[included.size()]);
+            this.available = available.toArray(new String[available.size()]);
+            this.plans = plans;
+        }
+
+        public ProductJson(String type, String name, Collection<String> included, Collection<String> available) {
+            this(type, name, new LinkedList<CatalogJsonSimple.PlanJson>(), included, available);
+        }
+
+        public void addPlan(PlanJson plan) {
+            plans.add(plan);
+        }
+        
+        public String getType() {
+            return type;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public List<PlanJson> getPlans() {
+            return plans;
+        }
+        
+        public String[] getIncluded() {
+            return included;
+        }
+
+        public String[] getAvailable() {
+            return available;
+        }
+    }
+    
+    @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
+    public static class PlanJson {
+
+        private final String name;
+        private final PhaseJson [] phases;
+        
+        @JsonCreator
+        public PlanJson(@JsonProperty("name") String name,
+                @JsonProperty("phases") PhaseJson[] phases) {
+            super();
+            this.name = name;
+            this.phases = phases;
+        }
+        public String getName() {
+            return name;
+        }
+        public PhaseJson[] getPhases() {
+            return phases;
+        }
+    }
+
+    @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
+    public static class PhaseJson {
+
+        private final String type;
+        private final Map<String, BigDecimal> prices;
+        
+        @JsonCreator
+        public PhaseJson(@JsonProperty("type") String type,
+                @JsonProperty("prices") Map<String, BigDecimal> prices) {
+            super();
+            this.type = type;
+            this.prices = prices;
+        }
+        public String getType() {
+            return type;
+        }
+        public Map<String, BigDecimal> getPrices() {
+            return prices;
+        }
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceEmailJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceEmailJson.java
new file mode 100644
index 0000000..4bffaa6
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceEmailJson.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs.json;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class InvoiceEmailJson {
+    private final String accountId;
+    private final boolean isNotifiedForInvoices;
+
+    @JsonCreator
+    public InvoiceEmailJson(@JsonProperty("accountId") final String accountId,
+                            @JsonProperty("isNotifiedForInvoices") final boolean isNotifiedForInvoices) {
+        this.accountId = accountId;
+        this.isNotifiedForInvoices = isNotifiedForInvoices;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    @JsonGetter("isNotifiedForInvoices")
+    public boolean isNotifiedForInvoices() {
+        return isNotifiedForInvoices;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("InvoiceEmailJson");
+        sb.append("{accountId='").append(accountId).append('\'');
+        sb.append(", isNotifiedForInvoices=").append(isNotifiedForInvoices);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final InvoiceEmailJson that = (InvoiceEmailJson) o;
+
+        if (isNotifiedForInvoices != that.isNotifiedForInvoices) {
+            return false;
+        }
+        if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = accountId != null ? accountId.hashCode() : 0;
+        result = 31 * result + (isNotifiedForInvoices ? 1 : 0);
+        return result;
+    }
+}
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 0cd9d7d..2cb2447 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
@@ -32,7 +32,7 @@ public class InvoiceJsonSimple {
     private final DateTime invoiceDate;
     private final DateTime targetDate;
     private final String invoiceNumber;
-    private final BigDecimal credit;    
+    private final BigDecimal credit;
     private final BigDecimal balance;
     private final String accountId;
 
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 db870fd..caeb147 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
@@ -17,14 +17,12 @@
 package com.ning.billing.jaxrs.json;
 
 import java.math.BigDecimal;
-import java.util.UUID;
 
 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.PaymentInfoEvent;
 import com.ning.billing.util.clock.DefaultClock;
 
 public class PaymentJsonSimple {
@@ -33,11 +31,11 @@ public class PaymentJsonSimple {
     private final BigDecimal amount;
 
     private final String accountId;
-    
+
     private final String invoiceId;
-    
+
     private final String paymentId;
-    
+
     private final DateTime requestedDate;
 
     private final DateTime effectiveDate;
@@ -62,21 +60,21 @@ public class PaymentJsonSimple {
     }
 
     @JsonCreator
-    public PaymentJsonSimple(@JsonProperty("amount") BigDecimal amount,
-            @JsonProperty("paidAmount") BigDecimal paidAmount,
-            @JsonProperty("accountId") String accountId,            
-            @JsonProperty("invoiceId") String invoiceId,
-            @JsonProperty("paymentId") String paymentId,
-            @JsonProperty("requestedDate") DateTime requestedDate,
-            @JsonProperty("effectiveDate") DateTime effectiveDate,
-            @JsonProperty("retryCount") Integer retryCount,
-            @JsonProperty("currency") String currency,
-            @JsonProperty("status") String status) {
+    public PaymentJsonSimple(@JsonProperty("amount") final BigDecimal amount,
+                             @JsonProperty("paidAmount") final BigDecimal paidAmount,
+                             @JsonProperty("accountId") final String accountId,
+                             @JsonProperty("invoiceId") final String invoiceId,
+                             @JsonProperty("paymentId") final String paymentId,
+                             @JsonProperty("requestedDate") final DateTime requestedDate,
+                             @JsonProperty("effectiveDate") final DateTime effectiveDate,
+                             @JsonProperty("retryCount") final Integer retryCount,
+                             @JsonProperty("currency") final String currency,
+                             @JsonProperty("status") final String status) {
         super();
         this.amount = amount;
         this.paidAmount = paidAmount;
         this.invoiceId = invoiceId;
-        this.accountId = accountId;        
+        this.accountId = accountId;
         this.paymentId = paymentId;
         this.requestedDate = DefaultClock.toUTCDateTime(requestedDate);
         this.effectiveDate = DefaultClock.toUTCDateTime(effectiveDate);
@@ -85,7 +83,7 @@ public class PaymentJsonSimple {
         this.status = status;
     }
 
-    public PaymentJsonSimple(Payment src) {
+    public PaymentJsonSimple(final Payment src) {
         this.amount = src.getAmount();
         this.paidAmount = src.getAmount();
         this.invoiceId = src.getInvoiceId().toString();
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 87bbe5d..8032fa5 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
@@ -17,7 +17,6 @@
 package com.ning.billing.jaxrs.json;
 
 import java.math.BigDecimal;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 
@@ -33,17 +32,17 @@ public class PaymentJsonWithBundleKeys extends PaymentJsonSimple {
     }
 
     @JsonCreator
-    public PaymentJsonWithBundleKeys(@JsonProperty("amount") BigDecimal amount,
-            @JsonProperty("paidAmount") BigDecimal paidAmount,
-            @JsonProperty("accountId") String accountId,
-            @JsonProperty("invoiceId") String invoiceId,
-            @JsonProperty("paymentId") String paymentId,
-            @JsonProperty("requestedDt") DateTime requestedDate,
-            @JsonProperty("effectiveDt") DateTime effectiveDate,
-            @JsonProperty("retryCount") Integer retryCount,
-            @JsonProperty("currency") String currency,
-            @JsonProperty("status") String status,
-            @JsonProperty("externalBundleKeys") String bundleKeys) {
+    public PaymentJsonWithBundleKeys(@JsonProperty("amount") final BigDecimal amount,
+                                     @JsonProperty("paidAmount") final BigDecimal paidAmount,
+                                     @JsonProperty("accountId") final String accountId,
+                                     @JsonProperty("invoiceId") final String invoiceId,
+                                     @JsonProperty("paymentId") final String paymentId,
+                                     @JsonProperty("requestedDt") final DateTime requestedDate,
+                                     @JsonProperty("effectiveDt") final DateTime effectiveDate,
+                                     @JsonProperty("retryCount") final Integer retryCount,
+                                     @JsonProperty("currency") final String currency,
+                                     @JsonProperty("status") final String status,
+                                     @JsonProperty("externalBundleKeys") final String bundleKeys) {
         super(amount, paidAmount, accountId, invoiceId, paymentId, requestedDate, effectiveDate, retryCount, currency, status);
         this.bundleKeys = bundleKeys;
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java
index c2979f3..9d7c676 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java
@@ -38,11 +38,11 @@ public class PaymentMethodJson {
     private final PaymentMethodPluginDetailJson pluginInfo;
 
     @JsonCreator
-    public PaymentMethodJson(@JsonProperty("paymentMethodId") String paymentMethodId,
-            @JsonProperty("accountId") String accountId,
-            @JsonProperty("isDefault") Boolean isDefault,
-            @JsonProperty("pluginName") String pluginName,
-            @JsonProperty("pluginInfo") PaymentMethodPluginDetailJson pluginInfo) {
+    public PaymentMethodJson(@JsonProperty("paymentMethodId") final String paymentMethodId,
+                             @JsonProperty("accountId") final String accountId,
+                             @JsonProperty("isDefault") final Boolean isDefault,
+                             @JsonProperty("pluginName") final String pluginName,
+                             @JsonProperty("pluginInfo") final PaymentMethodPluginDetailJson pluginInfo) {
         super();
         this.paymentMethodId = paymentMethodId;
         this.accountId = accountId;
@@ -50,17 +50,17 @@ public class PaymentMethodJson {
         this.pluginName = pluginName;
         this.pluginInfo = pluginInfo;
     }
-    
-    public static PaymentMethodJson toPaymentMethodJson(Account account, PaymentMethod in) {
+
+    public static PaymentMethodJson toPaymentMethodJson(final Account account, final PaymentMethod in) {
 
         final boolean isDefault = account.getPaymentMethodId() != null && account.getPaymentMethodId().equals(in.getId());
         PaymentMethodPluginDetailJson detail = null;
         if (in.getPluginDetail() != null) {
             List<PaymentMethodProperties> properties = null;
             if (in.getPluginDetail().getProperties() != null) {
-                properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>(Collections2.transform(in.getPluginDetail().getProperties(), new Function<PaymentMethodKVInfo,PaymentMethodProperties>() {
+                properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>(Collections2.transform(in.getPluginDetail().getProperties(), new Function<PaymentMethodKVInfo, PaymentMethodProperties>() {
                     @Override
-                    public PaymentMethodProperties apply(PaymentMethodKVInfo input) {
+                    public PaymentMethodProperties apply(final PaymentMethodKVInfo input) {
                         return new PaymentMethodProperties(input.getKey(), input.getValue().toString(), input.getIsUpdatable());
                     }
                 }));
@@ -76,18 +76,22 @@ public class PaymentMethodJson {
             public Boolean isActive() {
                 return true;
             }
+
             @Override
             public String getPluginName() {
                 return pluginName;
             }
+
             @Override
             public UUID getId() {
                 return paymentMethodId != null ? UUID.fromString(paymentMethodId) : null;
             }
+
             @Override
             public UUID getAccountId() {
                 return accountId != null ? UUID.fromString(accountId) : null;
             }
+
             @Override
             public PaymentMethodPlugin getPluginDetail() {
                 return new PaymentMethodPlugin() {
@@ -96,20 +100,23 @@ public class PaymentMethodJson {
                         // N/A
                         return false;
                     }
+
                     @Override
-                    public String getValueString(String key) {
+                    public String getValueString(final String key) {
                         // N/A
                         return null;
                     }
+
                     @Override
                     public String getExternalPaymentMethodId() {
                         return pluginInfo.getExternalPaymentId();
                     }
+
                     @Override
                     public List<PaymentMethodKVInfo> getProperties() {
                         if (pluginInfo.getProperties() != null) {
-                            List<PaymentMethodKVInfo> result = new LinkedList<PaymentMethodPlugin.PaymentMethodKVInfo>();
-                            for (PaymentMethodProperties cur : pluginInfo.getProperties()) {
+                            final List<PaymentMethodKVInfo> result = new LinkedList<PaymentMethodPlugin.PaymentMethodKVInfo>();
+                            for (final PaymentMethodProperties cur : pluginInfo.getProperties()) {
                                 result.add(new PaymentMethodKVInfo(cur.getKey(), cur.getValue(), cur.isUpdatable));
                             }
                             return result;
@@ -153,8 +160,8 @@ public class PaymentMethodJson {
 
 
         @JsonCreator
-        public PaymentMethodPluginDetailJson(@JsonProperty("externalPaymentId") String externalPaymentId,
-                @JsonProperty("properties") List<PaymentMethodProperties> properties) {
+        public PaymentMethodPluginDetailJson(@JsonProperty("externalPaymentId") final String externalPaymentId,
+                                             @JsonProperty("properties") final List<PaymentMethodProperties> properties) {
             super();
             this.externalPaymentId = externalPaymentId;
             this.properties = properties;
@@ -172,16 +179,16 @@ public class PaymentMethodJson {
             return properties;
         }
     }
-    
-    public final static class PaymentMethodProperties {
+
+    public static final class PaymentMethodProperties {
         private final String key;
         private final String value;
         private final Boolean isUpdatable;
 
         @JsonCreator
-        public PaymentMethodProperties(@JsonProperty("key") String key,
-                @JsonProperty("value") String value,
-                @JsonProperty("isUpdatable") Boolean isUpdatable) {
+        public PaymentMethodProperties(@JsonProperty("key") final String key,
+                                       @JsonProperty("value") final String value,
+                                       @JsonProperty("isUpdatable") final Boolean isUpdatable) {
             super();
             this.key = key;
             this.value = value;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
index 2d13cf6..3c7b2f6 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
@@ -22,12 +22,11 @@ import org.joda.time.DateTime;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
 import com.ning.billing.entitlement.api.user.Subscription;
 
 public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
     private final DateTime startDate;
-    
+
     private final String bundleId;
 
     private final String productName;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonSimple.java
index dd6427f..28d5365 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonSimple.java
@@ -19,7 +19,6 @@ import javax.annotation.Nullable;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
 
 public class SubscriptionJsonSimple {
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonWithEvents.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonWithEvents.java
index 4844344..73508ad 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonWithEvents.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonWithEvents.java
@@ -24,7 +24,6 @@ import org.joda.time.DateTime;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.ExistingEvent;
@@ -53,13 +52,13 @@ public class SubscriptionJsonWithEvents extends SubscriptionJsonSimple {
 
         @JsonCreator
         public SubscriptionReadEventJson(@JsonProperty("eventId") final String eventId,
-                @JsonProperty("billingPeriod") final String billingPeriod,
-                @JsonProperty("requestedDt") final DateTime requestedDate,
-                @JsonProperty("effectiveDt") final DateTime effectiveDate,
-                @JsonProperty("product") final String product,
-                @JsonProperty("priceList") final String priceList,
-                @JsonProperty("eventType") final String eventType,
-                @JsonProperty("phase") final String phase) {
+                                         @JsonProperty("billingPeriod") final String billingPeriod,
+                                         @JsonProperty("requestedDt") final DateTime requestedDate,
+                                         @JsonProperty("effectiveDt") final DateTime effectiveDate,
+                                         @JsonProperty("product") final String product,
+                                         @JsonProperty("priceList") final String priceList,
+                                         @JsonProperty("eventType") final String eventType,
+                                         @JsonProperty("phase") final String phase) {
             super(billingPeriod, requestedDate, product, priceList, eventType, phase);
             this.eventId = eventId;
             this.effectiveDate = effectiveDate;
@@ -76,14 +75,14 @@ public class SubscriptionJsonWithEvents extends SubscriptionJsonSimple {
         @Override
         public String toString() {
             return "SubscriptionReadEventJson [eventId=" + eventId
-            + ", effectiveDate=" + effectiveDate
-            + ", getBillingPeriod()=" + getBillingPeriod()
-            + ", getRequestedDate()=" + getRequestedDate()
-            + ", getProduct()=" + getProduct() + ", getPriceList()="
-            + getPriceList() + ", getEventType()=" + getEventType()
-            + ", getPhase()=" + getPhase() + ", getClass()="
-            + getClass() + ", hashCode()=" + hashCode()
-            + ", toString()=" + super.toString() + "]";
+                    + ", effectiveDate=" + effectiveDate
+                    + ", getBillingPeriod()=" + getBillingPeriod()
+                    + ", getRequestedDate()=" + getRequestedDate()
+                    + ", getProduct()=" + getProduct() + ", getPriceList()="
+                    + getPriceList() + ", getEventType()=" + getEventType()
+                    + ", getPhase()=" + getPhase() + ", getClass()="
+                    + getClass() + ", hashCode()=" + hashCode()
+                    + ", toString()=" + super.toString() + "]";
         }
 
         @Override
@@ -118,13 +117,13 @@ public class SubscriptionJsonWithEvents extends SubscriptionJsonSimple {
     public static class SubscriptionDeletedEventJson extends SubscriptionReadEventJson {
         @JsonCreator
         public SubscriptionDeletedEventJson(@JsonProperty("event_id") final String eventId,
-                @JsonProperty("billing_period") final String billingPeriod,
-                @JsonProperty("requested_date") final DateTime requestedDate,
-                @JsonProperty("effective_date") final DateTime effectiveDate,
-                @JsonProperty("product") final String product,
-                @JsonProperty("price_list") final String priceList,
-                @JsonProperty("event_type") final String eventType,
-                @JsonProperty("phase") final String phase) {
+                                            @JsonProperty("billing_period") final String billingPeriod,
+                                            @JsonProperty("requested_date") final DateTime requestedDate,
+                                            @JsonProperty("effective_date") final DateTime effectiveDate,
+                                            @JsonProperty("product") final String product,
+                                            @JsonProperty("price_list") final String priceList,
+                                            @JsonProperty("event_type") final String eventType,
+                                            @JsonProperty("phase") final String phase) {
             super(eventId, billingPeriod, requestedDate, effectiveDate, product, priceList, eventType, phase);
         }
     }
@@ -132,24 +131,24 @@ public class SubscriptionJsonWithEvents extends SubscriptionJsonSimple {
     public static class SubscriptionNewEventJson extends SubscriptionBaseEventJson {
         @JsonCreator
         public SubscriptionNewEventJson(@JsonProperty("billing_period") final String billingPeriod,
-                @JsonProperty("requested_date") final DateTime requestedDate,
-                @JsonProperty("product") final String product,
-                @JsonProperty("price_list") final String priceList,
-                @JsonProperty("event_type") final String eventType,
-                @JsonProperty("phase") final String phase) {
+                                        @JsonProperty("requested_date") final DateTime requestedDate,
+                                        @JsonProperty("product") final String product,
+                                        @JsonProperty("price_list") final String priceList,
+                                        @JsonProperty("event_type") final String eventType,
+                                        @JsonProperty("phase") final String phase) {
             super(billingPeriod, requestedDate, product, priceList, eventType, phase);
         }
 
         @Override
         public String toString() {
             return "SubscriptionNewEventJson [getBillingPeriod()="
-            + getBillingPeriod() + ", getRequestedDate()="
-            + getRequestedDate() + ", getProduct()=" + getProduct()
-            + ", getPriceList()=" + getPriceList()
-            + ", getEventType()=" + getEventType() + ", getPhase()="
-            + getPhase() + ", getClass()=" + getClass()
-            + ", hashCode()=" + hashCode() + ", toString()="
-            + super.toString() + "]";
+                    + getBillingPeriod() + ", getRequestedDate()="
+                    + getRequestedDate() + ", getProduct()=" + getProduct()
+                    + ", getPriceList()=" + getPriceList()
+                    + ", getEventType()=" + getEventType() + ", getPhase()="
+                    + getPhase() + ", getClass()=" + getClass()
+                    + ", hashCode()=" + hashCode() + ", toString()="
+                    + super.toString() + "]";
         }
     }
 
@@ -178,11 +177,11 @@ public class SubscriptionJsonWithEvents extends SubscriptionJsonSimple {
 
         @JsonCreator
         public SubscriptionBaseEventJson(@JsonProperty("billing_period") final String billingPeriod,
-                @JsonProperty("requested_date") final DateTime requestedDate,
-                @JsonProperty("product") final String product,
-                @JsonProperty("price_list") final String priceList,
-                @JsonProperty("event_type") final String eventType,
-                @JsonProperty("phase") final String phase) {
+                                         @JsonProperty("requested_date") final DateTime requestedDate,
+                                         @JsonProperty("product") final String product,
+                                         @JsonProperty("price_list") final String priceList,
+                                         @JsonProperty("event_type") final String eventType,
+                                         @JsonProperty("phase") final String phase) {
             super();
             this.billingPeriod = billingPeriod;
             this.requestedDate = DefaultClock.toUTCDateTime(requestedDate);
@@ -263,9 +262,9 @@ public class SubscriptionJsonWithEvents extends SubscriptionJsonSimple {
 
     @JsonCreator
     public SubscriptionJsonWithEvents(@JsonProperty("subscription_id") @Nullable final String subscriptionId,
-            @JsonProperty("events") @Nullable final List<SubscriptionReadEventJson> events,
-            @JsonProperty("new_events") @Nullable final List<SubscriptionNewEventJson> newEvents,
-            @JsonProperty("deleted_events") @Nullable final List<SubscriptionDeletedEventJson> deletedEvents) {
+                                      @JsonProperty("events") @Nullable final List<SubscriptionReadEventJson> events,
+                                      @JsonProperty("new_events") @Nullable final List<SubscriptionNewEventJson> newEvents,
+                                      @JsonProperty("deleted_events") @Nullable final List<SubscriptionDeletedEventJson> deletedEvents) {
         super(subscriptionId);
         this.events = events;
         this.deletedEvents = deletedEvents;
@@ -277,9 +276,9 @@ public class SubscriptionJsonWithEvents extends SubscriptionJsonSimple {
     }
 
     public SubscriptionJsonWithEvents(final Subscription data,
-            @Nullable final List<SubscriptionReadEventJson> events,
-            @Nullable final List<SubscriptionNewEventJson> newEvents,
-            @Nullable final List<SubscriptionDeletedEventJson> deletedEvents) {
+                                      @Nullable final List<SubscriptionReadEventJson> events,
+                                      @Nullable final List<SubscriptionNewEventJson> newEvents,
+                                      @Nullable final List<SubscriptionDeletedEventJson> deletedEvents) {
         this(data.getId().toString(), events, newEvents, deletedEvents);
     }
 
@@ -289,7 +288,7 @@ public class SubscriptionJsonWithEvents extends SubscriptionJsonSimple {
         for (final ExistingEvent cur : input.getExistingEvents()) {
             final PlanPhaseSpecifier spec = cur.getPlanPhaseSpecifier();
             this.events.add(new SubscriptionReadEventJson(cur.getEventId().toString(), spec.getBillingPeriod().toString(), cur.getRequestedDate(), cur.getEffectiveDate(),
-                    spec.getProductName(), spec.getPriceListName(), cur.getSubscriptionTransitionType().toString(), spec.getPhaseType().toString()));
+                                                          spec.getProductName(), spec.getPriceListName(), cur.getSubscriptionTransitionType().toString(), spec.getPhaseType().toString()));
         }
         this.newEvents = null;
         this.deletedEvents = null;
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 449b4d0..c0f8e1c 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
@@ -50,7 +50,9 @@ import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountData;
+import com.ning.billing.account.api.AccountEmail;
 import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.account.api.MutableAccountData;
 import com.ning.billing.entitlement.api.timeline.BundleTimeline;
 import com.ning.billing.entitlement.api.timeline.EntitlementRepairException;
 import com.ning.billing.entitlement.api.timeline.EntitlementTimelineApi;
@@ -58,10 +60,12 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceUserApi;
+import com.ning.billing.jaxrs.json.AccountEmailJson;
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.AccountTimelineJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
+import com.ning.billing.jaxrs.json.InvoiceEmailJson;
 import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.json.PaymentMethodJson;
 import com.ning.billing.jaxrs.util.Context;
@@ -78,11 +82,10 @@ import com.ning.billing.util.dao.ObjectType;
 @Singleton
 @Path(JaxrsResource.ACCOUNTS_PATH)
 public class AccountResource extends JaxRsResourceBase {
-
     private static final Logger log = LoggerFactory.getLogger(AccountResource.class);
     private static final String ID_PARAM_NAME = "accountId";
-    private static final String CUSTOM_FIELD_URI = JaxrsResource.CUSTOM_FIELDS;
-    private static final String TAG_URI = JaxrsResource.TAGS;
+    private static final String CUSTOM_FIELD_URI = JaxrsResource.CUSTOM_FIELDS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
+    private static final String TAG_URI = JaxrsResource.TAGS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
 
     private final AccountUserApi accountApi;
     private final EntitlementUserApi entitlementApi;
@@ -94,18 +97,18 @@ public class AccountResource extends JaxRsResourceBase {
 
     @Inject
     public AccountResource(final JaxrsUriBuilder uriBuilder,
-            final AccountUserApi accountApi,
-            final EntitlementUserApi entitlementApi,
-            final InvoiceUserApi invoiceApi,
-            final PaymentApi paymentApi,
-            final EntitlementTimelineApi timelineApi,
-            final CustomFieldUserApi customFieldUserApi,
-            final TagUserApi tagUserApi,
-            final TagHelper tagHelper,
-            final Context context) {
+                           final AccountUserApi accountApi,
+                           final EntitlementUserApi entitlementApi,
+                           final InvoiceUserApi invoiceApi,
+                           final PaymentApi paymentApi,
+                           final EntitlementTimelineApi timelineApi,
+                           final CustomFieldUserApi customFieldUserApi,
+                           final TagUserApi tagUserApi,
+                           final TagHelper tagHelper,
+                           final Context context) {
         super(uriBuilder, tagUserApi, tagHelper, customFieldUserApi);
         this.uriBuilder = uriBuilder;
-    	this.accountApi = accountApi;
+        this.accountApi = accountApi;
         this.entitlementApi = entitlementApi;
         this.invoiceApi = invoiceApi;
         this.paymentApi = paymentApi;
@@ -116,11 +119,11 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getAccount(@PathParam("accountId") String accountId) {
+    public Response getAccount(@PathParam("accountId") final String accountId) {
         try {
-            Account account = accountApi.getAccountById(UUID.fromString(accountId));
+            final Account account = accountApi.getAccountById(UUID.fromString(accountId));
 
-            AccountJson json = new AccountJson(account);
+            final AccountJson json = new AccountJson(account);
             return Response.status(Status.OK).entity(json).build();
         } catch (AccountApiException e) {
             return Response.status(Status.NO_CONTENT).build();
@@ -131,15 +134,15 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + BUNDLES)
     @Produces(APPLICATION_JSON)
-    public Response getAccountBundles(@PathParam("accountId") String accountId) {
+    public Response getAccountBundles(@PathParam("accountId") final String accountId) {
         try {
-            UUID uuid = UUID.fromString(accountId);
+            final UUID uuid = UUID.fromString(accountId);
             accountApi.getAccountById(uuid);
 
-            List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(uuid);
-            Collection<BundleJsonNoSubscriptions> result = Collections2.transform(bundles, new Function<SubscriptionBundle, BundleJsonNoSubscriptions>() {
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(uuid);
+            final Collection<BundleJsonNoSubscriptions> result = Collections2.transform(bundles, new Function<SubscriptionBundle, BundleJsonNoSubscriptions>() {
                 @Override
-                public BundleJsonNoSubscriptions apply(SubscriptionBundle input) {
+                public BundleJsonNoSubscriptions apply(final SubscriptionBundle input) {
                     return new BundleJsonNoSubscriptions(input);
                 }
             });
@@ -149,10 +152,9 @@ public class AccountResource extends JaxRsResourceBase {
         }
     }
 
-
     @GET
     @Produces(APPLICATION_JSON)
-    public Response getAccountByKey(@QueryParam(QUERY_EXTERNAL_KEY) String externalKey) {
+    public Response getAccountByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey) {
         try {
             Account account = null;
             if (externalKey != null) {
@@ -161,24 +163,23 @@ public class AccountResource extends JaxRsResourceBase {
             if (account == null) {
                 return Response.status(Status.NO_CONTENT).build();
             }
-            AccountJson json = new AccountJson(account);
+            final AccountJson json = new AccountJson(account);
             return Response.status(Status.OK).entity(json).build();
         } catch (AccountApiException e) {
             return Response.status(Status.NO_CONTENT).build();
         }
     }
 
-
     @POST
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createAccount(final AccountJson json,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                  @HeaderParam(HDR_REASON) final String reason,
+                                  @HeaderParam(HDR_COMMENT) final String comment) {
 
         try {
-            AccountData data = json.toAccountData();
+            final AccountData data = json.toAccountData();
             final Account account = accountApi.createAccount(data, context.createContext(createdBy, reason, comment));
             return uriBuilder.buildResponse(AccountResource.class, "getAccount", account.getId());
         } catch (AccountApiException e) {
@@ -195,22 +196,22 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @Path("/{accountId:" + UUID_PATTERN + "}")
     public Response updateAccount(final AccountJson json,
-            @PathParam("accountId") final String accountId,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                  @PathParam("accountId") final String accountId,
+                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                  @HeaderParam(HDR_REASON) final String reason,
+                                  @HeaderParam(HDR_COMMENT) final String comment) {
         try {
-            AccountData data = json.toAccountData();
-            UUID uuid = UUID.fromString(accountId);
+            final AccountData data = json.toAccountData();
+            final UUID uuid = UUID.fromString(accountId);
             accountApi.updateAccount(uuid, data, context.createContext(createdBy, reason, comment));
             return getAccount(accountId);
         } catch (AccountApiException e) {
-        	if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
+            if (e.getCode() == ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode()) {
                 return Response.status(Status.NO_CONTENT).build();
-        	} else {
-        		log.info(String.format("Failed to update account %s with %s", accountId, json), e);
+            } else {
+                log.info(String.format("Failed to update account %s with %s", accountId, json), e);
                 return Response.status(Status.BAD_REQUEST).build();
-        	}
+            }
         } catch (IllegalArgumentException e) {
             return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
         }
@@ -220,7 +221,7 @@ public class AccountResource extends JaxRsResourceBase {
     @DELETE
     @Path("/{accountId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response cancelAccount(@PathParam("accountId") String accountId) {
+    public Response cancelAccount(@PathParam("accountId") final String accountId) {
         /*
         try {
             accountApi.cancelAccount(accountId);
@@ -236,20 +237,20 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + TIMELINE)
     @Produces(APPLICATION_JSON)
-    public Response getAccountTimeline(@PathParam("accountId") String accountId) {
+    public Response getAccountTimeline(@PathParam("accountId") final String accountId) {
         try {
 
-            Account account = accountApi.getAccountById(UUID.fromString(accountId));
+            final Account account = accountApi.getAccountById(UUID.fromString(accountId));
 
-            List<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
-            List<Payment> payments = paymentApi.getAccountPayments(UUID.fromString(accountId));
+            final List<Invoice> invoices = invoiceApi.getInvoicesByAccount(account.getId());
+            final List<Payment> payments = paymentApi.getAccountPayments(UUID.fromString(accountId));
 
-            List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(account.getId());
-            List<BundleTimeline> bundlesTimeline = new LinkedList<BundleTimeline>();
-            for (SubscriptionBundle cur : bundles) {
+            final List<SubscriptionBundle> bundles = entitlementApi.getBundlesForAccount(account.getId());
+            final List<BundleTimeline> bundlesTimeline = new LinkedList<BundleTimeline>();
+            for (final SubscriptionBundle cur : bundles) {
                 bundlesTimeline.add(timelineApi.getBundleRepair(cur.getId()));
             }
-            AccountTimelineJson json = new AccountTimelineJson(account, invoices, payments, bundlesTimeline);
+            final AccountTimelineJson json = new AccountTimelineJson(account, invoices, payments, bundlesTimeline);
             return Response.status(Status.OK).entity(json).build();
         } catch (AccountApiException e) {
             return Response.status(Status.NO_CONTENT).build();
@@ -262,19 +263,61 @@ public class AccountResource extends JaxRsResourceBase {
         }
     }
 
+    /*
+     * ************************** EMAIL NOTIFICATIONS FOR INVOICES ********************************
+     */
+
+    @GET
+    @Path("/{accountId:" + UUID_PATTERN + "}/" + EMAIL_NOTIFICATIONS)
+    @Produces(APPLICATION_JSON)
+    public Response getEmailNotificationsForAccount(@PathParam("accountId") final String accountId) {
+        try {
+            final Account account = accountApi.getAccountById(UUID.fromString(accountId));
+            final InvoiceEmailJson invoiceEmailJson = new InvoiceEmailJson(accountId, account.isNotifiedForInvoices());
 
-    /*****************************  PAYMENTS *********************************/
+            return Response.status(Status.OK).entity(invoiceEmailJson).build();
+        } catch (AccountApiException e) {
+            return Response.status(Status.NOT_FOUND).build();
+        }
+    }
+
+    @PUT
+    @Path("/{accountId:" + UUID_PATTERN + "}/" + EMAIL_NOTIFICATIONS)
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    public Response getEmailNotificationsForAccount(final InvoiceEmailJson json,
+                                                    @PathParam("accountId") final String accountIdString,
+                                                    @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                                    @HeaderParam(HDR_REASON) final String reason,
+                                                    @HeaderParam(HDR_COMMENT) final String comment) {
+        try {
+            final UUID accountId = UUID.fromString(accountIdString);
+            final Account account = accountApi.getAccountById(accountId);
+
+            final MutableAccountData mutableAccountData = account.toMutableAccountData();
+            mutableAccountData.setIsNotifiedForInvoices(json.isNotifiedForInvoices());
+            accountApi.updateAccount(accountId, mutableAccountData, context.createContext(createdBy, reason, comment));
+
+            return Response.status(Status.OK).build();
+        } catch (AccountApiException e) {
+            return Response.status(Status.NOT_FOUND).build();
+        }
+    }
+
+    /*
+     * ************************** PAYMENTS ********************************
+     */
 
     @GET
     @Path("/{accountId:\\w+-\\w+-\\w+-\\w+-\\w+}/" + PAYMENTS)
     @Produces(APPLICATION_JSON)
-    public Response getPayments(@PathParam("accountId") String accountId,
-            @QueryParam(QUERY_PAYMENT_LAST4_CC) final String last4CC,
-            @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) {
+    public Response getPayments(@PathParam("accountId") final String accountId,
+                                @QueryParam(QUERY_PAYMENT_LAST4_CC) final String last4CC,
+                                @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) {
         try {
-             List<Payment> payments = paymentApi.getAccountPayments(UUID.fromString(accountId));
-            List<PaymentJsonSimple> result =  new ArrayList<PaymentJsonSimple>(payments.size());
-            for (Payment cur : payments) {
+            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));
             }
             return Response.status(Status.OK).entity(result).build();
@@ -288,18 +331,16 @@ public class AccountResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createPaymentMethod(final PaymentMethodJson json,
-            @QueryParam(QUERY_PAYMENT_METHOD_IS_DEFAULT) @DefaultValue("false") final Boolean isDefault,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment,
-            @javax.ws.rs.core.Context UriInfo uriInfo) {
-
+                                        @QueryParam(QUERY_PAYMENT_METHOD_IS_DEFAULT) @DefaultValue("false") final Boolean isDefault,
+                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                        @HeaderParam(HDR_REASON) final String reason,
+                                        @HeaderParam(HDR_COMMENT) final String comment,
+                                        @javax.ws.rs.core.Context final UriInfo uriInfo) {
         try {
+            final PaymentMethod data = json.toPaymentMethod();
+            final Account account = accountApi.getAccountById(data.getAccountId());
 
-            PaymentMethod data = json.toPaymentMethod();
-            Account account = accountApi.getAccountById(data.getAccountId());
-
-            UUID paymentMethodId = paymentApi.addPaymentMethod(data.getPluginName(), account, isDefault, data.getPluginDetail(), context.createContext(createdBy, reason, comment));
+            final UUID paymentMethodId = paymentApi.addPaymentMethod(data.getPluginName(), account, isDefault, data.getPluginDetail(), context.createContext(createdBy, reason, comment));
             return uriBuilder.buildResponse(PaymentMethodResource.class, "getPaymentMethod", paymentMethodId, uriInfo.getBaseUri().toString());
         } catch (AccountApiException e) {
             final String error = String.format("Failed to create account %s", json);
@@ -317,21 +358,22 @@ public class AccountResource extends JaxRsResourceBase {
     @GET
     @Path("/{accountId:" + UUID_PATTERN + "}/" + PAYMENT_METHODS)
     @Produces(APPLICATION_JSON)
-    public Response getPaymentMethods(@PathParam("accountId") String accountId,
-            @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
-            @QueryParam(QUERY_PAYMENT_LAST4_CC) final String last4CC,
-            @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) {
+    public Response getPaymentMethods(@PathParam("accountId") final String accountId,
+                                      @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
+                                      @QueryParam(QUERY_PAYMENT_LAST4_CC) final String last4CC,
+                                      @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) {
 
         try {
             final Account account = accountApi.getAccountById(UUID.fromString(accountId));
-            List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, withPluginInfo);
-            List<PaymentMethodJson> json = new ArrayList<PaymentMethodJson>(Collections2.transform(methods, new Function<PaymentMethod, PaymentMethodJson>() {
+            final List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, withPluginInfo);
+            final List<PaymentMethodJson> json = new ArrayList<PaymentMethodJson>(Collections2.transform(methods, new Function<PaymentMethod, PaymentMethodJson>() {
                 @Override
-                public PaymentMethodJson apply(PaymentMethod input) {
+                public PaymentMethodJson apply(final PaymentMethod input) {
                     return PaymentMethodJson.toPaymentMethodJson(account, input);
                 }
             }));
             return Response.status(Status.OK).entity(json).build();
+
         } catch (PaymentApiException e) {
             return Response.status(Status.NOT_FOUND).build();
         } catch (AccountApiException e) {
@@ -344,10 +386,10 @@ public class AccountResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @Path("/{accountId:" + UUID_PATTERN + "}/" + PAYMENT_METHODS + "/{paymentMethodId:" + UUID_PATTERN + "}/" + PAYMENT_METHODS_DEFAULT_PATH_POSTFIX)
     public Response setDefaultPaymentMethod(@PathParam("accountId") final String accountId,
-            @PathParam("paymentMethodId") final String paymentMethodId,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                            @PathParam("paymentMethodId") final String paymentMethodId,
+                                            @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                            @HeaderParam(HDR_REASON) final String reason,
+                                            @HeaderParam(HDR_COMMENT) final String comment) {
         try {
             final Account account = accountApi.getAccountById(UUID.fromString(accountId));
             paymentApi.setDefaultPaymentMethod(account, UUID.fromString(paymentMethodId), context.createContext(createdBy, reason, comment));
@@ -361,7 +403,10 @@ public class AccountResource extends JaxRsResourceBase {
         }
     }
 
-    /**************************** TAGS AND CUSTOM FIELDS ******************************/
+    /*
+     * *************************      CUSTOM FIELDS     *****************************
+     */
+
     @GET
     @Path(CUSTOM_FIELD_URI)
     @Produces(APPLICATION_JSON)
@@ -370,64 +415,134 @@ public class AccountResource extends JaxRsResourceBase {
     }
 
     @POST
-    @Path("/{accountId:" + UUID_PATTERN + "}/" + CUSTOM_FIELD_URI)
+    @Path(CUSTOM_FIELD_URI)
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
-            final List<CustomFieldJson> customFields,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                       final List<CustomFieldJson> customFields,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment) {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment));
     }
 
     @DELETE
-    @Path("/{accountId:" + UUID_PATTERN + "}/" + CUSTOM_FIELD_URI)
+    @Path(CUSTOM_FIELD_URI)
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment) {
         return super.deleteCustomFields(UUID.fromString(id), customFieldList,
-                context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment));
     }
 
+    /*
+     * *************************     TAGS     *****************************
+     */
+
     @GET
-    @Path("/{accountId:" + UUID_PATTERN + "}/" + TAG_URI)
+    @Path(TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) String id) {
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) {
         return super.getTags(UUID.fromString(id));
     }
 
     @POST
-    @Path("/{accountId:" + UUID_PATTERN + "}/" + TAG_URI)
+    @Path(TAG_URI)
+    @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_TAGS) final String tagList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                               @QueryParam(QUERY_TAGS) final String tagList,
+                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                               @HeaderParam(HDR_REASON) final String reason,
+                               @HeaderParam(HDR_COMMENT) final String comment) {
         return super.createTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
     }
 
     @DELETE
-    @Path("/{accountId:" + UUID_PATTERN + "}/" + TAG_URI)
+    @Path(TAG_URI)
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_TAGS) final String tagList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                               @QueryParam(QUERY_TAGS) final String tagList,
+                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                               @HeaderParam(HDR_REASON) final String reason,
+                               @HeaderParam(HDR_COMMENT) final String comment) {
 
         return super.deleteTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
     }
 
+    /*
+     * *************************     EMAILS     *****************************
+     */
+
+    @GET
+    @Path("/{accountId:" + UUID_PATTERN + "}/" + EMAILS)
+    @Produces(APPLICATION_JSON)
+    public Response getEmails(@PathParam(ID_PARAM_NAME) final String id) {
+        final UUID accountId = UUID.fromString(id);
+        final List<AccountEmail> emails = accountApi.getEmails(accountId);
+
+        final List<AccountEmailJson> emailsJson = new ArrayList<AccountEmailJson>();
+        for (final AccountEmail email : emails) {
+            emailsJson.add(new AccountEmailJson(email.getAccountId().toString(), email.getEmail()));
+        }
+        return Response.status(Response.Status.OK).entity(emailsJson).build();
+    }
+
+    @POST
+    @Path("/{accountId:" + UUID_PATTERN + "}/" + EMAILS)
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    public Response addEmail(final AccountEmailJson json,
+                             @PathParam(ID_PARAM_NAME) final String id,
+                             @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                             @HeaderParam(HDR_REASON) final String reason,
+                             @HeaderParam(HDR_COMMENT) final String comment) {
+        try {
+            final UUID accountId = UUID.fromString(id);
+
+            // Make sure the account exist or we will confuse the history and auditing code
+            if (accountApi.getAccountById(accountId) == null) {
+                return Response.status(Response.Status.BAD_REQUEST).entity("Account id " + accountId + " does not exist").build();
+            }
+
+            accountApi.addEmail(accountId, json.toAccountEmail(), context.createContext(createdBy, reason, comment));
+
+            return uriBuilder.buildResponse(AccountResource.class, "getEmails", json.getAccountId());
+        } catch (RuntimeException e) {
+            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
+        } catch (AccountApiException e) {
+            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
+        }
+    }
+
+    @DELETE
+    @Path("/{accountId:" + UUID_PATTERN + "}/" + EMAILS + "/{email}")
+    @Produces(APPLICATION_JSON)
+    public Response removeEmail(@PathParam(ID_PARAM_NAME) final String id,
+                                @PathParam("email") final String email,
+                                @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                @HeaderParam(HDR_REASON) final String reason,
+                                @HeaderParam(HDR_COMMENT) final String comment) {
+        try {
+            final UUID accountId = UUID.fromString(id);
+            final AccountEmailJson accountEmailJson = new AccountEmailJson(id, email);
+            final AccountEmail accountEmail = accountEmailJson.toAccountEmail();
+            accountApi.removeEmail(accountId, accountEmail, context.createContext(createdBy, reason, comment));
+
+            return Response.status(Response.Status.OK).build();
+        } catch (RuntimeException e) {
+            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
+        }
+    }
+
     @Override
     protected ObjectType getObjectType() {
         return ObjectType.ACCOUNT;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
index 42edae1..5e8877c 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
@@ -16,12 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.UUID;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -33,12 +27,10 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
 
-import com.ning.billing.jaxrs.json.CustomFieldJson;
-import com.ning.billing.jaxrs.util.TagHelper;
-import com.ning.billing.util.api.CustomFieldUserApi;
-import com.ning.billing.util.api.TagUserApi;
-import com.ning.billing.util.dao.ObjectType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -51,9 +43,16 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
+import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.jaxrs.util.TagHelper;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagUserApi;
+import com.ning.billing.util.dao.ObjectType;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.BUNDLES_PATH)
 public class BundleResource extends JaxRsResourceBase {
@@ -69,8 +68,8 @@ public class BundleResource extends JaxRsResourceBase {
 
     @Inject
     public BundleResource(final JaxrsUriBuilder uriBuilder, final EntitlementUserApi entitlementApi,
-                          TagUserApi tagUserApi, TagHelper tagHelper, CustomFieldUserApi customFieldUserApi,
-                          Context context) {
+                          final TagUserApi tagUserApi, final TagHelper tagHelper, final CustomFieldUserApi customFieldUserApi,
+                          final Context context) {
         super(uriBuilder, tagUserApi, tagHelper, customFieldUserApi);
         this.uriBuilder = uriBuilder;
         this.entitlementApi = entitlementApi;
@@ -78,12 +77,12 @@ public class BundleResource extends JaxRsResourceBase {
     }
 
     @GET
-    @Path("/{bundleId:"  + UUID_PATTERN + "}")
+    @Path("/{bundleId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
     public Response getBundle(@PathParam("bundleId") final String bundleId) throws EntitlementUserApiException {
         try {
-            SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(bundleId));
-            BundleJsonNoSubscriptions json = new BundleJsonNoSubscriptions(bundle);
+            final SubscriptionBundle bundle = entitlementApi.getBundleFromId(UUID.fromString(bundleId));
+            final BundleJsonNoSubscriptions json = new BundleJsonNoSubscriptions(bundle);
             return Response.status(Status.OK).entity(json).build();
         } catch (EntitlementUserApiException e) {
             if (e.getCode() == ErrorCode.ENT_GET_INVALID_BUNDLE_ID.getCode()) {
@@ -99,8 +98,8 @@ public class BundleResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     public Response getBundleByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey) throws EntitlementUserApiException {
         try {
-            SubscriptionBundle bundle = entitlementApi.getBundleForKey(externalKey);
-            BundleJsonNoSubscriptions json = new BundleJsonNoSubscriptions(bundle);
+            final SubscriptionBundle bundle = entitlementApi.getBundleForKey(externalKey);
+            final BundleJsonNoSubscriptions json = new BundleJsonNoSubscriptions(bundle);
             return Response.status(Status.OK).entity(json).build();
         } catch (EntitlementUserApiException e) {
             if (e.getCode() == ErrorCode.ENT_GET_INVALID_BUNDLE_KEY.getCode()) {
@@ -116,13 +115,13 @@ public class BundleResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createBundle(final BundleJsonNoSubscriptions json,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                 @HeaderParam(HDR_REASON) final String reason,
+                                 @HeaderParam(HDR_COMMENT) final String comment) {
         try {
-            UUID accountId = UUID.fromString(json.getAccountId());
+            final UUID accountId = UUID.fromString(json.getAccountId());
             final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(accountId, json.getExternalKey(),
-                    context.createContext(createdBy, reason, comment));
+                                                                                    context.createContext(createdBy, reason, comment));
             return uriBuilder.buildResponse(BundleResource.class, "getBundle", bundle.getId());
         } catch (EntitlementUserApiException e) {
             log.info(String.format("Failed to create bundle %s", json), e);
@@ -137,18 +136,18 @@ public class BundleResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     public Response getBundleSubscriptions(@PathParam("bundleId") final String bundleId) throws EntitlementUserApiException {
         try {
-            UUID uuid = UUID.fromString(bundleId);
-            SubscriptionBundle bundle = entitlementApi.getBundleFromId(uuid);
+            final UUID uuid = UUID.fromString(bundleId);
+            final SubscriptionBundle bundle = entitlementApi.getBundleFromId(uuid);
             if (bundle == null) {
                 return Response.status(Status.NO_CONTENT).build();
             }
-            List<Subscription> bundles = entitlementApi.getSubscriptionsForBundle(uuid);
-            Collection<SubscriptionJsonNoEvents> result =  Collections2.transform(bundles, new Function<Subscription, SubscriptionJsonNoEvents>() {
+            final List<Subscription> bundles = entitlementApi.getSubscriptionsForBundle(uuid);
+            final Collection<SubscriptionJsonNoEvents> result = Collections2.transform(bundles, new Function<Subscription, SubscriptionJsonNoEvents>() {
                 @Override
-                public SubscriptionJsonNoEvents apply(Subscription input) {
+                public SubscriptionJsonNoEvents apply(final Subscription input) {
                     return new SubscriptionJsonNoEvents(input);
                 }
-             });
+            });
             return Response.status(Status.OK).entity(result).build();
         } catch (EntitlementUserApiException e) {
             if (e.getCode() == ErrorCode.ENT_GET_INVALID_BUNDLE_ID.getCode()) {
@@ -172,12 +171,12 @@ public class BundleResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
-            final List<CustomFieldJson> customFields,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                       final List<CustomFieldJson> customFields,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment) {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment));
     }
 
     @DELETE
@@ -185,18 +184,18 @@ public class BundleResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment) {
         return super.deleteCustomFields(UUID.fromString(id), customFieldList,
-                context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment));
     }
 
     @GET
     @Path("/{bundleId:" + UUID_PATTERN + "}/" + TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) String id) {
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) {
         return super.getTags(UUID.fromString(id));
     }
 
@@ -205,10 +204,10 @@ public class BundleResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_TAGS) final String tagList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                               @QueryParam(QUERY_TAGS) final String tagList,
+                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                               @HeaderParam(HDR_REASON) final String reason,
+                               @HeaderParam(HDR_COMMENT) final String comment) {
         return super.createTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
     }
@@ -218,10 +217,10 @@ public class BundleResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_TAGS) final String tagList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                               @QueryParam(QUERY_TAGS) final String tagList,
+                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                               @HeaderParam(HDR_REASON) final String reason,
+                               @HeaderParam(HDR_COMMENT) final String comment) {
 
         return super.deleteTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CatalogResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CatalogResource.java
index ec6e5c0..3941dc6 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CatalogResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CatalogResource.java
@@ -16,12 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static javax.ws.rs.core.MediaType.APPLICATION_XML;
-
-import java.util.ArrayList;
-import java.util.List;
-
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
@@ -29,24 +23,35 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
+import org.joda.time.DateTime;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.common.base.Joiner;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Listing;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.StaticCatalog;
+import com.ning.billing.jaxrs.json.CatalogJsonSimple;
 import com.ning.billing.jaxrs.json.PlanDetailJason;
 import com.ning.billing.util.config.XMLWriter;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.APPLICATION_XML;
+
 @Singleton
 @Path(JaxrsResource.CATALOG_PATH)
 public class CatalogResource implements JaxrsResource {
 
-    private CatalogService catalogService;
+    private final CatalogService catalogService;
 
     @Inject
-    public CatalogResource(final CatalogService catalogService)
-    {
+    public CatalogResource(final CatalogService catalogService) {
         this.catalogService = catalogService;
     }
 
@@ -71,17 +76,27 @@ public class CatalogResource implements JaxrsResource {
     //    }
 
 
-
     @GET
     @Path("/availableAddons")
     @Produces(APPLICATION_JSON)
     public Response getAvailableAddons(@QueryParam("baseProductName") final String baseProductName) throws CatalogApiException {
-        StaticCatalog catalog = catalogService.getCurrentCatalog();
-        List<Listing> listings = catalog.getAvailableAddonListings(baseProductName);
-        List<PlanDetailJason> details = new ArrayList<PlanDetailJason>();
-        for(Listing listing : listings) {
+        final StaticCatalog catalog = catalogService.getCurrentCatalog();
+        final List<Listing> listings = catalog.getAvailableAddonListings(baseProductName);
+        final List<PlanDetailJason> details = new ArrayList<PlanDetailJason>();
+        for (final Listing listing : listings) {
             details.add(new PlanDetailJason(listing));
         }
         return Response.status(Status.OK).entity(details).build();
     }
+
+    @GET
+    @Path("/simpleCatalog")
+    @Produces(APPLICATION_JSON)
+    public Response getSimpleCatalog() throws CatalogApiException {
+
+        StaticCatalog catalog  = catalogService.getCurrentCatalog();
+        
+        CatalogJsonSimple json = new CatalogJsonSimple(catalog);
+        return Response.status(Status.OK).entity(json).build();            
+    }
 }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
index 3fba78a..8823018 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
@@ -103,31 +103,33 @@ public class ChargebackResource implements JaxrsResource {
     @GET
     @Path("/payments/{paymentId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getForPayment(@PathParam("paymentId") String paymentId) {
-        
+    public Response getForPayment(@PathParam("paymentId") final String paymentId) {
+
         try {
-            Payment payment = paymentApi.getPayment(UUID.fromString(paymentId));
-            Collection<PaymentAttempt> attempts = Collections2.filter(payment.getAttempts(), new Predicate<PaymentAttempt>() {
+            final Payment payment = paymentApi.getPayment(UUID.fromString(paymentId));
+            final Collection<PaymentAttempt> attempts = Collections2.filter(payment.getAttempts(), new Predicate<PaymentAttempt>() {
                 @Override
-                public boolean apply(PaymentAttempt input) {
+                public boolean apply(final PaymentAttempt input) {
                     return input.getPaymentStatus() == PaymentStatus.SUCCESS;
                 }
             });
             if (attempts.size() == 0) {
-                final String error = String.format("Failed to locate succesful payment attempts for paymentId %s", paymentId);
+                final String error = String.format("Failed to locate successful payment attempts for paymentId %s", paymentId);
                 return Response.status(Response.Status.NO_CONTENT).entity(error).build();
             }
-            UUID paymentAttemptId = attempts.iterator().next().getId();
-            
-            List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentAttemptId(paymentAttemptId);
-            List<ChargebackJson> chargebacksJson = convertToJson(chargebacks);
-
-            String accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(UUID.fromString(paymentId)).toString();
+            final UUID paymentAttemptId = attempts.iterator().next().getId();
 
+            final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentAttemptId(paymentAttemptId);
+            if (chargebacks.size() == 0) {
+                return Response.status(Response.Status.NO_CONTENT).build();
+            }
 
+            final UUID invoicePaymentId = chargebacks.get(0).getId();
+            final String accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(invoicePaymentId).toString();
+            final List<ChargebackJson> chargebacksJson = convertToJson(chargebacks);
             final ChargebackCollectionJson json = new ChargebackCollectionJson(accountId, chargebacksJson);
+
             return Response.status(Response.Status.OK).entity(json).build();
-        
         } catch (PaymentApiException e) {
             final String error = String.format("Failed to locate payment attempt for payment id %s", paymentId);
             return Response.status(Response.Status.NO_CONTENT).entity(error).build();
@@ -145,15 +147,36 @@ public class ChargebackResource implements JaxrsResource {
                                      @HeaderParam(HDR_REASON) final String reason,
                                      @HeaderParam(HDR_COMMENT) final String comment) {
         try {
-            invoicePaymentApi.processChargeback(UUID.fromString(json.getPaymentId()), json.getChargebackAmount(),
-                                                context.createContext(createdBy, reason, comment));
-            return uriBuilder.buildResponse(ChargebackResource.class, "getChargeback", json.getPaymentId());
+            final Payment payment = paymentApi.getPayment(UUID.fromString(json.getPaymentId()));
+            final Collection<PaymentAttempt> attempts = Collections2.filter(payment.getAttempts(), new Predicate<PaymentAttempt>() {
+                @Override
+                public boolean apply(final PaymentAttempt input) {
+                    return input.getPaymentStatus() == PaymentStatus.SUCCESS;
+                }
+            });
+            if (attempts.size() == 0) {
+                final String error = String.format("Failed to locate successful payment attempts for paymentId %s", json.getPaymentId());
+                return Response.status(Response.Status.NO_CONTENT).entity(error).build();
+            }
+
+            final UUID paymentAttemptId = attempts.iterator().next().getId();
+            final InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePayment(paymentAttemptId);
+            if (invoicePayment == null) {
+                final String error = String.format("Failed to locate invoice payment for paymentAttemptId %s", paymentAttemptId);
+                return Response.status(Response.Status.NO_CONTENT).entity(error).build();
+            }
+
+            final InvoicePayment chargeBack = invoicePaymentApi.processChargeback(invoicePayment.getId(), json.getChargebackAmount(),
+                                                                                  context.createContext(createdBy, reason, comment));
+            return uriBuilder.buildResponse(ChargebackResource.class, "getChargeback", chargeBack.getId());
         } catch (InvoiceApiException e) {
             final String error = String.format("Failed to create chargeback %s", json);
             log.info(error, e);
             return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
         } catch (IllegalArgumentException e) {
             return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
+        } catch (PaymentApiException e) {
+            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
         }
     }
 
@@ -165,4 +188,4 @@ public class ChargebackResource implements JaxrsResource {
 
         return result;
     }
-}
\ No newline at end of file
+}
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 c957c86..822e0ab 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
@@ -16,13 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.UUID;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -35,20 +28,25 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.joda.time.format.DateTimeFormatter;
 import org.joda.time.format.ISODateTimeFormat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
+import com.ning.billing.invoice.api.InvoiceNotifier;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
@@ -64,12 +62,12 @@ import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.TEXT_HTML;
+
 
 @Path(JaxrsResource.INVOICES_PATH)
 public class InvoiceResource extends JaxRsResourceBase {
-    
-    private static final Logger log = LoggerFactory.getLogger(InvoiceResource.class);
-    
     private static final String ID_PARAM_NAME = "invoiceId";
     private static final String CUSTOM_FIELD_URI = JaxrsResource.CUSTOM_FIELDS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
     private static final String TAG_URI = JaxrsResource.TAGS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
@@ -81,34 +79,36 @@ public class InvoiceResource extends JaxRsResourceBase {
     private final PaymentApi paymentApi;
     private final Context context;
     private final JaxrsUriBuilder uriBuilder;
+    private final InvoiceNotifier invoiceNotifier;
 
     @Inject
     public InvoiceResource(final AccountUserApi accountApi,
-            final InvoiceUserApi invoiceApi,
-            final PaymentApi paymentApi,            
-            final Context context,
-            final JaxrsUriBuilder uriBuilder,
-            final TagUserApi tagUserApi,
-            final TagHelper tagHelper,
-            final CustomFieldUserApi customFieldUserApi) {
+                           final InvoiceUserApi invoiceApi,
+                           final PaymentApi paymentApi,
+                           final Context context,
+                           final JaxrsUriBuilder uriBuilder,
+                           final TagUserApi tagUserApi,
+                           final TagHelper tagHelper,
+                           final CustomFieldUserApi customFieldUserApi,
+                           final InvoiceNotifier invoiceNotifier) {
         super(uriBuilder, tagUserApi, tagHelper, customFieldUserApi);
         this.accountApi = accountApi;
         this.invoiceApi = invoiceApi;
         this.paymentApi = paymentApi;
         this.context = context;
         this.uriBuilder = uriBuilder;
+        this.invoiceNotifier = invoiceNotifier;
     }
 
     @GET
     @Produces(APPLICATION_JSON)
     public Response getInvoices(@QueryParam(QUERY_ACCOUNT_ID) final String accountId) {
         try {
-
             Preconditions.checkNotNull(accountId, "% query parameter must be specified", QUERY_ACCOUNT_ID);
             accountApi.getAccountById(UUID.fromString(accountId));
-            List<Invoice> invoices = invoiceApi.getInvoicesByAccount(UUID.fromString(accountId));
-            List<InvoiceJsonSimple> result = new LinkedList<InvoiceJsonSimple>();
-            for (Invoice cur : invoices) {
+            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));
             }
             return Response.status(Status.OK).entity(result).build();
@@ -120,84 +120,98 @@ public class InvoiceResource extends JaxRsResourceBase {
     }
 
     @GET
-    @Path("/{invoiceId:\\w+-\\w+-\\w+-\\w+-\\w+}")
+    @Path("/{invoiceId:" + UUID_PATTERN + "}/")
     @Produces(APPLICATION_JSON)
-    public Response getInvoice(@PathParam("invoiceId") String invoiceId, @QueryParam("withItems") @DefaultValue("false") boolean withItems) {
-        Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId));
+    public Response getInvoice(@PathParam("invoiceId") final String invoiceId, @QueryParam("withItems") @DefaultValue("false") final boolean withItems) {
+        final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId));
         if (invoice == null) {
             return Response.status(Status.NO_CONTENT).build();
-        }
-        else {
-            InvoiceJsonSimple json = withItems ? new InvoiceJsonWithItems(invoice) : new InvoiceJsonSimple(invoice);
+        } else {
+            final InvoiceJsonSimple json = withItems ? new InvoiceJsonWithItems(invoice) : new InvoiceJsonSimple(invoice);
             return Response.status(Status.OK).entity(json).build();
         }
     }
 
+    @GET
+    @Path("/{invoiceId:" + UUID_PATTERN + "}/html")
+    @Produces(TEXT_HTML)
+    public Response getInvoiceAsHTML(@PathParam("invoiceId") final String invoiceId) {
+        try {
+            return Response.status(Status.OK).entity(invoiceApi.getInvoiceAsHTML(UUID.fromString(invoiceId))).build();
+        } catch (AccountApiException e) {
+            return Response.status(Status.NO_CONTENT).build();
+        } catch (IOException e) {
+            return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+        } catch (InvoiceApiException e) {
+            return Response.status(Status.NO_CONTENT).build();
+        }
+    }
+
     @POST
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
-    public Response createFutureInvoice(final InvoiceJsonSimple invoice,
-            @QueryParam(QUERY_ACCOUNT_ID) final String accountId,
-            @QueryParam(QUERY_TARGET_DATE) final String targetDate,
-            @QueryParam(QUERY_DRY_RUN) @DefaultValue("false") final Boolean dryRun,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
-
+    public Response createFutureInvoice(@QueryParam(QUERY_ACCOUNT_ID) final String accountId,
+                                        @QueryParam(QUERY_TARGET_DATE) final String targetDate,
+                                        @QueryParam(QUERY_DRY_RUN) @DefaultValue("false") final Boolean dryRun,
+                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                        @HeaderParam(HDR_REASON) final String reason,
+                                        @HeaderParam(HDR_COMMENT) final String comment) {
         try {
-
             Preconditions.checkNotNull(accountId, "% needs to be specified", QUERY_ACCOUNT_ID);
             Preconditions.checkNotNull(targetDate, "% needs to be specified", QUERY_TARGET_DATE);
 
-            DateTime inputDate = (targetDate != null) ? DATE_TIME_FORMATTER.parseDateTime(targetDate) : null;
+            final DateTime inputDate = (targetDate != null) ? DATE_TIME_FORMATTER.parseDateTime(targetDate) : null;
 
             accountApi.getAccountById(UUID.fromString(accountId));
-            Invoice generatedInvoice = invoiceApi.triggerInvoiceGeneration(UUID.fromString(accountId), inputDate, dryRun.booleanValue(),
-                    context.createContext(createdBy, reason, comment));
+            final Invoice generatedInvoice = invoiceApi.triggerInvoiceGeneration(UUID.fromString(accountId), inputDate, dryRun,
+                                                                                 context.createContext(createdBy, reason, comment));
             if (dryRun) {
                 return Response.status(Status.OK).entity(new InvoiceJsonSimple(generatedInvoice)).build();
             } else {
-               return uriBuilder.buildResponse(InvoiceResource.class, "getInvoice", generatedInvoice.getId());
+                return uriBuilder.buildResponse(InvoiceResource.class, "getInvoice", generatedInvoice.getId());
             }
         } catch (AccountApiException e) {
             return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
         } catch (InvoiceApiException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+            if (e.getCode() == ErrorCode.INVOICE_NOTHING_TO_DO.getCode()) {
+                return Response.status(Status.NO_CONTENT).build();
+            } else {
+                return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+            }
         } catch (NullPointerException e) {
             return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
         }
     }
 
     @GET
-    @Path("/{invoiceId:\\w+-\\w+-\\w+-\\w+-\\w+}/" + PAYMENTS)
+    @Path("/{invoiceId:" + UUID_PATTERN + "}/" + PAYMENTS)
     @Produces(APPLICATION_JSON)
-    public Response getPayments(@PathParam("invoiceId") String invoiceId) {
+    public Response getPayments(@PathParam("invoiceId") final String invoiceId) {
         try {
-            List<Payment> payments = paymentApi.getInvoicePayments(UUID.fromString(invoiceId));
-            List<PaymentJsonSimple> result =  new ArrayList<PaymentJsonSimple>(payments.size());
-            for (Payment cur : payments) {
+            final List<Payment> payments = paymentApi.getInvoicePayments(UUID.fromString(invoiceId));
+            final List<PaymentJsonSimple> result = new ArrayList<PaymentJsonSimple>(payments.size());
+            for (final Payment cur : payments) {
                 result.add(new PaymentJsonSimple(cur));
             }
             return Response.status(Status.OK).entity(result).build();
         } catch (PaymentApiException e) {
-            return Response.status(Status.NOT_FOUND).build();     
+            return Response.status(Status.NOT_FOUND).build();
         }
     }
 
     @POST
     @Produces(APPLICATION_JSON)
     @Consumes(APPLICATION_JSON)
-    @Path("/{invoiceId:\\w+-\\w+-\\w+-\\w+-\\w+}/" + PAYMENTS)
-    public Response createInstantPayment(PaymentJsonSimple payment,
-            @QueryParam(QUERY_PAYMENT_EXTERNAL) @DefaultValue("false") final Boolean externalPayment,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+    @Path("/{invoiceId:" + UUID_PATTERN + "}/" + PAYMENTS)
+    public Response createInstantPayment(final PaymentJsonSimple payment,
+                                         @QueryParam(QUERY_PAYMENT_EXTERNAL) @DefaultValue("false") final Boolean externalPayment,
+                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                         @HeaderParam(HDR_REASON) final String reason,
+                                         @HeaderParam(HDR_COMMENT) final String comment) {
         try {
-            Account account = accountApi.getAccountById(UUID.fromString(payment.getAccountId()));
+            final Account account = accountApi.getAccountById(UUID.fromString(payment.getAccountId()));
             paymentApi.createPayment(account, UUID.fromString(payment.getInvoiceId()), null, context.createContext(createdBy, reason, comment));
-            Response response = uriBuilder.buildResponse(InvoiceResource.class, "getPayments", payment.getInvoiceId());
-            return response;
+            return uriBuilder.buildResponse(InvoiceResource.class, "getPayments", payment.getInvoiceId());
         } catch (PaymentApiException e) {
             final String error = String.format("Failed to create payment %s", e.getMessage());
             return Response.status(Status.BAD_REQUEST).entity(error).build();
@@ -209,6 +223,34 @@ public class InvoiceResource extends JaxRsResourceBase {
         }
     }
 
+    @POST
+    @Path("/{invoiceId:" + UUID_PATTERN + "}/" + EMAIL_NOTIFICATIONS)
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    public Response triggerEmailNotificationForInvoice(@PathParam("invoiceId") final String invoiceId,
+                                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                                       @HeaderParam(HDR_REASON) final String reason,
+                                                       @HeaderParam(HDR_COMMENT) final String comment) {
+        final Invoice invoice = invoiceApi.getInvoice(UUID.fromString(invoiceId));
+        if (invoice == null) {
+            return Response.status(Status.NOT_FOUND).build();
+        }
+
+        try {
+            final Account account = accountApi.getAccountById(invoice.getAccountId());
+
+            // Send the email (synchronous send)
+            invoiceNotifier.notify(account, invoice);
+
+            return Response.status(Status.OK).build();
+        } catch (AccountApiException e) {
+            return Response.status(Status.NOT_FOUND).build();
+        } catch (InvoiceApiException e) {
+            // Sending failed
+            return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build();
+        }
+    }
+
     @GET
     @Path(CUSTOM_FIELD_URI)
     @Produces(APPLICATION_JSON)
@@ -221,12 +263,12 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
-            final List<CustomFieldJson> customFields,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                       final List<CustomFieldJson> customFields,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment) {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment));
     }
 
     @DELETE
@@ -234,18 +276,18 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment) {
         return super.deleteCustomFields(UUID.fromString(id), customFieldList,
-                context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment));
     }
 
     @GET
     @Path(TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) String id) {
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) {
         return super.getTags(UUID.fromString(id));
     }
 
@@ -254,10 +296,10 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_TAGS) final String tagList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                               @QueryParam(QUERY_TAGS) final String tagList,
+                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                               @HeaderParam(HDR_REASON) final String reason,
+                               @HeaderParam(HDR_COMMENT) final String comment) {
         return super.createTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
     }
@@ -267,10 +309,10 @@ public class InvoiceResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_TAGS) final String tagList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                               @QueryParam(QUERY_TAGS) final String tagList,
+                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                               @HeaderParam(HDR_REASON) final String reason,
+                               @HeaderParam(HDR_COMMENT) final String comment) {
 
         return super.deleteTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
index fbf052f..16c6bc5 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
@@ -15,77 +15,74 @@
  */
 package com.ning.billing.jaxrs.resources;
 
-
 public interface JaxrsResource {
-	
     public static final String API_PREFIX = "";
     public static final String API_VERSION = "/1.0";
     public static final String API_POSTFIX = "/kb";
-    
+
     public static final String PREFIX = API_PREFIX + API_VERSION + API_POSTFIX;
-	
-	public static final String TIMELINE = "timeline";
-	
-	/*
-	 * Metadata Additional headers 
-	 */
-	public static String HDR_CREATED_BY = "X-Killbill-CreatedBy";
-	public static String HDR_REASON = "X-Killbill-Reason";  
-	public static String HDR_COMMENT = "X-Killbill-Comment";   	
-	
-	/*
-	 * Patterns
-	 */
-	public static String STRING_PATTERN = "\\w+";	
-	public static String UUID_PATTERN = "\\w+-\\w+-\\w+-\\w+-\\w+";
-	
-	/*
-	 * Query parameters
-	 */
-	public static final String QUERY_EXTERNAL_KEY = "external_key";
-	public static final String QUERY_REQUESTED_DT = "requested_date";
-	public static final String QUERY_CALL_COMPLETION = "call_completion";
-	public static final String QUERY_CALL_TIMEOUT = "call_timeout_sec";    
-	public static final String QUERY_DRY_RUN = "dry_run";      
-	public static final String QUERY_TARGET_DATE = "target_date";          
-	
-	public static final String QUERY_ACCOUNT_ID = "account_id";
-
-	public static final String QUERY_PAYMENT_EXTERNAL = "external_payment";
-	public static final String QUERY_PAYMENT_LAST4_CC = "last4_cc";
-	public static final String QUERY_PAYMENT_NAME_ON_CC= "name_on_cc";	
-	
-	public static final String QUERY_TAGS = "tag_list";    
-	public static final String QUERY_CUSTOM_FIELDS = "custom_field_list";    	
-	
-	public static final String QUERY_PAYMENT_METHOD_PLUGIN_INFO = "plugin_info";
-	public static final String QUERY_PAYMENT_METHOD_IS_DEFAULT = "is_default";
-	
-		
-	
-	public static final String ACCOUNTS = "accounts";  
+
+
+    public static final String TIMELINE = "timeline";
+
+    /*
+     * Metadata Additional headers
+     */
+    public static String HDR_CREATED_BY = "X-Killbill-CreatedBy";
+    public static String HDR_REASON = "X-Killbill-Reason";
+    public static String HDR_COMMENT = "X-Killbill-Comment";
+
+    /*
+     * Patterns
+     */
+    public static String STRING_PATTERN = "\\w+";
+    public static String UUID_PATTERN = "\\w+-\\w+-\\w+-\\w+-\\w+";
+
+    /*
+     * Query parameters
+     */
+    public static final String QUERY_EXTERNAL_KEY = "external_key";
+    public static final String QUERY_REQUESTED_DT = "requested_date";
+    public static final String QUERY_CALL_COMPLETION = "call_completion";
+    public static final String QUERY_CALL_TIMEOUT = "call_timeout_sec";
+    public static final String QUERY_DRY_RUN = "dry_run";
+    public static final String QUERY_TARGET_DATE = "target_date";
+
+    public static final String QUERY_ACCOUNT_ID = "account_id";
+
+    public static final String QUERY_PAYMENT_EXTERNAL = "external_payment";
+    public static final String QUERY_PAYMENT_LAST4_CC = "last4_cc";
+    public static final String QUERY_PAYMENT_NAME_ON_CC = "name_on_cc";
+
+    public static final String QUERY_TAGS = "tag_list";
+    public static final String QUERY_CUSTOM_FIELDS = "custom_field_list";
+
+    public static final String QUERY_PAYMENT_METHOD_PLUGIN_INFO = "plugin_info";
+    public static final String QUERY_PAYMENT_METHOD_IS_DEFAULT = "is_default";
+
+
+    public static final String ACCOUNTS = "accounts";
     public static final String ACCOUNTS_PATH = PREFIX + "/" + ACCOUNTS;
 
-	public static final String BUNDLES = "bundles";		
-	public static final String BUNDLES_PATH = PREFIX + "/" + BUNDLES;
+    public static final String BUNDLES = "bundles";
+    public static final String BUNDLES_PATH = PREFIX + "/" + BUNDLES;
 
-    public static final String SUBSCRIPTIONS = "subscriptions";     
+    public static final String SUBSCRIPTIONS = "subscriptions";
     public static final String SUBSCRIPTIONS_PATH = PREFIX + "/" + SUBSCRIPTIONS;
 
-    public static final String TAG_DEFINITIONS = "tagDefinitions";     
+    public static final String TAG_DEFINITIONS = "tagDefinitions";
     public static final String TAG_DEFINITIONS_PATH = PREFIX + "/" + TAG_DEFINITIONS;
 
-    public static final String INVOICES = "invoices";     
+    public static final String INVOICES = "invoices";
     public static final String INVOICES_PATH = PREFIX + "/" + INVOICES;
 
-    public static final String PAYMENTS = "payments";     
-    public static final String PAYMENTS_PATH = PREFIX + "/" + PAYMENTS;    
+    public static final String PAYMENTS = "payments";
+    public static final String PAYMENTS_PATH = PREFIX + "/" + PAYMENTS;
 
-    public static final String PAYMENT_METHODS = "paymentMethods";     
-    public static final String PAYMENT_METHODS_PATH  = PREFIX + "/" + PAYMENT_METHODS;
+    public static final String PAYMENT_METHODS = "paymentMethods";
+    public static final String PAYMENT_METHODS_PATH = PREFIX + "/" + PAYMENT_METHODS;
     public static final String PAYMENT_METHODS_DEFAULT_PATH_POSTFIX = "setDefault";
-    
-    
+
     public static final String CREDITS = "credits";
     public static final String CREDITS_PATH = PREFIX + "/" + CREDITS;
 
@@ -94,7 +91,9 @@ public interface JaxrsResource {
 
     public static final String TAGS = "tags";
     public static final String CUSTOM_FIELDS = "customFields";
-    
+    public static final String EMAILS = "emails";
+    public static final String EMAIL_NOTIFICATIONS = "emailNotifications";
+
     public static final String CATALOG = "catalog";
     public static final String CATALOG_PATH = PREFIX + "/" + CATALOG;
 
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 33d778c..bdff8e8 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
@@ -16,6 +16,14 @@
 
 package com.ning.billing.jaxrs.resources;
 
+import javax.ws.rs.core.Response;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
 import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Collections2;
@@ -33,14 +41,6 @@ import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.TagDefinition;
 
-import javax.ws.rs.core.Response;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
 public abstract class JaxRsResourceBase implements JaxrsResource {
     private final JaxrsUriBuilder uriBuilder;
     private final TagUserApi tagUserApi;
@@ -60,15 +60,15 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
     }
 
     protected Response getTags(final UUID id) {
-        Map<String, Tag> tags = tagUserApi.getTags(id, getObjectType());
-        Collection<String> tagNameList = (tags.size() == 0) ?
+        final Map<String, Tag> tags = tagUserApi.getTags(id, getObjectType());
+        final Collection<String> tagNameList = (tags.size() == 0) ?
                 Collections.<String>emptyList() :
-            Collections2.transform(tags.values(), new Function<Tag, String>() {
-                @Override
-                public String apply(Tag input) {
-                    return input.getTagDefinitionName();
-                }
-            });
+                Collections2.transform(tags.values(), new Function<Tag, String>() {
+                    @Override
+                    public String apply(final Tag input) {
+                        return input.getTagDefinitionName();
+                    }
+                });
         return Response.status(Response.Status.OK).entity(tagNameList).build();
     }
 
@@ -78,7 +78,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
         try {
             Preconditions.checkNotNull(tagList, "Query % list cannot be null", JaxrsResource.QUERY_TAGS);
 
-            List<TagDefinition> input = tagHelper.getTagDefinitionFromTagList(tagList);
+            final List<TagDefinition> input = tagHelper.getTagDefinitionFromTagList(tagList);
             tagUserApi.addTags(id, getObjectType(), input, context);
 
             return uriBuilder.buildResponse(this.getClass(), "createTags", id);
@@ -98,7 +98,7 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
                                   final CallContext context) {
 
         try {
-            List<TagDefinition> input = tagHelper.getTagDefinitionFromTagList(tagList);
+            final List<TagDefinition> input = tagHelper.getTagDefinitionFromTagList(tagList);
             tagUserApi.removeTags(id, getObjectType(), input, context);
 
             return Response.status(Response.Status.OK).build();
@@ -114,10 +114,10 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
     }
 
     protected Response getCustomFields(final UUID id) {
-        Map<String, CustomField> fields = customFieldUserApi.getCustomFields(id, getObjectType());
+        final Map<String, CustomField> fields = customFieldUserApi.getCustomFields(id, getObjectType());
 
-        List<CustomFieldJson> result = new LinkedList<CustomFieldJson>();
-        for (CustomField cur : fields.values()) {
+        final List<CustomFieldJson> result = new LinkedList<CustomFieldJson>();
+        for (final CustomField cur : fields.values()) {
             result.add(new CustomFieldJson(cur));
         }
         return Response.status(Response.Status.OK).entity(result).build();
@@ -127,8 +127,8 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
                                           final List<CustomFieldJson> customFields,
                                           final CallContext context) {
         try {
-            LinkedList<CustomField> input = new LinkedList<CustomField>();
-            for (CustomFieldJson cur : customFields) {
+            final LinkedList<CustomField> input = new LinkedList<CustomField>();
+            for (final CustomFieldJson cur : customFields) {
                 input.add(new StringCustomField(cur.getName(), cur.getValue()));
             }
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
index 14ac19b..339da66 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
@@ -15,11 +15,6 @@
  */
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import java.util.List;
-import java.util.UUID;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -32,17 +27,16 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
+import java.util.UUID;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
-import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.PaymentMethodJson;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
@@ -54,45 +48,46 @@ import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
 @Singleton
 @Path(JaxrsResource.PAYMENT_METHODS_PATH)
 public class PaymentMethodResource extends JaxRsResourceBase {
 
     private static final Logger log = LoggerFactory.getLogger(PaymentMethodResource.class);
-    
+
     private final PaymentApi paymentApi;
     private final AccountUserApi accountApi;
     private final Context context;
-    
+
     @Inject
     public PaymentMethodResource(final JaxrsUriBuilder uriBuilder, final AccountUserApi accountApi,
-            final PaymentApi paymentApi, final TagUserApi tagUserApi, final TagHelper tagHelper,
-            final CustomFieldUserApi customFieldUserApi, final Context context) {
+                                 final PaymentApi paymentApi, final TagUserApi tagUserApi, final TagHelper tagHelper,
+                                 final CustomFieldUserApi customFieldUserApi, final Context context) {
         super(uriBuilder, tagUserApi, tagHelper, customFieldUserApi);
         this.paymentApi = paymentApi;
         this.accountApi = accountApi;
         this.context = context;
     }
-    
-    
-    
+
+
     @GET
-    @Path("/{paymentMethodId:" + UUID_PATTERN + "}")    
+    @Path("/{paymentMethodId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
     public Response getPaymentMethod(@PathParam("paymentMethodId") final String paymentMethodId,
-            @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo) {
+                                     @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo) {
         try {
             PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
-            final Account account = accountApi.getAccountById(paymentMethod.getAccountId());  
+            final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
             if (withPluginInfo) {
                 paymentMethod = paymentApi.getPaymentMethod(account, paymentMethod.getId(), true);
             }
-            PaymentMethodJson json = PaymentMethodJson.toPaymentMethodJson(account, paymentMethod);
+            final PaymentMethodJson json = PaymentMethodJson.toPaymentMethodJson(account, paymentMethod);
 
             return Response.status(Status.OK).entity(json).build();
         } catch (AccountApiException e) {
-            return Response.status(Status.NO_CONTENT).build();            
-        } catch (PaymentApiException e) { 
+            return Response.status(Status.NO_CONTENT).build();
+        } catch (PaymentApiException e) {
             return Response.status(Status.NO_CONTENT).entity("PaymentMethod does not exist").build();
         }
     }
@@ -103,45 +98,45 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     @Produces(APPLICATION_JSON)
     @Path("/{paymentMethodId:" + UUID_PATTERN + "}")
     public Response updatePaymentMethod(final PaymentMethodJson json,
-            @PathParam("paymentMethodId") final String paymentMethodId,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                        @PathParam("paymentMethodId") final String paymentMethodId,
+                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                        @HeaderParam(HDR_REASON) final String reason,
+                                        @HeaderParam(HDR_COMMENT) final String comment) {
         try {
 
-            final PaymentMethod input = json.toPaymentMethod();            
+            final PaymentMethod input = json.toPaymentMethod();
             final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
- 
+
             final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
 
             paymentApi.updatePaymentMethod(account, paymentMethod.getId(), input.getPluginDetail());
             return getPaymentMethod(paymentMethod.getId().toString(), false);
-        } catch (PaymentApiException e) { 
-            return Response.status(Status.NO_CONTENT).entity("PaymentMethod does not exist").build();                          
+        } catch (PaymentApiException e) {
+            return Response.status(Status.NO_CONTENT).entity("PaymentMethod does not exist").build();
         } catch (AccountApiException e) {
-            return Response.status(Status.NO_CONTENT).build();              
+            return Response.status(Status.NO_CONTENT).build();
         } catch (IllegalArgumentException e) {
             return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
         }
     }
-    
+
     @DELETE
     @Produces(APPLICATION_JSON)
     @Path("/{paymentMethodId:" + UUID_PATTERN + "}")
     public Response deletePaymentMethod(@PathParam("paymentMethodId") final String paymentMethodId,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                        @HeaderParam(HDR_REASON) final String reason,
+                                        @HeaderParam(HDR_COMMENT) final String comment) {
         try {
 
-            final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));            
-            final Account account = accountApi.getAccountById(paymentMethod.getAccountId());            
+            final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId));
+            final Account account = accountApi.getAccountById(paymentMethod.getAccountId());
             paymentApi.deletedPaymentMethod(account, UUID.fromString(paymentMethodId), context.createContext(createdBy, reason, comment));
             return Response.status(Status.OK).build();
-        } catch (PaymentApiException e) { 
-            return Response.status(Status.NO_CONTENT).entity("PaymentMethod does not exist").build();                          
+        } catch (PaymentApiException e) {
+            return Response.status(Status.NO_CONTENT).entity("PaymentMethod does not exist").build();
         } catch (AccountApiException e) {
-            return Response.status(Status.NO_CONTENT).build();              
+            return Response.status(Status.NO_CONTENT).build();
         } catch (IllegalArgumentException e) {
             return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
         }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
index 9f8d421..5f53ab3 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
@@ -16,8 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -28,11 +26,11 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
+import java.util.List;
+import java.util.UUID;
 
 import com.google.inject.Inject;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
-import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.jaxrs.util.TagHelper;
@@ -40,12 +38,11 @@ import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.dao.ObjectType;
 
-import java.util.List;
-import java.util.UUID;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 @Path(JaxrsResource.PAYMENTS_PATH)
 public class PaymentResource extends JaxRsResourceBase {
-    
+
     private static final String ID_PARAM_NAME = "paymentId";
     private static final String CUSTOM_FIELD_URI = JaxrsResource.CUSTOM_FIELDS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
     private static final String TAG_URI = JaxrsResource.TAGS + "/{" + ID_PARAM_NAME + ":" + UUID_PATTERN + "}";
@@ -72,12 +69,12 @@ public class PaymentResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createCustomFields(@PathParam(ID_PARAM_NAME) final String id,
-            final List<CustomFieldJson> customFields,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                       final List<CustomFieldJson> customFields,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment) {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment));
     }
 
     @DELETE
@@ -85,18 +82,18 @@ public class PaymentResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response deleteCustomFields(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                       @QueryParam(QUERY_CUSTOM_FIELDS) final String customFieldList,
+                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                       @HeaderParam(HDR_REASON) final String reason,
+                                       @HeaderParam(HDR_COMMENT) final String comment) {
         return super.deleteCustomFields(UUID.fromString(id), customFieldList,
-                context.createContext(createdBy, reason, comment));
+                                        context.createContext(createdBy, reason, comment));
     }
 
     @GET
     @Path(TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) String id) {
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) {
         return super.getTags(UUID.fromString(id));
     }
 
@@ -105,10 +102,10 @@ public class PaymentResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createTags(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_TAGS) final String tagList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                               @QueryParam(QUERY_TAGS) final String tagList,
+                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                               @HeaderParam(HDR_REASON) final String reason,
+                               @HeaderParam(HDR_COMMENT) final String comment) {
         return super.createTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
     }
@@ -118,10 +115,10 @@ public class PaymentResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response deleteTags(@PathParam(ID_PARAM_NAME) final String id,
-            @QueryParam(QUERY_TAGS) final String tagList,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                               @QueryParam(QUERY_TAGS) final String tagList,
+                               @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                               @HeaderParam(HDR_REASON) final String reason,
+                               @HeaderParam(HDR_COMMENT) final String comment) {
 
         return super.deleteTags(UUID.fromString(id), tagList,
                                 context.createContext(createdBy, reason, comment));
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
index a55f952..fe79b2a 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
@@ -16,13 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import java.math.BigDecimal;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.TimeoutException;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -36,12 +29,11 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.TimeoutException;
 
-import com.ning.billing.jaxrs.json.CustomFieldJson;
-import com.ning.billing.jaxrs.util.TagHelper;
-import com.ning.billing.util.api.CustomFieldUserApi;
-import com.ning.billing.util.api.TagUserApi;
-import com.ning.billing.util.dao.ObjectType;
 import org.joda.time.DateTime;
 import org.joda.time.format.DateTimeFormatter;
 import org.joda.time.format.ISODateTimeFormat;
@@ -59,15 +51,22 @@ import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionEvent;
 import com.ning.billing.invoice.api.EmptyInvoiceEvent;
 import com.ning.billing.invoice.api.InvoiceCreationEvent;
+import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.jaxrs.util.KillbillEventHandler;
+import com.ning.billing.jaxrs.util.TagHelper;
 import com.ning.billing.payment.api.PaymentErrorEvent;
 import com.ning.billing.payment.api.PaymentInfoEvent;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.userrequest.CompletionUserRequestBase;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
 @Path(JaxrsResource.SUBSCRIPTIONS_PATH)
 public class SubscriptionResource extends JaxRsResourceBase {
     private static final Logger log = LoggerFactory.getLogger(SubscriptionResource.class);
@@ -79,9 +78,9 @@ public class SubscriptionResource extends JaxRsResourceBase {
 
     private final EntitlementUserApi entitlementApi;
     private final Context context;
-    private final JaxrsUriBuilder uriBuilder;	
+    private final JaxrsUriBuilder uriBuilder;
     private final KillbillEventHandler killbillHandler;
-    
+
     @Inject
     public SubscriptionResource(final JaxrsUriBuilder uriBuilder, final EntitlementUserApi entitlementApi,
             final Context context, final KillbillEventHandler killbillHandler,
@@ -99,9 +98,9 @@ public class SubscriptionResource extends JaxRsResourceBase {
     public Response getSubscription(@PathParam("subscriptionId") final String subscriptionId) throws EntitlementUserApiException {
 
         try {
-            UUID uuid = UUID.fromString(subscriptionId);
-            Subscription subscription = entitlementApi.getSubscriptionFromId(uuid);
-            SubscriptionJsonNoEvents json = new SubscriptionJsonNoEvents(subscription);
+            final UUID uuid = UUID.fromString(subscriptionId);
+            final Subscription subscription = entitlementApi.getSubscriptionFromId(uuid);
+            final SubscriptionJsonNoEvents json = new SubscriptionJsonNoEvents(subscription);
             return Response.status(Status.OK).entity(json).build();
         } catch (EntitlementUserApiException e) {
             if (e.getCode() == ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getCode()) {
@@ -111,7 +110,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
             }
         }
     }
-  
+
 
     @POST
     @Consumes(APPLICATION_JSON)
@@ -125,28 +124,30 @@ public class SubscriptionResource extends JaxRsResourceBase {
             @HeaderParam(HDR_COMMENT) final String comment) {
 
 
-        SubscriptionCallCompletionCallback<Subscription> callback = new SubscriptionCallCompletionCallback<Subscription>() {
+        final SubscriptionCallCompletionCallback<Subscription> callback = new SubscriptionCallCompletionCallback<Subscription>() {
             @Override
             public Subscription doOperation(final CallContext ctx) throws EntitlementUserApiException, InterruptedException, TimeoutException {
 
-                DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;        
-                UUID uuid = UUID.fromString(subscription.getBundleId());
+                final DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
+                final UUID uuid = UUID.fromString(subscription.getBundleId());
 
-                PlanPhaseSpecifier spec =  new PlanPhaseSpecifier(subscription.getProductName(),
+                final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(subscription.getProductName(),
                         ProductCategory.valueOf(subscription.getProductCategory()),
                         BillingPeriod.valueOf(subscription.getBillingPeriod()), subscription.getPriceList(), null);
                 return entitlementApi.createSubscription(uuid, spec, inputDate, ctx);
             }
+
             @Override
             public boolean isImmOperation() {
                 return true;
             }
+
             @Override
             public Response doResponseOk(final Subscription createdSubscription) {
                 return uriBuilder.buildResponse(SubscriptionResource.class, "getSubscription", createdSubscription.getId());
             }
         };
-        SubscriptionCallCompletion<Subscription> callCompletionCreation = new SubscriptionCallCompletion<Subscription>();
+        final SubscriptionCallCompletion<Subscription> callCompletionCreation = new SubscriptionCallCompletion<Subscription>();
         return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
     }
 
@@ -163,31 +164,33 @@ public class SubscriptionResource extends JaxRsResourceBase {
             @HeaderParam(HDR_REASON) final String reason,
             @HeaderParam(HDR_COMMENT) final String comment) {
 
-        SubscriptionCallCompletionCallback<Response> callback = new SubscriptionCallCompletionCallback<Response>() {
+        final SubscriptionCallCompletionCallback<Response> callback = new SubscriptionCallCompletionCallback<Response>() {
 
             private boolean isImmediateOp = true;
 
             @Override
-            public Response doOperation(CallContext ctx)
-                    throws EntitlementUserApiException, InterruptedException,
-                    TimeoutException {
+            public Response doOperation(final CallContext ctx)
+            throws EntitlementUserApiException, InterruptedException,
+            TimeoutException {
                 try {
-                    UUID uuid = UUID.fromString(subscriptionId);
-                    Subscription current = entitlementApi.getSubscriptionFromId(uuid);
-                    DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
-                    isImmediateOp = current.changePlan(subscription.getProductName(),  BillingPeriod.valueOf(subscription.getBillingPeriod()), subscription.getPriceList(), inputDate, ctx);
+                    final UUID uuid = UUID.fromString(subscriptionId);
+                    final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
+                    final DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
+                    isImmediateOp = current.changePlan(subscription.getProductName(), BillingPeriod.valueOf(subscription.getBillingPeriod()), subscription.getPriceList(), inputDate, ctx);
                     return Response.status(Status.OK).build();
                 } catch (EntitlementUserApiException e) {
-                    log.warn("Subscription not found: " + subscriptionId , e);
+                    log.warn("Subscription not found: " + subscriptionId, e);
                     return Response.status(Status.NO_CONTENT).build();
                 }
             }
+
             @Override
             public boolean isImmOperation() {
                 return isImmediateOp;
             }
+
             @Override
-            public Response doResponseOk(Response operationResponse) {
+            public Response doResponseOk(final Response operationResponse) {
                 if (operationResponse.getStatus() != Status.OK.getStatusCode()) {
                     return operationResponse;
                 }
@@ -202,7 +205,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
                 }
             }
         };
-        SubscriptionCallCompletion<Response> callCompletionCreation = new SubscriptionCallCompletion<Response>();
+        final SubscriptionCallCompletion<Response> callCompletionCreation = new SubscriptionCallCompletion<Response>();
         return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
     }
 
@@ -214,13 +217,13 @@ public class SubscriptionResource extends JaxRsResourceBase {
             @HeaderParam(HDR_REASON) final String reason,
             @HeaderParam(HDR_COMMENT) final String comment) {
         try {
-            UUID uuid = UUID.fromString(subscriptionId);
-            Subscription current = entitlementApi.getSubscriptionFromId(uuid);
-        
+            final UUID uuid = UUID.fromString(subscriptionId);
+            final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
+
             current.uncancel(context.createContext(createdBy, reason, comment));
             return Response.status(Status.OK).build();
         } catch (EntitlementUserApiException e) {
-            if(e.getCode() == ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getCode()) {
+            if (e.getCode() == ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getCode()) {
                 return Response.status(Status.NO_CONTENT).build();
             } else {
                 log.info(String.format("Failed to uncancel plan for subscription %s", subscriptionId), e);
@@ -232,7 +235,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @DELETE
     @Path("/{subscriptionId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response cancelSubscriptionPlan(final @PathParam("subscriptionId") String subscriptionId,
+    public Response cancelSubscriptionPlan(@PathParam("subscriptionId") final String subscriptionId,
             @QueryParam(QUERY_REQUESTED_DT) final String requestedDate,
             @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion,
             @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("5") final long timeoutSec,
@@ -240,80 +243,89 @@ public class SubscriptionResource extends JaxRsResourceBase {
             @HeaderParam(HDR_REASON) final String reason,
             @HeaderParam(HDR_COMMENT) final String comment) {
 
-        SubscriptionCallCompletionCallback<Response> callback = new SubscriptionCallCompletionCallback<Response>() {
+        final SubscriptionCallCompletionCallback<Response> callback = new SubscriptionCallCompletionCallback<Response>() {
 
             private boolean isImmediateOp = true;
 
             @Override
-            public Response doOperation(CallContext ctx)
-                    throws EntitlementUserApiException, InterruptedException,
-                    TimeoutException {
+            public Response doOperation(final CallContext ctx)
+            throws EntitlementUserApiException, InterruptedException,
+            TimeoutException {
                 try {
-                    UUID uuid = UUID.fromString(subscriptionId);
+                    final UUID uuid = UUID.fromString(subscriptionId);
 
-                    Subscription current = entitlementApi.getSubscriptionFromId(uuid);
+                    final Subscription current = entitlementApi.getSubscriptionFromId(uuid);
 
-                    DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
+                    final DateTime inputDate = (requestedDate != null) ? DATE_TIME_FORMATTER.parseDateTime(requestedDate) : null;
                     isImmediateOp = current.cancel(inputDate, false, ctx);
                     return Response.status(Status.OK).build();
                 } catch (EntitlementUserApiException e) {
-                    if(e.getCode() == ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getCode()) {
+                    if (e.getCode() == ErrorCode.ENT_INVALID_SUBSCRIPTION_ID.getCode()) {
                         return Response.status(Status.NO_CONTENT).build();
                     } else {
                         throw e;
                     }
                 }
             }
+
             @Override
             public boolean isImmOperation() {
                 return isImmediateOp;
             }
+
             @Override
-            public Response doResponseOk(Response operationResponse) {
+            public Response doResponseOk(final Response operationResponse) {
                 return operationResponse;
             }
         };
-        SubscriptionCallCompletion<Response> callCompletionCreation = new SubscriptionCallCompletion<Response>();
+        final SubscriptionCallCompletion<Response> callCompletionCreation = new SubscriptionCallCompletion<Response>();
         return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, createdBy, reason, comment);
     }
 
-    private final static class CompletionUserRequestSubscription extends CompletionUserRequestBase {
+    private static final class CompletionUserRequestSubscription extends CompletionUserRequestBase {
 
         public CompletionUserRequestSubscription(final UUID userToken) {
             super(userToken);
         }
+
         @Override
         public void onSubscriptionTransition(SubscriptionEvent curEvent) {
-            log.debug(String.format("Got event SubscriptionTransition token = %s, type = %s, remaining = %d ", 
+            log.info(String.format("Got event SubscriptionTransition token = %s, type = %s, remaining = %d ", 
                     curEvent.getUserToken(), curEvent.getTransitionType(),  curEvent.getRemainingEventsForUserOperation())); 
         }
+
         @Override
         public void onEmptyInvoice(final EmptyInvoiceEvent curEvent) {
-            log.debug(String.format("Got event EmptyInvoiceNotification token = %s ", curEvent.getUserToken())); 
+            log.info(String.format("Got event EmptyInvoiceNotification token = %s ", curEvent.getUserToken())); 
             notifyForCompletion();
         }
+
         @Override
         public void onInvoiceCreation(InvoiceCreationEvent curEvent) {
-            log.debug(String.format("Got event InvoiceCreationNotification token = %s ", curEvent.getUserToken())); 
+            log.info(String.format("Got event InvoiceCreationNotification token = %s ", curEvent.getUserToken())); 
             if (curEvent.getAmountOwed().compareTo(BigDecimal.ZERO) <= 0) {
                 notifyForCompletion();
             }
         }
+
         @Override
         public void onPaymentInfo(PaymentInfoEvent curEvent) {
-            log.debug(String.format("Got event PaymentInfo token = %s ", curEvent.getUserToken()));  
+            log.info(String.format("Got event PaymentInfo token = %s ", curEvent.getUserToken()));  
             notifyForCompletion();
         }
+
         @Override
         public void onPaymentError(PaymentErrorEvent curEvent) {
-            log.debug(String.format("Got event PaymentError token = %s ", curEvent.getUserToken())); 
+            log.info(String.format("Got event PaymentError token = %s ", curEvent.getUserToken())); 
             notifyForCompletion();
         }
     }
 
     private interface SubscriptionCallCompletionCallback<T> {
         public T doOperation(final CallContext ctx) throws EntitlementUserApiException, InterruptedException, TimeoutException;
+
         public boolean isImmOperation();
+
         public Response doResponseOk(final T operationResponse);
     }
 
@@ -326,13 +338,13 @@ public class SubscriptionResource extends JaxRsResourceBase {
                 final String reason,
                 final String comment) {
 
-            CallContext ctx = context.createContext(createdBy, reason, comment);
-            CompletionUserRequestSubscription waiter = callCompletion ? new CompletionUserRequestSubscription(ctx.getUserToken()) : null; 
+            final CallContext ctx = context.createContext(createdBy, reason, comment);
+            final CompletionUserRequestSubscription waiter = callCompletion ? new CompletionUserRequestSubscription(ctx.getUserToken()) : null;
             try {
                 if (waiter != null) {
-                    killbillHandler.registerCompletionUserRequestWaiter(waiter);    
+                    killbillHandler.registerCompletionUserRequestWaiter(waiter);
                 }
-                T operationValue = callback.doOperation(ctx);
+                final T operationValue = callback.doOperation(ctx);
                 if (waiter != null && callback.isImmOperation()) {
                     waiter.waitForCompletion(timeoutSec * 1000);
                 }
@@ -343,10 +355,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
             } catch (InterruptedException e) {
                 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
             } catch (TimeoutException e) {
-                return Response.status(Status.fromStatusCode(408)).build();   
+                return Response.status(Status.fromStatusCode(408)).build();
             } finally {
                 if (waiter != null) {
-                    killbillHandler.unregisterCompletionUserRequestWaiter(waiter);              
+                    killbillHandler.unregisterCompletionUserRequestWaiter(waiter);
                 }
             }
         }
@@ -388,7 +400,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
     @GET
     @Path(TAG_URI)
     @Produces(APPLICATION_JSON)
-    public Response getTags(@PathParam(ID_PARAM_NAME) String id) {
+    public Response getTags(@PathParam(ID_PARAM_NAME) final String id) {
         return super.getTags(UUID.fromString(id));
     }
 
@@ -402,7 +414,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
             @HeaderParam(HDR_REASON) final String reason,
             @HeaderParam(HDR_COMMENT) final String comment) {
         return super.createTags(UUID.fromString(id), tagList,
-                                context.createContext(createdBy, reason, comment));
+                context.createContext(createdBy, reason, comment));
     }
 
     @DELETE
@@ -416,7 +428,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
             @HeaderParam(HDR_COMMENT) final String comment) {
 
         return super.deleteTags(UUID.fromString(id), tagList,
-                                context.createContext(createdBy, reason, comment));
+                context.createContext(createdBy, reason, comment));
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
index 0e3853c..ecb7242 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import java.util.LinkedList;
-import java.util.List;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -31,6 +26,8 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
+import java.util.LinkedList;
+import java.util.List;
 
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -41,77 +38,78 @@ import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.tag.TagDefinition;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
 @Singleton
 @Path(JaxrsResource.TAG_DEFINITIONS_PATH)
 public class TagResource implements JaxrsResource {
-    
+
     private final TagUserApi tagUserApi;
     private final Context context;
     private final JaxrsUriBuilder uriBuilder;
-    
+
     @Inject
-    public TagResource(TagUserApi tagUserApi, final JaxrsUriBuilder uriBuilder, final Context context) {
+    public TagResource(final TagUserApi tagUserApi, final JaxrsUriBuilder uriBuilder, final Context context) {
         this.tagUserApi = tagUserApi;
         this.context = context;
         this.uriBuilder = uriBuilder;
     }
-    
+
     @GET
     @Produces(APPLICATION_JSON)
     public Response getTagDefinitions() {
-        
-        List<TagDefinitionJson> result = new LinkedList<TagDefinitionJson>();
-        List<TagDefinition> tagDefinitions = tagUserApi.getTagDefinitions();
-        for (TagDefinition cur : tagDefinitions) {
+
+        final List<TagDefinitionJson> result = new LinkedList<TagDefinitionJson>();
+        final List<TagDefinition> tagDefinitions = tagUserApi.getTagDefinitions();
+        for (final TagDefinition cur : tagDefinitions) {
             result.add(new TagDefinitionJson(cur.getName(), cur.getDescription()));
         }
         return Response.status(Status.OK).entity(result).build();
     }
-    
+
     @GET
     @Path("/{tagDefinitionName:" + STRING_PATTERN + "}")
     @Produces(APPLICATION_JSON)
     public Response getTagDefinition(@PathParam("tagDefinitionName") final String tagDefName) {
         try {
-            TagDefinition tagDef = tagUserApi.getTagDefinition(tagDefName);
-            TagDefinitionJson json = new TagDefinitionJson(tagDef.getName(), tagDef.getDescription());
+            final TagDefinition tagDef = tagUserApi.getTagDefinition(tagDefName);
+            final TagDefinitionJson json = new TagDefinitionJson(tagDef.getName(), tagDef.getDescription());
             return Response.status(Status.OK).entity(json).build();
         } catch (TagDefinitionApiException e) {
-            return Response.status(Status.NO_CONTENT).build(); 
+            return Response.status(Status.NO_CONTENT).build();
         }
     }
 
 
-
     @POST
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createTagDefinition(final TagDefinitionJson json,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                        @HeaderParam(HDR_REASON) final String reason,
+                                        @HeaderParam(HDR_COMMENT) final String comment) {
         try {
-            TagDefinition createdTagDef =  tagUserApi.create(json.getName(), json.getDescription(), context.createContext(createdBy, reason, comment));
+            final TagDefinition createdTagDef = tagUserApi.create(json.getName(), json.getDescription(), context.createContext(createdBy, reason, comment));
             return uriBuilder.buildResponse(TagResource.class, "getTagDefinition", createdTagDef.getName());
         } catch (TagDefinitionApiException e) {
-            return Response.status(Status.NO_CONTENT).build(); 
+            return Response.status(Status.NO_CONTENT).build();
         } catch (IllegalArgumentException e) {
             return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
         }
     }
-    
+
     @DELETE
     @Path("/{tagDefinitionName:" + STRING_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response deleteTagDefinition(@PathParam("tagDefinitionName") String tagDefName,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment) {
+    public Response deleteTagDefinition(@PathParam("tagDefinitionName") final String tagDefName,
+                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                        @HeaderParam(HDR_REASON) final String reason,
+                                        @HeaderParam(HDR_COMMENT) final String comment) {
         try {
             tagUserApi.deleteTagDefinition(tagDefName, context.createContext(createdBy, reason, comment));
             return Response.status(Status.NO_CONTENT).build();
         } catch (TagDefinitionApiException e) {
-            return Response.status(Status.NO_CONTENT).build(); 
+            return Response.status(Status.NO_CONTENT).build();
         } catch (IllegalArgumentException e) {
             return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
         }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
index c49616b..ea453a0 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/Context.java
@@ -40,7 +40,7 @@ public class Context {
     }
 
     public CallContext createContext(final String createdBy, final String reason, final String comment)
-    throws IllegalArgumentException {
+            throws IllegalArgumentException {
         try {
             Preconditions.checkNotNull(createdBy, String.format("Header %s needs to be set", JaxrsResource.HDR_CREATED_BY));
             return contextFactory.createCallContext(createdBy, origin, userType, reason, comment, UUID.randomUUID());
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java
index c291d95..8cdf084 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java
@@ -15,18 +15,17 @@
  */
 package com.ning.billing.jaxrs.util;
 
-import java.net.URI;
-
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
+import java.net.URI;
 
 import com.ning.billing.jaxrs.resources.JaxrsResource;
 
 public class JaxrsUriBuilder {
 
     public Response buildResponse(final Class<? extends JaxrsResource> theClass, final String getMethodName, final Object objectId) {
-        URI uri = UriBuilder.fromPath(objectId.toString()).build();
-        Response.ResponseBuilder ri = Response.created(uri);
+        final URI uri = UriBuilder.fromPath(objectId.toString()).build();
+        final Response.ResponseBuilder ri = Response.created(uri);
         return ri.entity(new Object() {
             @SuppressWarnings(value = "all")
             public URI getUri() {
@@ -36,19 +35,19 @@ public class JaxrsUriBuilder {
         }).build();
     }
 
-	
-    public Response buildResponse(final Class<? extends JaxrsResource> theClass, final String getMethodName, final Object objectId, String baseUri) {
-        
+
+    public Response buildResponse(final Class<? extends JaxrsResource> theClass, final String getMethodName, final Object objectId, final String baseUri) {
+
         // Let's build a n absolute location for cross resources
         // See Jersey ContainerResponse.setHeaders
-        StringBuilder tmp  = new StringBuilder(baseUri.substring(0, baseUri.length() - 1));
+        final StringBuilder tmp = new StringBuilder(baseUri.substring(0, baseUri.length() - 1));
         tmp.append(UriBuilder.fromResource(theClass).path(theClass, getMethodName).build(objectId).toString());
         final URI newUriFromResource = UriBuilder.fromUri(tmp.toString()).build();
-        Response.ResponseBuilder ri = Response.created(newUriFromResource);
+        final Response.ResponseBuilder ri = Response.created(newUriFromResource);
         return ri.entity(new Object() {
             @SuppressWarnings(value = "all")
             public URI getUri() {
-                
+
                 return newUriFromResource;
             }
         }).build();
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/KillbillEventHandler.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/KillbillEventHandler.java
index dc18416..a16694e 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/KillbillEventHandler.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/KillbillEventHandler.java
@@ -25,45 +25,45 @@ import com.ning.billing.util.userrequest.CompletionUserRequest;
 import com.ning.billing.util.userrequest.CompletionUserRequestNotifier;
 
 public class KillbillEventHandler {
-    
-    
+
+
     private final List<CompletionUserRequest> activeWaiters;
-    
+
     public KillbillEventHandler() {
         activeWaiters = new LinkedList<CompletionUserRequest>();
     }
-    
+
     public void registerCompletionUserRequestWaiter(final CompletionUserRequest waiter) {
         if (waiter == null) {
             return;
         }
-        synchronized(activeWaiters) {
+        synchronized (activeWaiters) {
             activeWaiters.add(waiter);
         }
     }
-    
+
     public void unregisterCompletionUserRequestWaiter(final CompletionUserRequest waiter) {
         if (waiter == null) {
             return;
         }
-        synchronized(activeWaiters) {
+        synchronized (activeWaiters) {
             activeWaiters.remove(waiter);
         }
     }
-    
+
     /*
-     * IRS event handler for killbill entitlement events
+     * Killbill server event handler
      */
     @Subscribe
     public void handleEntitlementevents(final BusEvent event) {
-        List<CompletionUserRequestNotifier> runningWaiters = new ArrayList<CompletionUserRequestNotifier>();
-        synchronized(activeWaiters) {
+        final List<CompletionUserRequestNotifier> runningWaiters = new ArrayList<CompletionUserRequestNotifier>();
+        synchronized (activeWaiters) {
             runningWaiters.addAll(activeWaiters);
         }
         if (runningWaiters.size() == 0) {
             return;
         }
-        for (CompletionUserRequestNotifier cur : runningWaiters) {
+        for (final CompletionUserRequestNotifier cur : runningWaiters) {
             cur.onBusEvent(event);
         }
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/TagHelper.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/TagHelper.java
index b7ecbd8..d3e9519 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/TagHelper.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/TagHelper.java
@@ -27,17 +27,17 @@ import com.ning.billing.util.tag.TagDefinition;
 public class TagHelper {
 
     private final TagUserApi tagUserApi;
-    
+
     @Inject
     public TagHelper(final TagUserApi tagUserApi) {
         this.tagUserApi = tagUserApi;
     }
-    
+
     public List<TagDefinition> getTagDefinitionFromTagList(final String tagList) throws TagDefinitionApiException {
-        List<TagDefinition> result = new LinkedList<TagDefinition>();
-        String [] tagParts = tagList.split(",\\s*");
-        for (String cur : tagParts) {
-            TagDefinition curDef = tagUserApi.getTagDefinition(cur);
+        final List<TagDefinition> result = new LinkedList<TagDefinition>();
+        final String[] tagParts = tagList.split(",\\s*");
+        for (final String cur : tagParts) {
+            final TagDefinition curDef = tagUserApi.getTagDefinition(cur);
             // Yack should throw exception
             if (curDef == null) {
                 throw new TagDefinitionApiException(ErrorCode.TAG_DEFINITION_DOES_NOT_EXIST, cur);
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountEmailJson.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountEmailJson.java
new file mode 100644
index 0000000..c9e55f8
--- /dev/null
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountEmailJson.java
@@ -0,0 +1,60 @@
+/*
+ * 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.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ning.billing.account.api.AccountEmail;
+
+public class TestAccountEmailJson {
+    private static final ObjectMapper mapper = new ObjectMapper();
+
+    @Test(groups = "fast")
+    public void testJson() throws Exception {
+        final String accountId = UUID.randomUUID().toString();
+        final String email = UUID.randomUUID().toString();
+
+        final AccountEmailJson accountEmailJson = new AccountEmailJson(accountId, email);
+        Assert.assertEquals(accountEmailJson.getAccountId(), accountId);
+        Assert.assertEquals(accountEmailJson.getEmail(), email);
+
+        final String asJson = mapper.writeValueAsString(accountEmailJson);
+        Assert.assertEquals(asJson, "{\"accountId\":\"" + accountId + "\"," +
+                "\"email\":\"" + email + "\"}");
+
+        final AccountEmailJson fromJson = mapper.readValue(asJson, AccountEmailJson.class);
+        Assert.assertEquals(fromJson, accountEmailJson);
+    }
+
+    @Test(groups = "fast")
+    public void testToAccountEmail() throws Exception {
+        final String accountId = UUID.randomUUID().toString();
+        final String email = UUID.randomUUID().toString();
+
+        final AccountEmailJson accountEmailJson = new AccountEmailJson(accountId, email);
+        Assert.assertEquals(accountEmailJson.getAccountId(), accountId);
+        Assert.assertEquals(accountEmailJson.getEmail(), email);
+
+        final AccountEmail accountEmail = accountEmailJson.toAccountEmail();
+        Assert.assertEquals(accountEmail.getAccountId().toString(), accountId);
+        Assert.assertEquals(accountEmail.getEmail(), email);
+    }
+}
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountJsonSimple.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountJsonSimple.java
index 99ff73b..386d7cd 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountJsonSimple.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountJsonSimple.java
@@ -15,11 +15,12 @@
  */
 package com.ning.billing.jaxrs.json;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.UUID;
+
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import java.util.UUID;
+import com.fasterxml.jackson.databind.ObjectMapper;
 
 public class TestAccountJsonSimple {
     private static final ObjectMapper mapper = new ObjectMapper();
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 874cd8c..8e6f306 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
@@ -154,7 +154,7 @@ public class TestBundleTimelineJson {
         final String currency = "USD";
         final String status = UUID.randomUUID().toString();
 
-        
+
         return new PaymentJsonSimple(amount, paidAmount, accountId.toString(), invoiceId.toString(), paymentId.toString(),
                                      paymentRequestedDate, paymentEffectiveDate, retryCount,
                                      currency, status);
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceEmailJson.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceEmailJson.java
new file mode 100644
index 0000000..c859596
--- /dev/null
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceEmailJson.java
@@ -0,0 +1,45 @@
+/*
+ * 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.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class TestInvoiceEmailJson {
+    private static final ObjectMapper mapper = new ObjectMapper();
+
+    @Test(groups = "fast")
+    public void testJson() throws Exception {
+        final String accountId = UUID.randomUUID().toString();
+        final boolean isNotifiedForInvoices = true;
+
+        final InvoiceEmailJson invoiceEmailJson = new InvoiceEmailJson(accountId, isNotifiedForInvoices);
+        Assert.assertEquals(invoiceEmailJson.getAccountId(), accountId);
+        Assert.assertEquals(invoiceEmailJson.isNotifiedForInvoices(), isNotifiedForInvoices);
+
+        final String asJson = mapper.writeValueAsString(invoiceEmailJson);
+        Assert.assertEquals(asJson, "{\"accountId\":\"" + accountId + "\"," +
+                "\"isNotifiedForInvoices\":" + isNotifiedForInvoices + "}");
+
+        final InvoiceEmailJson fromJson = mapper.readValue(asJson, InvoiceEmailJson.class);
+        Assert.assertEquals(fromJson, invoiceEmailJson);
+    }
+}

junction/pom.xml 15(+7 -8)

diff --git a/junction/pom.xml b/junction/pom.xml
index 1824a28..cc01087 100644
--- a/junction/pom.xml
+++ b/junction/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-junction</artifactId>
@@ -28,7 +28,7 @@
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-util</artifactId>
         </dependency>
-         <dependency>
+        <dependency>
             <groupId>com.google.inject</groupId>
             <artifactId>guice</artifactId>
             <scope>provided</scope>
@@ -41,7 +41,7 @@
             <groupId>joda-time</groupId>
             <artifactId>joda-time</artifactId>
         </dependency>
-         <dependency>
+        <dependency>
             <groupId>org.jdbi</groupId>
             <artifactId>jdbi</artifactId>
         </dependency>
@@ -50,12 +50,12 @@
             <artifactId>testng</artifactId>
             <scope>test</scope>
         </dependency>
+        <!-- TEST SCOPE -->
         <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
             <scope>test</scope>
         </dependency>
-        <!-- TEST SCOPE -->
         <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-util</artifactId>
@@ -78,7 +78,7 @@
             <artifactId>mockito-all</artifactId>
             <scope>test</scope>
         </dependency>
-         <dependency>
+        <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <scope>runtime</scope>
@@ -99,7 +99,6 @@
             <artifactId>guava</artifactId>
            <scope>test</scope>
          </dependency>
- 
     </dependencies>
     <build>
         <plugins>
diff --git a/junction/src/main/java/com/ning/billing/junction/api/blocking/DefaultBlockingApi.java b/junction/src/main/java/com/ning/billing/junction/api/blocking/DefaultBlockingApi.java
index 904d303..0c74ffd 100644
--- a/junction/src/main/java/com/ning/billing/junction/api/blocking/DefaultBlockingApi.java
+++ b/junction/src/main/java/com/ning/billing/junction/api/blocking/DefaultBlockingApi.java
@@ -28,44 +28,44 @@ import com.ning.billing.junction.dao.BlockingStateDao;
 import com.ning.billing.util.clock.Clock;
 
 public class DefaultBlockingApi implements BlockingApi {
-    private BlockingStateDao dao;
-    private Clock clock;
+    private final BlockingStateDao dao;
+    private final Clock clock;
 
     @Inject
-    public DefaultBlockingApi(BlockingStateDao dao, Clock clock) {
+    public DefaultBlockingApi(final BlockingStateDao dao, final Clock clock) {
         this.dao = dao;
         this.clock = clock;
     }
-    
+
     @Override
-    public BlockingState getBlockingStateFor(Blockable overdueable) {
+    public BlockingState getBlockingStateFor(final Blockable overdueable) {
         BlockingState state = dao.getBlockingStateFor(overdueable);
-        if(state == null) {
+        if (state == null) {
             state = DefaultBlockingState.getClearState();
         }
         return state;
-        
+
     }
 
     @Override
-    public BlockingState getBlockingStateFor(UUID overdueableId) {
+    public BlockingState getBlockingStateFor(final UUID overdueableId) {
         return dao.getBlockingStateFor(overdueableId);
     }
 
     @Override
-    public SortedSet<BlockingState> getBlockingHistory(Blockable overdueable) {
-        return dao.getBlockingHistoryFor(overdueable); 
+    public SortedSet<BlockingState> getBlockingHistory(final Blockable overdueable) {
+        return dao.getBlockingHistoryFor(overdueable);
     }
 
     @Override
-    public SortedSet<BlockingState> getBlockingHistory(UUID overdueableId) {
+    public SortedSet<BlockingState> getBlockingHistory(final UUID overdueableId) {
         return dao.getBlockingHistoryFor(overdueableId);
     }
 
     @Override
-    public <T extends Blockable> void setBlockingState(BlockingState state) {
-       dao.setBlockingState(state, clock);
-        
+    public <T extends Blockable> void setBlockingState(final BlockingState state) {
+        dao.setBlockingState(state, clock);
+
     }
 
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/block/BlockingChecker.java b/junction/src/main/java/com/ning/billing/junction/block/BlockingChecker.java
index 04d68f0..e67560d 100644
--- a/junction/src/main/java/com/ning/billing/junction/block/BlockingChecker.java
+++ b/junction/src/main/java/com/ning/billing/junction/block/BlockingChecker.java
@@ -23,11 +23,11 @@ import com.ning.billing.junction.api.BlockingApiException;
 
 public interface BlockingChecker {
 
-    public void checkBlockedChange(Blockable blockable)  throws BlockingApiException;
+    public void checkBlockedChange(Blockable blockable) throws BlockingApiException;
 
-    public void checkBlockedEntitlement(Blockable blockable)  throws BlockingApiException;
+    public void checkBlockedEntitlement(Blockable blockable) throws BlockingApiException;
 
-    public void checkBlockedBilling(Blockable blockable)  throws BlockingApiException;
+    public void checkBlockedBilling(Blockable blockable) throws BlockingApiException;
 
     public void checkBlockedChange(UUID bundleId, Blockable.Type type) throws BlockingApiException;
 
diff --git a/junction/src/main/java/com/ning/billing/junction/block/DefaultBlockingChecker.java b/junction/src/main/java/com/ning/billing/junction/block/DefaultBlockingChecker.java
index 8becce5..5bfb8de 100644
--- a/junction/src/main/java/com/ning/billing/junction/block/DefaultBlockingChecker.java
+++ b/junction/src/main/java/com/ning/billing/junction/block/DefaultBlockingChecker.java
@@ -34,18 +34,22 @@ public class DefaultBlockingChecker implements BlockingChecker {
 
     private static class BlockingAggregator {
         private boolean blockChange = false;
-        private boolean blockEntitlement= false;
+        private boolean blockEntitlement = false;
         private boolean blockBilling = false;
 
-        public void or(BlockingState state) {
-            if (state == null) { return; }
+        public void or(final BlockingState state) {
+            if (state == null) {
+                return;
+            }
             blockChange = blockChange || state.isBlockChange();
             blockEntitlement = blockEntitlement || state.isBlockEntitlement();
             blockBilling = blockBilling || state.isBlockBilling();
         }
 
-        public void or(BlockingAggregator state) {
-            if (state == null) { return; }
+        public void or(final BlockingAggregator state) {
+            if (state == null) {
+                return;
+            }
             blockChange = blockChange || state.isBlockChange();
             blockEntitlement = blockEntitlement || state.isBlockEntitlement();
             blockBilling = blockBilling || state.isBlockBilling();
@@ -54,9 +58,11 @@ public class DefaultBlockingChecker implements BlockingChecker {
         public boolean isBlockChange() {
             return blockChange;
         }
+
         public boolean isBlockEntitlement() {
             return blockEntitlement;
         }
+
         public boolean isBlockBilling() {
             return blockBilling;
         }
@@ -75,68 +81,69 @@ public class DefaultBlockingChecker implements BlockingChecker {
     private final BlockingStateDao dao;
 
     @Inject
-    public DefaultBlockingChecker(EntitlementUserApi entitlementApi, BlockingStateDao dao) {
+    public DefaultBlockingChecker(final EntitlementUserApi entitlementApi, final BlockingStateDao dao) {
         this.entitlementApi = entitlementApi;
         this.dao = dao;
     }
 
-    public BlockingAggregator getBlockedStateSubscriptionId(UUID subscriptionId) throws EntitlementUserApiException  {
-        Subscription subscription = entitlementApi.getSubscriptionFromId(subscriptionId);
+    public BlockingAggregator getBlockedStateSubscriptionId(final UUID subscriptionId) throws EntitlementUserApiException {
+        final Subscription subscription = entitlementApi.getSubscriptionFromId(subscriptionId);
         return getBlockedStateSubscription(subscription);
     }
 
-    public BlockingAggregator getBlockedStateSubscription(Subscription subscription) throws EntitlementUserApiException  {
-        BlockingAggregator result = new BlockingAggregator();
-        if(subscription != null) {
-            BlockingState subscriptionState = subscription.getBlockingState();
-            if(subscriptionState != null) {
+    public BlockingAggregator getBlockedStateSubscription(final Subscription subscription) throws EntitlementUserApiException {
+        final BlockingAggregator result = new BlockingAggregator();
+        if (subscription != null) {
+            final BlockingState subscriptionState = subscription.getBlockingState();
+            if (subscriptionState != null) {
                 result.or(subscriptionState);
             }
-            if(subscription.getBundleId() != null) {
+            if (subscription.getBundleId() != null) {
                 result.or(getBlockedStateBundleId(subscription.getBundleId()));
-            } 
+            }
         }
         return result;
     }
 
-    public BlockingAggregator getBlockedStateBundleId(UUID bundleId) throws EntitlementUserApiException  {
-        SubscriptionBundle bundle = entitlementApi.getBundleFromId(bundleId);
+    public BlockingAggregator getBlockedStateBundleId(final UUID bundleId) throws EntitlementUserApiException {
+        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(bundleId);
         return getBlockedStateBundle(bundle);
     }
 
-    public BlockingAggregator getBlockedStateBundle(SubscriptionBundle bundle)  {
-        BlockingAggregator result = getBlockedStateAccountId(bundle.getAccountId());
-        BlockingState bundleState = bundle.getBlockingState();
-        if(bundleState != null) {
+    public BlockingAggregator getBlockedStateBundle(final SubscriptionBundle bundle) {
+        final BlockingAggregator result = getBlockedStateAccountId(bundle.getAccountId());
+        final BlockingState bundleState = bundle.getBlockingState();
+        if (bundleState != null) {
             result.or(bundleState);
         }
         return result;
     }
 
-    public BlockingAggregator getBlockedStateAccountId(UUID accountId)  {
-        BlockingAggregator result = new BlockingAggregator();
-        if(accountId != null) {
-            BlockingState accountState = dao.getBlockingStateFor(accountId);
+    public BlockingAggregator getBlockedStateAccountId(final UUID accountId) {
+        final BlockingAggregator result = new BlockingAggregator();
+        if (accountId != null) {
+            final BlockingState accountState = dao.getBlockingStateFor(accountId);
             result.or(accountState);
         }
         return result;
     }
 
-    public BlockingAggregator getBlockedStateAccount(Account account)  {
-        if(account != null) {
+    public BlockingAggregator getBlockedStateAccount(final Account account) {
+        if (account != null) {
             return getBlockedStateAccountId(account.getId());
         }
         return new BlockingAggregator();
     }
+
     @Override
-    public void checkBlockedChange(Blockable blockable) throws BlockingApiException  {
+    public void checkBlockedChange(final Blockable blockable) throws BlockingApiException {
         try {
-            if(blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable).isBlockChange()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_CHANGE, TYPE_SUBSCRIPTION, blockable.getId().toString());
-            } else if(blockable instanceof SubscriptionBundle &&  getBlockedStateBundle((SubscriptionBundle) blockable).isBlockChange()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_CHANGE, TYPE_BUNDLE, blockable.getId().toString());
-            } else if(blockable instanceof Account && getBlockedStateAccount((Account) blockable).isBlockChange()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_CHANGE, TYPE_ACCOUNT, blockable.getId().toString());
+            if (blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable).isBlockChange()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_SUBSCRIPTION, blockable.getId().toString());
+            } else if (blockable instanceof SubscriptionBundle && getBlockedStateBundle((SubscriptionBundle) blockable).isBlockChange()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_BUNDLE, blockable.getId().toString());
+            } else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable).isBlockChange()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_ACCOUNT, blockable.getId().toString());
             }
         } catch (EntitlementUserApiException e) {
             throw new BlockingApiException(e, ErrorCode.values()[e.getCode()]);
@@ -144,14 +151,14 @@ public class DefaultBlockingChecker implements BlockingChecker {
     }
 
     @Override
-    public void checkBlockedEntitlement(Blockable blockable) throws BlockingApiException  {
+    public void checkBlockedEntitlement(final Blockable blockable) throws BlockingApiException {
         try {
-            if(blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable).isBlockEntitlement()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_ENTITLEMENT, TYPE_SUBSCRIPTION, blockable.getId().toString());
-            } else if(blockable instanceof SubscriptionBundle &&  getBlockedStateBundle((SubscriptionBundle) blockable).isBlockEntitlement()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_ENTITLEMENT, TYPE_BUNDLE, blockable.getId().toString());
-            } else if(blockable instanceof Account && getBlockedStateAccount((Account) blockable).isBlockEntitlement()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_ENTITLEMENT, TYPE_ACCOUNT, blockable.getId().toString());
+            if (blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable).isBlockEntitlement()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_SUBSCRIPTION, blockable.getId().toString());
+            } else if (blockable instanceof SubscriptionBundle && getBlockedStateBundle((SubscriptionBundle) blockable).isBlockEntitlement()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_BUNDLE, blockable.getId().toString());
+            } else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable).isBlockEntitlement()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_ACCOUNT, blockable.getId().toString());
             }
         } catch (EntitlementUserApiException e) {
             throw new BlockingApiException(e, ErrorCode.values()[e.getCode()]);
@@ -159,14 +166,14 @@ public class DefaultBlockingChecker implements BlockingChecker {
     }
 
     @Override
-    public void checkBlockedBilling(Blockable blockable) throws BlockingApiException  {
+    public void checkBlockedBilling(final Blockable blockable) throws BlockingApiException {
         try {
-            if(blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable).isBlockBilling()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_BILLING, TYPE_SUBSCRIPTION, blockable.getId().toString());
-            } else if(blockable instanceof SubscriptionBundle &&  getBlockedStateBundle((SubscriptionBundle) blockable).isBlockBilling()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_BILLING, TYPE_BUNDLE, blockable.getId().toString());
-            } else if(blockable instanceof Account && getBlockedStateAccount((Account) blockable).isBlockBilling()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_BILLING, TYPE_ACCOUNT, blockable.getId().toString());
+            if (blockable instanceof Subscription && getBlockedStateSubscription((Subscription) blockable).isBlockBilling()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_SUBSCRIPTION, blockable.getId().toString());
+            } else if (blockable instanceof SubscriptionBundle && getBlockedStateBundle((SubscriptionBundle) blockable).isBlockBilling()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_BUNDLE, blockable.getId().toString());
+            } else if (blockable instanceof Account && getBlockedStateAccount((Account) blockable).isBlockBilling()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_ACCOUNT, blockable.getId().toString());
             }
         } catch (EntitlementUserApiException e) {
             throw new BlockingApiException(e, ErrorCode.values()[e.getCode()]);
@@ -175,30 +182,30 @@ public class DefaultBlockingChecker implements BlockingChecker {
 
 
     @Override
-    public void checkBlockedChange(UUID blockableId, Blockable.Type type) throws BlockingApiException  {
+    public void checkBlockedChange(final UUID blockableId, final Blockable.Type type) throws BlockingApiException {
         try {
-            if(type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId).isBlockChange()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_CHANGE, TYPE_SUBSCRIPTION, blockableId.toString());
-            } else if(type == Blockable.Type.SUBSCRIPTION_BUNDLE  &&  getBlockedStateBundleId(blockableId).isBlockChange()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_CHANGE, TYPE_BUNDLE, blockableId.toString());
-            } else if(type == Blockable.Type.ACCOUNT  && getBlockedStateAccountId(blockableId).isBlockChange()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_CHANGE, TYPE_ACCOUNT, blockableId.toString());
-
-            } 
+            if (type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId).isBlockChange()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_SUBSCRIPTION, blockableId.toString());
+            } else if (type == Blockable.Type.SUBSCRIPTION_BUNDLE && getBlockedStateBundleId(blockableId).isBlockChange()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_BUNDLE, blockableId.toString());
+            } else if (type == Blockable.Type.ACCOUNT && getBlockedStateAccountId(blockableId).isBlockChange()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_CHANGE, TYPE_ACCOUNT, blockableId.toString());
+
+            }
         } catch (EntitlementUserApiException e) {
             throw new BlockingApiException(e, ErrorCode.values()[e.getCode()]);
         }
     }
 
     @Override
-    public void checkBlockedEntitlement(UUID blockableId, Blockable.Type type) throws BlockingApiException  {
+    public void checkBlockedEntitlement(final UUID blockableId, final Blockable.Type type) throws BlockingApiException {
         try {
-            if(type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId).isBlockEntitlement()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_ENTITLEMENT, TYPE_SUBSCRIPTION, blockableId.toString());
-            } else if(type == Blockable.Type.SUBSCRIPTION_BUNDLE  &&  getBlockedStateBundleId(blockableId).isBlockEntitlement()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_ENTITLEMENT, TYPE_BUNDLE, blockableId.toString());
-            } else if(type == Blockable.Type.ACCOUNT  && getBlockedStateAccountId(blockableId).isBlockEntitlement()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_ENTITLEMENT, TYPE_ACCOUNT, blockableId.toString());
+            if (type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId).isBlockEntitlement()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_SUBSCRIPTION, blockableId.toString());
+            } else if (type == Blockable.Type.SUBSCRIPTION_BUNDLE && getBlockedStateBundleId(blockableId).isBlockEntitlement()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_BUNDLE, blockableId.toString());
+            } else if (type == Blockable.Type.ACCOUNT && getBlockedStateAccountId(blockableId).isBlockEntitlement()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_ENTITLEMENT, TYPE_ACCOUNT, blockableId.toString());
             }
         } catch (EntitlementUserApiException e) {
             throw new BlockingApiException(e, ErrorCode.values()[e.getCode()]);
@@ -206,14 +213,14 @@ public class DefaultBlockingChecker implements BlockingChecker {
     }
 
     @Override
-    public void checkBlockedBilling(UUID blockableId, Blockable.Type type) throws BlockingApiException  {
+    public void checkBlockedBilling(final UUID blockableId, final Blockable.Type type) throws BlockingApiException {
         try {
-            if(type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId).isBlockBilling()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_BILLING, TYPE_SUBSCRIPTION, blockableId.toString());
-            } else if(type == Blockable.Type.SUBSCRIPTION_BUNDLE  &&  getBlockedStateBundleId(blockableId).isBlockBilling()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_BILLING, TYPE_BUNDLE, blockableId.toString());
-            } else if(type == Blockable.Type.ACCOUNT  && getBlockedStateAccountId(blockableId).isBlockBilling()) {
-                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION,ACTION_BILLING, TYPE_ACCOUNT, blockableId.toString());
+            if (type == Blockable.Type.SUBSCRIPTION && getBlockedStateSubscriptionId(blockableId).isBlockBilling()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_SUBSCRIPTION, blockableId.toString());
+            } else if (type == Blockable.Type.SUBSCRIPTION_BUNDLE && getBlockedStateBundleId(blockableId).isBlockBilling()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_BUNDLE, blockableId.toString());
+            } else if (type == Blockable.Type.ACCOUNT && getBlockedStateAccountId(blockableId).isBlockBilling()) {
+                throw new BlockingApiException(ErrorCode.BLOCK_BLOCKED_ACTION, ACTION_BILLING, TYPE_ACCOUNT, blockableId.toString());
             }
         } catch (EntitlementUserApiException e) {
             throw new BlockingApiException(e, ErrorCode.values()[e.getCode()]);
@@ -221,6 +228,4 @@ public class DefaultBlockingChecker implements BlockingChecker {
     }
 
 
-
-
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateDao.java b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateDao.java
index 6f5396d..b9f8510 100644
--- a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateDao.java
+++ b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateDao.java
@@ -20,7 +20,6 @@ import java.util.SortedSet;
 import java.util.UUID;
 
 import com.ning.billing.junction.api.Blockable;
-import com.ning.billing.junction.api.Blockable.Type;
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.util.clock.Clock;
 
@@ -36,6 +35,6 @@ public interface BlockingStateDao {
     public SortedSet<BlockingState> getBlockingHistoryFor(UUID blockableId);
 
     //Write
-    <T extends Blockable> void  setBlockingState(BlockingState state, Clock clock);
+    <T extends Blockable> void setBlockingState(BlockingState state, Clock clock);
 
-} 
\ No newline at end of file
+} 
diff --git a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java
index ba241a4..6383b9d 100644
--- a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java
+++ b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java
@@ -52,14 +52,14 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
     @SqlUpdate
     public abstract <T extends Blockable> void setBlockingState(
             @Bind(binder = BlockingStateBinder.class) BlockingState state,
-            @Bind(binder = CurrentTimeBinder.class) Clock clock) ;
+            @Bind(binder = CurrentTimeBinder.class) Clock clock);
 
 
     @Override
     @SqlQuery
     @Mapper(BlockingHistorySqlMapper.class)
-    public abstract BlockingState getBlockingStateFor(@Bind(binder = BlockableBinder.class)Blockable overdueable) ;
-    
+    public abstract BlockingState getBlockingStateFor(@Bind(binder = BlockableBinder.class) Blockable overdueable);
+
     @Override
     @SqlQuery
     @Mapper(BlockingHistorySqlMapper.class)
@@ -68,8 +68,8 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
     @Override
     @SqlQuery
     @Mapper(BlockingHistorySqlMapper.class)
-    public abstract SortedSet<BlockingState> getBlockingHistoryFor(@Bind(binder = BlockableBinder.class)Blockable blockable) ;
-    
+    public abstract SortedSet<BlockingState> getBlockingHistoryFor(@Bind(binder = BlockableBinder.class) Blockable blockable);
+
     @Override
     @SqlQuery
     @Mapper(BlockingHistorySqlMapper.class)
@@ -79,17 +79,17 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
     public class BlockingHistorySqlMapper extends MapperBase implements ResultSetMapper<BlockingState> {
 
         @Override
-        public BlockingState map(int index, ResultSet r, StatementContext ctx)
+        public BlockingState map(final int index, final ResultSet r, final StatementContext ctx)
                 throws SQLException {
-            
-            DateTime timestamp;
-            UUID blockableId;
-            String stateName;
-            String service;
-            boolean blockChange;
-            boolean blockEntitlement;
-            boolean blockBilling;
-            Type type;
+
+            final DateTime timestamp;
+            final UUID blockableId;
+            final String stateName;
+            final String service;
+            final boolean blockChange;
+            final boolean blockEntitlement;
+            final boolean blockBilling;
+            final Type type;
             try {
                 timestamp = new DateTime(r.getDate("created_date"));
                 blockableId = UUID.fromString(r.getString("id"));
@@ -103,22 +103,22 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
                 throw new SQLException(e);
             }
             return new DefaultBlockingState(blockableId, stateName, type, service, blockChange, blockEntitlement, blockBilling, timestamp);
-        }    
+        }
     }
-    
+
     public static class BlockingStateSqlMapper extends MapperBase implements ResultSetMapper<String> {
 
         @Override
-        public String map(int index, ResultSet r, StatementContext ctx)
+        public String map(final int index, final ResultSet r, final StatementContext ctx)
                 throws SQLException {
             return r.getString("state") == null ? BlockingApi.CLEAR_STATE_NAME : r.getString("state");
         }
     }
-    
+
     public static class BlockingStateBinder extends BinderBase implements Binder<Bind, DefaultBlockingState> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, DefaultBlockingState state) {
-            stmt.bind("id", state.getBlockedId().toString()); 
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final DefaultBlockingState state) {
+            stmt.bind("id", state.getBlockedId().toString());
             stmt.bind("state", state.getStateName().toString());
             stmt.bind("type", state.getType().toString());
             stmt.bind("service", state.getService().toString());
@@ -127,32 +127,32 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
             stmt.bind("block_billing", state.isBlockBilling());
         }
     }
-    
+
     public static class UUIDBinder extends BinderBase implements Binder<Bind, UUID> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, UUID id) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final UUID id) {
             stmt.bind("id", id.toString());
         }
     }
-    
+
     public static class BlockableBinder extends BinderBase implements Binder<Bind, Blockable> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, Blockable overdueable) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final Blockable overdueable) {
             stmt.bind("id", overdueable.getId().toString());
         }
     }
-    
+
     public static class OverdueStateBinder<T extends Blockable> extends BinderBase implements Binder<Bind, OverdueState<T>> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, OverdueState<T> overdueState) {
+        public void bind(final SQLStatement<?> stmt, final Bind bind, final OverdueState<T> overdueState) {
             stmt.bind("state", overdueState.getName());
         }
     }
-    
-    public class BlockableTypeBinder extends BinderBase implements Binder<Bind, Blockable.Type>{
+
+    public class BlockableTypeBinder extends BinderBase implements Binder<Bind, Blockable.Type> {
 
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, Type type) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final Type type) {
             stmt.bind("type", type.name());
         }
 
@@ -160,10 +160,10 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
 
     public static class CurrentTimeBinder extends BinderBase implements Binder<Bind, Clock> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, Clock clock) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final Clock clock) {
             stmt.bind("created_date", clock.getUTCNow().toDate());
         }
-        
+
     }
 
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/glue/DefaultJunctionModule.java b/junction/src/main/java/com/ning/billing/junction/glue/DefaultJunctionModule.java
index 0065ab3..b0d8fd8 100644
--- a/junction/src/main/java/com/ning/billing/junction/glue/DefaultJunctionModule.java
+++ b/junction/src/main/java/com/ning/billing/junction/glue/DefaultJunctionModule.java
@@ -46,52 +46,53 @@ public class DefaultJunctionModule extends AbstractModule implements JunctionMod
         installBillingApi();
         installEntitlementUserApi();
         installBlockingChecker();
-        
+
         // Internal
         installBlockingCalculator();
         installBlockingStateDao();
-     }
+    }
 
     public void installBlockingChecker() {
         bind(BlockingChecker.class).to(DefaultBlockingChecker.class).asEagerSingleton();
-        
+
     }
 
     public void installBillingApi() {
         bind(BillingApi.class).to(DefaultBillingApi.class).asEagerSingleton();
     }
-    
+
     public void installBlockingStateDao() {
         bind(BlockingStateDao.class).toProvider(BlockingDaoProvider.class);
     }
-    
+
     public void installAccountUserApi() {
         bind(AccountUserApi.class).to(BlockingAccountUserApi.class).asEagerSingleton();
     }
-    
+
     public void installEntitlementUserApi() {
         bind(EntitlementUserApi.class).to(BlockingEntitlementUserApi.class).asEagerSingleton();
     }
-    
+
     public void installBlockingApi() {
         bind(BlockingApi.class).to(DefaultBlockingApi.class).asEagerSingleton();
     }
-    
+
     public void installBlockingCalculator() {
         bind(BlockingCalculator.class).asEagerSingleton();
     }
 
-    public static class BlockingDaoProvider implements Provider<BlockingStateDao>{        
-        private IDBI dbi;
+    public static class BlockingDaoProvider implements Provider<BlockingStateDao> {
+        private final IDBI dbi;
 
 
         @Inject
-        public BlockingDaoProvider(IDBI dbi){
+        public BlockingDaoProvider(final IDBI dbi) {
             this.dbi = dbi;
         }
+
         @Override
         public BlockingStateDao get() {
             return dbi.onDemand(BlockingStateSqlDao.class);
-        }   
+        }
     }
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccount.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccount.java
index 2dfb4b4..40c713d 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccount.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccount.java
@@ -29,9 +29,9 @@ import com.ning.billing.junction.api.BlockingState;
 public class BlockingAccount implements Account {
     private final Account account;
     private BlockingState blockingState = null;
-    private BlockingApi blockingApi;
+    private final BlockingApi blockingApi;
 
-    public BlockingAccount( Account account, BlockingApi blockingApi) {
+    public BlockingAccount(final Account account, final BlockingApi blockingApi) {
         this.account = account;
         this.blockingApi = blockingApi;
     }
@@ -52,7 +52,7 @@ public class BlockingAccount implements Account {
     }
 
     @Override
-    public int getFirstNameLength() {
+    public Integer getFirstNameLength() {
         return account.getFirstNameLength();
     }
 
@@ -62,7 +62,7 @@ public class BlockingAccount implements Account {
     }
 
     @Override
-    public int getBillCycleDay() {
+    public Integer getBillCycleDay() {
         return account.getBillCycleDay();
     }
 
@@ -93,7 +93,7 @@ public class BlockingAccount implements Account {
 
     @Override
     public BlockingState getBlockingState() {
-        if(blockingState == null) {
+        if (blockingState == null) {
             blockingState = blockingApi.getBlockingStateFor(account);
         }
         return blockingState;
@@ -140,12 +140,17 @@ public class BlockingAccount implements Account {
     }
 
     @Override
-    public boolean isMigrated() {
+    public Boolean isMigrated() {
         return account.isMigrated();
     }
 
     @Override
-    public boolean isNotifiedForInvoices() {
+    public Boolean isNotifiedForInvoices() {
         return account.isNotifiedForInvoices();
     }
+
+    @Override
+    public Account mergeWithDelegate(final Account delegate) {
+        return account.mergeWithDelegate(delegate);
+    }
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccountUserApi.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccountUserApi.java
index 6a36e2f..e568b61 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccountUserApi.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingAccountUserApi.java
@@ -28,53 +28,51 @@ import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.account.api.MigrationAccountData;
 import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.customfield.CustomField;
 import com.ning.billing.util.glue.RealImplementation;
-import com.ning.billing.util.tag.TagDefinition;
 
-public class BlockingAccountUserApi implements AccountUserApi { 
-    private AccountUserApi userApi;
-    private BlockingApi blockingApi;
+public class BlockingAccountUserApi implements AccountUserApi {
+    private final AccountUserApi userApi;
+    private final BlockingApi blockingApi;
 
     @Inject
-    public BlockingAccountUserApi(@RealImplementation AccountUserApi userApi, BlockingApi blockingApi) {
+    public BlockingAccountUserApi(@RealImplementation final AccountUserApi userApi, final BlockingApi blockingApi) {
         this.userApi = userApi;
         this.blockingApi = blockingApi;
     }
 
     @Override
-    public Account createAccount(AccountData data, CallContext context)
+    public Account createAccount(final AccountData data, final CallContext context)
             throws AccountApiException {
         return userApi.createAccount(data, context);
     }
 
     @Override
-    public Account migrateAccount(MigrationAccountData data, CallContext context) throws AccountApiException {
+    public Account migrateAccount(final MigrationAccountData data, final CallContext context) throws AccountApiException {
         return userApi.migrateAccount(data, context);
     }
 
     @Override
-    public void updateAccount(Account account, CallContext context) throws AccountApiException {
+    public void updateAccount(final Account account, final CallContext context) throws AccountApiException {
         userApi.updateAccount(account, context);
     }
 
     @Override
-    public void updateAccount(String key, AccountData accountData, CallContext context) throws AccountApiException {
+    public void updateAccount(final String key, final AccountData accountData, final CallContext context) throws AccountApiException {
         userApi.updateAccount(key, accountData, context);
     }
 
     @Override
-    public void updateAccount(UUID accountId, AccountData accountData, CallContext context) throws AccountApiException {
+    public void updateAccount(final UUID accountId, final AccountData accountData, final CallContext context) throws AccountApiException {
         userApi.updateAccount(accountId, accountData, context);
     }
 
     @Override
-    public Account getAccountByKey(String key) throws AccountApiException {
+    public Account getAccountByKey(final String key) throws AccountApiException {
         return new BlockingAccount(userApi.getAccountByKey(key), blockingApi);
     }
 
     @Override
-    public Account getAccountById(UUID accountId) throws AccountApiException {
+    public Account getAccountById(final UUID accountId) throws AccountApiException {
         return userApi.getAccountById(accountId);
     }
 
@@ -84,18 +82,27 @@ public class BlockingAccountUserApi implements AccountUserApi {
     }
 
     @Override
-    public UUID getIdFromKey(String externalKey) throws AccountApiException {
+    public UUID getIdFromKey(final String externalKey) throws AccountApiException {
         return userApi.getIdFromKey(externalKey);
     }
 
     @Override
-    public List<AccountEmail> getEmails(UUID accountId) {
+    public List<AccountEmail> getEmails(final UUID accountId) {
         return userApi.getEmails(accountId);
     }
 
     @Override
-    public void saveEmails(UUID accountId, List<AccountEmail> emails, CallContext context) {
+    public void saveEmails(final UUID accountId, final List<AccountEmail> emails, final CallContext context) {
         userApi.saveEmails(accountId, emails, context);
     }
 
+    @Override
+    public void addEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+        userApi.addEmail(accountId, email, context);
+    }
+
+    @Override
+    public void removeEmail(final UUID accountId, final AccountEmail email, final CallContext context) {
+        userApi.removeEmail(accountId, email, context);
+    }
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java
index 9452146..0b15824 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingEntitlementUserApi.java
@@ -23,7 +23,6 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 
 import com.google.inject.Inject;
-import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
@@ -43,55 +42,55 @@ public class BlockingEntitlementUserApi implements EntitlementUserApi {
     private final BlockingChecker checker;
 
     @Inject
-    public BlockingEntitlementUserApi(@RealImplementation EntitlementUserApi userApi, BlockingApi blockingApi, BlockingChecker checker) {
+    public BlockingEntitlementUserApi(@RealImplementation final EntitlementUserApi userApi, final BlockingApi blockingApi, final BlockingChecker checker) {
         this.entitlementUserApi = userApi;
         this.blockingApi = blockingApi;
         this.checker = checker;
     }
 
     @Override
-    public SubscriptionBundle getBundleFromId(UUID id) throws EntitlementUserApiException {
-        SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(id);
+    public SubscriptionBundle getBundleFromId(final UUID id) throws EntitlementUserApiException {
+        final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(id);
         return new BlockingSubscriptionBundle(bundle, blockingApi);
     }
 
     @Override
-    public Subscription getSubscriptionFromId(UUID id) throws EntitlementUserApiException {
-        Subscription subscription = entitlementUserApi.getSubscriptionFromId(id);
+    public Subscription getSubscriptionFromId(final UUID id) throws EntitlementUserApiException {
+        final Subscription subscription = entitlementUserApi.getSubscriptionFromId(id);
         return new BlockingSubscription(subscription, blockingApi, checker);
     }
 
     @Override
-    public SubscriptionBundle getBundleForKey(String bundleKey) throws EntitlementUserApiException {
-        SubscriptionBundle bundle = entitlementUserApi.getBundleForKey(bundleKey);
+    public SubscriptionBundle getBundleForKey(final String bundleKey) throws EntitlementUserApiException {
+        final SubscriptionBundle bundle = entitlementUserApi.getBundleForKey(bundleKey);
         return new BlockingSubscriptionBundle(bundle, blockingApi);
     }
 
     @Override
-    public List<SubscriptionBundle> getBundlesForAccount(UUID accountId) {
-        List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>();
-        List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId);
-        for(SubscriptionBundle bundle : bundles) {
+    public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId) {
+        final List<SubscriptionBundle> result = new ArrayList<SubscriptionBundle>();
+        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId);
+        for (final SubscriptionBundle bundle : bundles) {
             result.add(new BlockingSubscriptionBundle(bundle, blockingApi));
         }
         return result;
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForBundle(UUID bundleId) {
-        List<Subscription> result = new ArrayList<Subscription>();
-        List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForBundle(bundleId);
-        for(Subscription subscription : subscriptions) {
+    public List<Subscription> getSubscriptionsForBundle(final UUID bundleId) {
+        final List<Subscription> result = new ArrayList<Subscription>();
+        final List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForBundle(bundleId);
+        for (final Subscription subscription : subscriptions) {
             result.add(new BlockingSubscription(subscription, blockingApi, checker));
         }
         return result;
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForKey(String bundleKey) {
-        List<Subscription> result = new ArrayList<Subscription>();
-        List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForKey(bundleKey);
-        for(Subscription subscription : subscriptions) {
+    public List<Subscription> getSubscriptionsForKey(final String bundleKey) {
+        final List<Subscription> result = new ArrayList<Subscription>();
+        final List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForKey(bundleKey);
+        for (final Subscription subscription : subscriptions) {
             result.add(new BlockingSubscription(subscription, blockingApi, checker));
         }
         return result;
@@ -99,40 +98,40 @@ public class BlockingEntitlementUserApi implements EntitlementUserApi {
 
     @Override
     public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(
-            UUID subscriptionId, String productName, DateTime requestedDate)
+            final UUID subscriptionId, final String productName, final DateTime requestedDate)
             throws EntitlementUserApiException {
         return entitlementUserApi.getDryRunChangePlanStatus(subscriptionId, productName, requestedDate);
     }
 
     @Override
-    public Subscription getBaseSubscription(UUID bundleId) throws EntitlementUserApiException {
+    public Subscription getBaseSubscription(final UUID bundleId) throws EntitlementUserApiException {
         return new BlockingSubscription(entitlementUserApi.getBaseSubscription(bundleId), blockingApi, checker);
     }
 
     @Override
-    public SubscriptionBundle createBundleForAccount(UUID accountId, String bundleKey, CallContext context)
-    throws EntitlementUserApiException {
+    public SubscriptionBundle createBundleForAccount(final UUID accountId, final String bundleKey, final CallContext context)
+            throws EntitlementUserApiException {
         try {
             checker.checkBlockedChange(accountId, Blockable.Type.ACCOUNT);
             return new BlockingSubscriptionBundle(entitlementUserApi.createBundleForAccount(accountId, bundleKey, context), blockingApi);
-        }catch (BlockingApiException e) {
+        } catch (BlockingApiException e) {
             throw new EntitlementUserApiException(e, e.getCode(), e.getMessage());
         }
     }
 
     @Override
-    public Subscription createSubscription(UUID bundleId, PlanPhaseSpecifier spec, DateTime requestedDate,
-            CallContext context) throws EntitlementUserApiException {
+    public Subscription createSubscription(final UUID bundleId, final PlanPhaseSpecifier spec, final DateTime requestedDate,
+                                           final CallContext context) throws EntitlementUserApiException {
         try {
             checker.checkBlockedChange(bundleId, Blockable.Type.SUBSCRIPTION_BUNDLE);
             return new BlockingSubscription(entitlementUserApi.createSubscription(bundleId, spec, requestedDate, context), blockingApi, checker);
-        }catch (BlockingApiException e) {
+        } catch (BlockingApiException e) {
             throw new EntitlementUserApiException(e, e.getCode(), e.getMessage());
         }
     }
 
     @Override
-    public DateTime getNextBillingDate(UUID account) {
+    public DateTime getNextBillingDate(final UUID account) {
         return entitlementUserApi.getNextBillingDate(account);
     }
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
index d2cc774..b602820 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscription.java
@@ -38,12 +38,12 @@ import com.ning.billing.util.callcontext.CallContext;
 
 public class BlockingSubscription implements Subscription {
     private final Subscription subscription;
-    private final BlockingApi blockingApi; 
+    private final BlockingApi blockingApi;
     private final BlockingChecker checker;
-    
+
     private BlockingState blockingState = null;
 
-    public BlockingSubscription(Subscription subscription, BlockingApi blockingApi, BlockingChecker checker) {
+    public BlockingSubscription(final Subscription subscription, final BlockingApi blockingApi, final BlockingChecker checker) {
         this.subscription = subscription;
         this.blockingApi = blockingApi;
         this.checker = checker;
@@ -53,25 +53,25 @@ public class BlockingSubscription implements Subscription {
         return subscription.getId();
     }
 
-    public boolean cancel(DateTime requestedDate, boolean eot, CallContext context) throws EntitlementUserApiException {
+    public boolean cancel(final DateTime requestedDate, final boolean eot, final CallContext context) throws EntitlementUserApiException {
         return subscription.cancel(requestedDate, eot, context);
     }
 
-    public boolean uncancel(CallContext context) throws EntitlementUserApiException {
+    public boolean uncancel(final CallContext context) throws EntitlementUserApiException {
         return subscription.uncancel(context);
     }
 
-    public boolean changePlan(String productName, BillingPeriod term, String planSet, DateTime requestedDate,
-            CallContext context) throws EntitlementUserApiException {
+    public boolean changePlan(final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate,
+                              final CallContext context) throws EntitlementUserApiException {
         try {
             checker.checkBlockedChange(this);
         } catch (BlockingApiException e) {
-            throw new EntitlementUserApiException(e, e.getCode(), e.getMessage()); 
+            throw new EntitlementUserApiException(e, e.getCode(), e.getMessage());
         }
         return subscription.changePlan(productName, term, planSet, requestedDate, context);
     }
 
-    public boolean recreate(PlanPhaseSpecifier spec, DateTime requestedDate, CallContext context)
+    public boolean recreate(final PlanPhaseSpecifier spec, final DateTime requestedDate, final CallContext context)
             throws EntitlementUserApiException {
         return subscription.recreate(spec, requestedDate, context);
     }
@@ -129,12 +129,12 @@ public class BlockingSubscription implements Subscription {
     }
 
     public BlockingState getBlockingState() {
-        if(blockingState == null) {
+        if (blockingState == null) {
             blockingState = blockingApi.getBlockingStateFor(this);
         }
         return blockingState;
     }
-    
+
     public Subscription getDelegateSubscription() {
         return subscription;
     }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscriptionBundle.java b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscriptionBundle.java
index fd23104..27727e7 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscriptionBundle.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/api/BlockingSubscriptionBundle.java
@@ -27,11 +27,11 @@ import com.ning.billing.overdue.OverdueState;
 
 public class BlockingSubscriptionBundle implements SubscriptionBundle {
     private final SubscriptionBundle subscriptionBundle;
-    private final BlockingApi blockingApi; 
-    
+    private final BlockingApi blockingApi;
+
     private BlockingState blockingState = null;
 
-    public BlockingSubscriptionBundle(SubscriptionBundle subscriptionBundle, BlockingApi blockingApi) {
+    public BlockingSubscriptionBundle(final SubscriptionBundle subscriptionBundle, final BlockingApi blockingApi) {
         this.subscriptionBundle = subscriptionBundle;
         this.blockingApi = blockingApi;
     }
@@ -58,7 +58,7 @@ public class BlockingSubscriptionBundle implements SubscriptionBundle {
 
     @Override
     public BlockingState getBlockingState() {
-        if(blockingState == null) {
+        if (blockingState == null) {
             blockingState = blockingApi.getBlockingStateFor(this);
         }
         return blockingState;
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
index b1c5558..f76c04e 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BillCycleDayCalculator.java
@@ -40,69 +40,69 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionEvent;
 
 public class BillCycleDayCalculator {
-	private static final Logger log = LoggerFactory.getLogger(BillCycleDayCalculator.class);
-	
-	private final CatalogService catalogService;
-	private final EntitlementUserApi entitlementApi;
-
-	@Inject
-	public BillCycleDayCalculator(final CatalogService catalogService, final EntitlementUserApi entitlementApi) {
-		super();
-		this.catalogService = catalogService;
-		this.entitlementApi = entitlementApi;
-	}
-
-	protected int calculateBcd(SubscriptionBundle bundle, Subscription subscription, final SubscriptionEvent transition, final Account account)
-	throws CatalogApiException, AccountApiException, EntitlementUserApiException {
-
-	    Catalog catalog = catalogService.getFullCatalog();
-		
-	    Plan prevPlan = (transition.getPreviousPlan() != null) ? catalog.findPlan(transition.getPreviousPlan(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
-	    Plan nextPlan = (transition.getNextPlan() != null) ? catalog.findPlan(transition.getNextPlan(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;	    
-		
-		Plan plan =  (transition.getTransitionType() != SubscriptionTransitionType.CANCEL) ? nextPlan : prevPlan;
-		Product product = plan.getProduct();
-
-        PlanPhase prevPhase = (transition.getPreviousPhase() != null) ? catalog.findPhase(transition.getPreviousPhase(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
-        PlanPhase nextPhase = (transition.getNextPhase() != null) ? catalog.findPhase(transition.getNextPhase(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
-        
-		PlanPhase phase = (transition.getTransitionType() != SubscriptionTransitionType.CANCEL) ? nextPhase : prevPhase;
-
-		BillingAlignment alignment = catalog.billingAlignment(
-		        new PlanPhaseSpecifier(product.getName(),
-		                product.getCategory(),
-		                phase.getBillingPeriod(),
-		                transition.getNextPriceList(),
-		                phase.getPhaseType()),
-		                transition.getRequestedTransitionTime());
-
-		int result = -1;
-		switch (alignment) {
-		case ACCOUNT :
-		    result = account.getBillCycleDay();
-		    if(result == 0) {
-		        result = calculateBcdFromSubscription(subscription, plan, account);
-		    }
-		    break;
-		case BUNDLE :
-		    Subscription baseSub = entitlementApi.getBaseSubscription(bundle.getId());
-		    Plan basePlan = baseSub.getCurrentPlan();
-		    result = calculateBcdFromSubscription(baseSub, basePlan, account);
-		    break;
-		case SUBSCRIPTION :
-		    result = calculateBcdFromSubscription(subscription, plan, account);
-		    break;
-		}
-		if(result == -1) {
-		    throw new CatalogApiException(ErrorCode.CAT_INVALID_BILLING_ALIGNMENT, alignment.toString());
-		}
-		return result;
-
-	}
-
-	private int calculateBcdFromSubscription(Subscription subscription, Plan plan, Account account) throws AccountApiException {
-		DateTime date = plan.dateOfFirstRecurringNonZeroCharge(subscription.getStartDate());
-		return date.toDateTime(account.getTimeZone()).getDayOfMonth();
-	}
+    private static final Logger log = LoggerFactory.getLogger(BillCycleDayCalculator.class);
+
+    private final CatalogService catalogService;
+    private final EntitlementUserApi entitlementApi;
+
+    @Inject
+    public BillCycleDayCalculator(final CatalogService catalogService, final EntitlementUserApi entitlementApi) {
+        super();
+        this.catalogService = catalogService;
+        this.entitlementApi = entitlementApi;
+    }
+
+    protected int calculateBcd(final SubscriptionBundle bundle, final Subscription subscription, final SubscriptionEvent transition, final Account account)
+            throws CatalogApiException, AccountApiException, EntitlementUserApiException {
+
+        final Catalog catalog = catalogService.getFullCatalog();
+
+        final Plan prevPlan = (transition.getPreviousPlan() != null) ? catalog.findPlan(transition.getPreviousPlan(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
+        final Plan nextPlan = (transition.getNextPlan() != null) ? catalog.findPlan(transition.getNextPlan(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
+
+        final Plan plan = (transition.getTransitionType() != SubscriptionTransitionType.CANCEL) ? nextPlan : prevPlan;
+        final Product product = plan.getProduct();
+
+        final PlanPhase prevPhase = (transition.getPreviousPhase() != null) ? catalog.findPhase(transition.getPreviousPhase(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
+        final PlanPhase nextPhase = (transition.getNextPhase() != null) ? catalog.findPhase(transition.getNextPhase(), transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
+
+        final PlanPhase phase = (transition.getTransitionType() != SubscriptionTransitionType.CANCEL) ? nextPhase : prevPhase;
+
+        final BillingAlignment alignment = catalog.billingAlignment(
+                new PlanPhaseSpecifier(product.getName(),
+                                       product.getCategory(),
+                                       phase.getBillingPeriod(),
+                                       transition.getNextPriceList(),
+                                       phase.getPhaseType()),
+                transition.getRequestedTransitionTime());
+
+        int result = -1;
+        switch (alignment) {
+            case ACCOUNT:
+                result = account.getBillCycleDay();
+                if (result == 0) {
+                    result = calculateBcdFromSubscription(subscription, plan, account);
+                }
+                break;
+            case BUNDLE:
+                final Subscription baseSub = entitlementApi.getBaseSubscription(bundle.getId());
+                final Plan basePlan = baseSub.getCurrentPlan();
+                result = calculateBcdFromSubscription(baseSub, basePlan, account);
+                break;
+            case SUBSCRIPTION:
+                result = calculateBcdFromSubscription(subscription, plan, account);
+                break;
+        }
+        if (result == -1) {
+            throw new CatalogApiException(ErrorCode.CAT_INVALID_BILLING_ALIGNMENT, alignment.toString());
+        }
+        return result;
+
+    }
+
+    private int calculateBcdFromSubscription(final Subscription subscription, final Plan plan, final Account account) throws AccountApiException {
+        final DateTime date = plan.dateOfFirstRecurringNonZeroCharge(subscription.getStartDate());
+        return date.toDateTime(account.getTimeZone()).getDayOfMonth();
+    }
 
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BlockingCalculator.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BlockingCalculator.java
index 19fce2b..07c96b7 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BlockingCalculator.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/BlockingCalculator.java
@@ -43,21 +43,23 @@ import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.junction.api.DefaultBlockingState;
 
 public class BlockingCalculator {
-    private static AtomicLong globaltotalOrder = new AtomicLong();
-    
+    private static final AtomicLong globaltotalOrder = new AtomicLong();
+
     private final BlockingApi blockingApi;
 
     protected static class DisabledDuration {
         private final DateTime start;
         private final DateTime end;
 
-        public DisabledDuration(DateTime start,DateTime end) {
+        public DisabledDuration(final DateTime start, final DateTime end) {
             this.start = start;
             this.end = end;
         }
+
         public DateTime getStart() {
             return start;
         }
+
         public DateTime getEnd() {
             return end;
         }
@@ -66,57 +68,59 @@ public class BlockingCalculator {
 
     protected static class MergeEvent extends DefaultBlockingState {
 
-        public MergeEvent(DateTime timestamp) {
-            super(null,null,null,null,false,false,false,timestamp);
+        public MergeEvent(final DateTime timestamp) {
+            super(null, null, null, null, false, false, false, timestamp);
         }
 
     }
 
     @Inject
-    public BlockingCalculator(BlockingApi blockingApi) {
+    public BlockingCalculator(final BlockingApi blockingApi) {
         this.blockingApi = blockingApi;
     }
 
-    public void insertBlockingEvents(SortedSet<BillingEvent> billingEvents) {
-        if(billingEvents.size() <= 0) { return; }
+    public void insertBlockingEvents(final SortedSet<BillingEvent> billingEvents) {
+        if (billingEvents.size() <= 0) {
+            return;
+        }
 
-        Account account = billingEvents.first().getAccount();
- 
-        Hashtable<UUID,List<Subscription>> bundleMap = createBundleSubscriptionMap(billingEvents);
+        final Account account = billingEvents.first().getAccount();
 
-        SortedSet<BillingEvent> billingEventsToAdd = new TreeSet<BillingEvent>();
-        SortedSet<BillingEvent> billingEventsToRemove = new TreeSet<BillingEvent>();
+        final Hashtable<UUID, List<Subscription>> bundleMap = createBundleSubscriptionMap(billingEvents);
 
-        for(UUID bundleId : bundleMap.keySet()) {
-            SortedSet<BlockingState> blockingEvents = blockingApi.getBlockingHistory(bundleId);
+        final SortedSet<BillingEvent> billingEventsToAdd = new TreeSet<BillingEvent>();
+        final SortedSet<BillingEvent> billingEventsToRemove = new TreeSet<BillingEvent>();
+
+        for (final UUID bundleId : bundleMap.keySet()) {
+            final SortedSet<BlockingState> blockingEvents = blockingApi.getBlockingHistory(bundleId);
             blockingEvents.addAll(blockingApi.getBlockingHistory(account.getId()));
-            List<DisabledDuration>  blockingDurations  = createBlockingDurations(blockingEvents); 
+            final List<DisabledDuration> blockingDurations = createBlockingDurations(blockingEvents);
 
-            for (Subscription subscription: bundleMap.get(bundleId)) {
-                billingEventsToAdd.addAll(createNewEvents( blockingDurations, billingEvents, account, subscription));
+            for (final Subscription subscription : bundleMap.get(bundleId)) {
+                billingEventsToAdd.addAll(createNewEvents(blockingDurations, billingEvents, account, subscription));
                 billingEventsToRemove.addAll(eventsToRemove(blockingDurations, billingEvents, subscription));
             }
         }
 
-        for(BillingEvent eventToAdd: billingEventsToAdd ) {
+        for (final BillingEvent eventToAdd : billingEventsToAdd) {
             billingEvents.add(eventToAdd);
         }
 
-        for(BillingEvent eventToRemove : billingEventsToRemove) {
+        for (final BillingEvent eventToRemove : billingEventsToRemove) {
             billingEvents.remove(eventToRemove);
         }
 
     }
 
-    protected SortedSet<BillingEvent> eventsToRemove(List<DisabledDuration> disabledDuration,
-            SortedSet<BillingEvent> billingEvents, Subscription subscription) {
-        SortedSet<BillingEvent> result = new TreeSet<BillingEvent>();
+    protected SortedSet<BillingEvent> eventsToRemove(final List<DisabledDuration> disabledDuration,
+                                                     final SortedSet<BillingEvent> billingEvents, final Subscription subscription) {
+        final SortedSet<BillingEvent> result = new TreeSet<BillingEvent>();
 
-        SortedSet<BillingEvent> filteredBillingEvents = filter(billingEvents, subscription);
-        for(DisabledDuration duration : disabledDuration) {
-            for(BillingEvent event : filteredBillingEvents) {
-                if(duration.getEnd() == null || event.getEffectiveDate().isBefore(duration.getEnd())) {
-                    if( event.getEffectiveDate().isAfter(duration.getStart()) ) { //between the pair
+        final SortedSet<BillingEvent> filteredBillingEvents = filter(billingEvents, subscription);
+        for (final DisabledDuration duration : disabledDuration) {
+            for (final BillingEvent event : filteredBillingEvents) {
+                if (duration.getEnd() == null || event.getEffectiveDate().isBefore(duration.getEnd())) {
+                    if (event.getEffectiveDate().isAfter(duration.getStart())) { //between the pair
                         result.add(event);
                     }
                 } else { //after the last event of the pair no need to keep checking
@@ -127,46 +131,46 @@ public class BlockingCalculator {
         return result;
     }
 
-     protected SortedSet<BillingEvent> createNewEvents( List<DisabledDuration> disabledDuration, SortedSet<BillingEvent> billingEvents, Account account, Subscription subscription) {
-        SortedSet<BillingEvent> result = new TreeSet<BillingEvent>();
-        for(DisabledDuration duration : disabledDuration) {
-            BillingEvent precedingInitialEvent = precedingBillingEventForSubscription(duration.getStart(), billingEvents, subscription);
-            BillingEvent precedingFinalEvent = precedingBillingEventForSubscription(duration.getEnd(), billingEvents, subscription);
+    protected SortedSet<BillingEvent> createNewEvents(final List<DisabledDuration> disabledDuration, final SortedSet<BillingEvent> billingEvents, final Account account, final Subscription subscription) {
+        final SortedSet<BillingEvent> result = new TreeSet<BillingEvent>();
+        for (final DisabledDuration duration : disabledDuration) {
+            final BillingEvent precedingInitialEvent = precedingBillingEventForSubscription(duration.getStart(), billingEvents, subscription);
+            final BillingEvent precedingFinalEvent = precedingBillingEventForSubscription(duration.getEnd(), billingEvents, subscription);
 
-            if(precedingInitialEvent != null) { // there is a preceding billing event
+            if (precedingInitialEvent != null) { // there is a preceding billing event
                 result.add(createNewDisableEvent(duration.getStart(), precedingInitialEvent));
-                if(duration.getEnd() != null) { // no second event in the pair means they are still disabled (no re-enable)
+                if (duration.getEnd() != null) { // no second event in the pair means they are still disabled (no re-enable)
                     result.add(createNewReenableEvent(duration.getEnd(), precedingFinalEvent));
                 }
 
-            } else if(precedingFinalEvent != null) { // can happen - e.g. phase event
+            } else if (precedingFinalEvent != null) { // can happen - e.g. phase event
                 //
                 // TODO: check with Jeff that this is going to do something sensible
                 //
                 result.add(createNewReenableEvent(duration.getEnd(), precedingFinalEvent));
 
-            } 
+            }
 
             // N.B. if there's no precedingInitial and no precedingFinal then there's nothing to do
         }
         return result;
     }
 
-    protected BillingEvent precedingBillingEventForSubscription(DateTime datetime, SortedSet<BillingEvent> billingEvents, Subscription subscription) { 
-        if(datetime == null) { //second of a pair can be null if there's no re-enabling
+    protected BillingEvent precedingBillingEventForSubscription(final DateTime datetime, final SortedSet<BillingEvent> billingEvents, final Subscription subscription) {
+        if (datetime == null) { //second of a pair can be null if there's no re-enabling
             return null;
         }
 
-        SortedSet<BillingEvent> filteredBillingEvents = filter(billingEvents, subscription);
+        final SortedSet<BillingEvent> filteredBillingEvents = filter(billingEvents, subscription);
         BillingEvent result = filteredBillingEvents.first();
 
-        if(datetime.isBefore(result.getEffectiveDate())) {
+        if (datetime.isBefore(result.getEffectiveDate())) {
             //This case can happen, for example, if we have an add on and the bundle goes into disabled before the add on is created
             return null;
         }
 
-        for(BillingEvent event : filteredBillingEvents) {
-            if(event.getEffectiveDate().isAfter(datetime)) { // found it its the previous event
+        for (final BillingEvent event : filteredBillingEvents) {
+            if (event.getEffectiveDate().isAfter(datetime)) { // found it its the previous event
                 return result;
             } else { // still looking
                 result = event;
@@ -175,17 +179,17 @@ public class BlockingCalculator {
         return result;
     }
 
-    protected SortedSet<BillingEvent> filter(SortedSet<BillingEvent> billingEvents, Subscription subscription) {
-        SortedSet<BillingEvent> result = new TreeSet<BillingEvent>();
-        for(BillingEvent event : billingEvents) {
-            if(event.getSubscription() == subscription) {
+    protected SortedSet<BillingEvent> filter(final SortedSet<BillingEvent> billingEvents, final Subscription subscription) {
+        final SortedSet<BillingEvent> result = new TreeSet<BillingEvent>();
+        for (final BillingEvent event : billingEvents) {
+            if (event.getSubscription() == subscription) {
                 result.add(event);
             }
         }
         return result;
     }
 
-    protected BillingEvent createNewDisableEvent(DateTime odEventTime, BillingEvent previousEvent) {
+    protected BillingEvent createNewDisableEvent(final DateTime odEventTime, final BillingEvent previousEvent) {
         final Account account = previousEvent.getAccount();
         final int billCycleDay = previousEvent.getBillCycleDay();
         final Subscription subscription = previousEvent.getSubscription();
@@ -199,16 +203,16 @@ public class BlockingCalculator {
         final BillingModeType billingModeType = previousEvent.getBillingMode();
         final BillingPeriod billingPeriod = previousEvent.getBillingPeriod();
         final SubscriptionTransitionType type = SubscriptionTransitionType.CANCEL;
-        final Long totalOrdering = globaltotalOrder.getAndIncrement(); 
+        final Long totalOrdering = globaltotalOrder.getAndIncrement();
         final DateTimeZone tz = previousEvent.getTimeZone();
 
         return new DefaultBillingEvent(account, subscription, effectiveDate, plan, planPhase,
-                fixedPrice, recurringPrice, currency,
-                billingPeriod, billCycleDay, billingModeType,
-                description, totalOrdering, type, tz);
+                                       fixedPrice, recurringPrice, currency,
+                                       billingPeriod, billCycleDay, billingModeType,
+                                       description, totalOrdering, type, tz);
     }
 
-    protected BillingEvent createNewReenableEvent(DateTime odEventTime, BillingEvent previousEvent) {
+    protected BillingEvent createNewReenableEvent(final DateTime odEventTime, final BillingEvent previousEvent) {
         final Account account = previousEvent.getAccount();
         final int billCycleDay = previousEvent.getBillCycleDay();
         final Subscription subscription = previousEvent.getSubscription();
@@ -222,47 +226,46 @@ public class BlockingCalculator {
         final BillingModeType billingModeType = previousEvent.getBillingMode();
         final BillingPeriod billingPeriod = previousEvent.getBillingPeriod();
         final SubscriptionTransitionType type = SubscriptionTransitionType.RE_CREATE;
-        final Long totalOrdering = globaltotalOrder.getAndIncrement();  
+        final Long totalOrdering = globaltotalOrder.getAndIncrement();
         final DateTimeZone tz = previousEvent.getTimeZone();
 
         return new DefaultBillingEvent(account, subscription, effectiveDate, plan, planPhase,
-                fixedPrice, recurringPrice, currency,
-                billingPeriod, billCycleDay, billingModeType,
-                description, totalOrdering, type, tz);
+                                       fixedPrice, recurringPrice, currency,
+                                       billingPeriod, billCycleDay, billingModeType,
+                                       description, totalOrdering, type, tz);
     }
 
-    protected Hashtable<UUID,List<Subscription>> createBundleSubscriptionMap(SortedSet<BillingEvent> billingEvents) {
-        Hashtable<UUID,List<Subscription>> result = new Hashtable<UUID,List<Subscription>>();
-        for(BillingEvent event : billingEvents) {
-            UUID bundleId = event.getSubscription().getBundleId();
+    protected Hashtable<UUID, List<Subscription>> createBundleSubscriptionMap(final SortedSet<BillingEvent> billingEvents) {
+        final Hashtable<UUID, List<Subscription>> result = new Hashtable<UUID, List<Subscription>>();
+        for (final BillingEvent event : billingEvents) {
+            final UUID bundleId = event.getSubscription().getBundleId();
             List<Subscription> subs = result.get(bundleId);
-            if(subs == null) {
+            if (subs == null) {
                 subs = new ArrayList<Subscription>();
-                result.put(bundleId,subs);
+                result.put(bundleId, subs);
             }
-            if(!result.contains(event.getSubscription())) {
-                subs.add(event.getSubscription());        
+            if (!result.contains(event.getSubscription())) {
+                subs.add(event.getSubscription());
             }
         }
         return result;
     }
 
 
-
-    protected List<DisabledDuration> createBlockingDurations(SortedSet<BlockingState> overdueBundleEvents) {
-        List<DisabledDuration> result = new ArrayList<BlockingCalculator.DisabledDuration>();
+    protected List<DisabledDuration> createBlockingDurations(final SortedSet<BlockingState> overdueBundleEvents) {
+        final List<DisabledDuration> result = new ArrayList<BlockingCalculator.DisabledDuration>();
         BlockingState first = null;
 
-        for(BlockingState e : overdueBundleEvents) {
-            if(e.isBlockBilling() && first == null) { // found a transition to disabled
+        for (final BlockingState e : overdueBundleEvents) {
+            if (e.isBlockBilling() && first == null) { // found a transition to disabled
                 first = e;
-            } else if(first != null && !e.isBlockBilling()) { // found a transition from disabled
+            } else if (first != null && !e.isBlockBilling()) { // found a transition from disabled
                 result.add(new DisabledDuration(first.getTimestamp(), e.getTimestamp()));
                 first = null;
             }
         }
 
-        if(first != null) { // found a transition to disabled with no terminating event
+        if (first != null) { // found a transition to disabled with no terminating event
             result.add(new DisabledDuration(first.getTimestamp(), null));
         }
 
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingApi.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingApi.java
index 6d91e7c..019acc8 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingApi.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingApi.java
@@ -65,9 +65,9 @@ public class DefaultBillingApi implements BillingApi {
     private final TagUserApi tagApi;
 
     @Inject
-    public DefaultBillingApi(final ChargeThruApi chargeThruApi, final CallContextFactory factory, final AccountUserApi accountApi, 
-            final BillCycleDayCalculator bcdCalculator, final EntitlementUserApi entitlementUserApi, final BlockingCalculator blockCalculator,
-            final CatalogService catalogService, final TagUserApi tagApi) {
+    public DefaultBillingApi(final ChargeThruApi chargeThruApi, final CallContextFactory factory, final AccountUserApi accountApi,
+                             final BillCycleDayCalculator bcdCalculator, final EntitlementUserApi entitlementUserApi, final BlockingCalculator blockCalculator,
+                             final CatalogService catalogService, final TagUserApi tagApi) {
 
         this.chargeThruApi = chargeThruApi;
         this.accountApi = accountApi;
@@ -81,79 +81,79 @@ public class DefaultBillingApi implements BillingApi {
 
     @Override
     public BillingEventSet getBillingEventsForAccountAndUpdateAccountBCD(final UUID accountId) {
-        CallContext context = factory.createCallContext(API_USER_NAME, CallOrigin.INTERNAL, UserType.SYSTEM);
+        final CallContext context = factory.createCallContext(API_USER_NAME, CallOrigin.INTERNAL, UserType.SYSTEM);
 
-        List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId);
-        DefaultBillingEventSet result = new DefaultBillingEventSet();
+        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId);
+        final DefaultBillingEventSet result = new DefaultBillingEventSet();
 
         try {
-            Account account = accountApi.getAccountById(accountId);
+            final Account account = accountApi.getAccountById(accountId);
 
             // Check to see if billing is off for the account
-            Map<String,Tag> accountTags = tagApi.getTags(accountId,ObjectType.ACCOUNT);
-            if(accountTags.get(ControlTagType.AUTO_INVOICING_OFF.name()) != null) {
+            final Map<String, Tag> accountTags = tagApi.getTags(accountId, ObjectType.ACCOUNT);
+            if (accountTags.get(ControlTagType.AUTO_INVOICING_OFF.name()) != null) {
                 result.setAccountAutoInvoiceIsOff(true);
                 return result; // billing is off, we are done
             }
 
-            addBillingEventsForBundles(bundles, account, context, result);         
-           
+            addBillingEventsForBundles(bundles, account, context, result);
+
         } catch (AccountApiException e) {
             log.warn("Failed while getting BillingEvent", e);
         }
-        
+
         debugLog(result, "********* Billing Events Raw");
         blockCalculator.insertBlockingEvents(result);
-        debugLog(result,"*********  Billing Events After Blocking");
-        
+        debugLog(result, "*********  Billing Events After Blocking");
+
         return result;
     }
-    
 
-    private void debugLog(SortedSet<BillingEvent> result, String title) {
+
+    private void debugLog(final SortedSet<BillingEvent> result, final String title) {
         log.debug(title);
-        Iterator<BillingEvent> i = result.iterator();
-        while(i.hasNext()) {
+        final Iterator<BillingEvent> i = result.iterator();
+        while (i.hasNext()) {
             log.debug(i.next().toString());
         }
-        
+
     }
 
-    private void addBillingEventsForBundles(List<SubscriptionBundle> bundles, Account account, CallContext context,
-            DefaultBillingEventSet result) {
-        
-        for (final SubscriptionBundle bundle: bundles) {
-            List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForBundle(bundle.getId());
+    private void addBillingEventsForBundles(final List<SubscriptionBundle> bundles, final Account account, final CallContext context,
+                                            final DefaultBillingEventSet result) {
+
+        for (final SubscriptionBundle bundle : bundles) {
+            final List<Subscription> subscriptions = entitlementUserApi.getSubscriptionsForBundle(bundle.getId());
 
             //Check if billing is off for the bundle
-            Map<String,Tag> bundleTags = tagApi.getTags(bundle.getId(), ObjectType.BUNDLE);
-            if(bundleTags.get(ControlTagType.AUTO_INVOICING_OFF.name()) != null) {
-                 for (final Subscription subscription: subscriptions) { // billing is off so list sub ids in set to be excluded
+            final Map<String, Tag> bundleTags = tagApi.getTags(bundle.getId(), ObjectType.BUNDLE);
+            if (bundleTags.get(ControlTagType.AUTO_INVOICING_OFF.name()) != null) {
+                for (final Subscription subscription : subscriptions) { // billing is off so list sub ids in set to be excluded
                     result.getSubscriptionIdsWithAutoInvoiceOff().add(subscription.getId());
                 }
             } else { // billing is not off
-                addBillingEventsForSubscription(subscriptions, bundle, account, context, result);                 
+                addBillingEventsForSubscription(subscriptions, bundle, account, context, result);
             }
-        }        
+        }
     }
 
-    private void addBillingEventsForSubscription(List<Subscription> subscriptions, SubscriptionBundle bundle, Account account, CallContext context, DefaultBillingEventSet result) {
-        for (final Subscription subscription: subscriptions) {
+    private void addBillingEventsForSubscription(final List<Subscription> subscriptions, final SubscriptionBundle bundle, final Account account, final CallContext context, final DefaultBillingEventSet result) {
+        for (final Subscription subscription : subscriptions) {
             for (final SubscriptionEvent transition : subscription.getBillingTransitions()) {
                 try {
-                    int bcd = bcdCalculator.calculateBcd(bundle, subscription, transition, account);
+                    final int bcd = bcdCalculator.calculateBcd(bundle, subscription, transition, account);
 
-                    if(account.getBillCycleDay() == 0) {
-                        MutableAccountData modifiedData = account.toMutableAccountData();
+                    if (account.getBillCycleDay() == 0) {
+                        final MutableAccountData modifiedData = account.toMutableAccountData();
                         modifiedData.setBillCycleDay(bcd);
                         accountApi.updateAccount(account.getExternalKey(), modifiedData, context);
                     }
 
-                    BillingEvent event = new DefaultBillingEvent(account, transition, subscription, bcd, account.getCurrency(), catalogService.getFullCatalog());
+                    final BillingEvent event = new DefaultBillingEvent(account, transition, subscription, bcd, account.getCurrency(), catalogService.getFullCatalog());
                     result.add(event);
                 } catch (CatalogApiException e) {
                     log.error("Failing to identify catalog components while creating BillingEvent from transition: " +
-                            transition.getId().toString(), e);
+                                      transition.getId().toString(), e);
                 } catch (Exception e) {
                     log.warn("Failed while getting BillingEvent", e);
                 }
@@ -163,8 +163,8 @@ public class DefaultBillingApi implements BillingApi {
     }
 
     @Override
-    public UUID getAccountIdFromSubscriptionId(UUID subscriptionId) throws EntitlementBillingApiException {
-        UUID result = chargeThruApi.getAccountIdFromSubscriptionId(subscriptionId);
+    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId) throws EntitlementBillingApiException {
+        final UUID result = chargeThruApi.getAccountIdFromSubscriptionId(subscriptionId);
         if (result == null) {
             throw new EntitlementBillingApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, subscriptionId.toString());
         }
@@ -172,7 +172,7 @@ public class DefaultBillingApi implements BillingApi {
     }
 
     @Override
-    public void setChargedThroughDate(UUID subscriptionId, DateTime ctd, CallContext context) {
+    public void setChargedThroughDate(final UUID subscriptionId, final DateTime ctd, final CallContext context) {
         chargeThruApi.setChargedThroughDate(subscriptionId, ctd, context);
     }
 }
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEvent.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEvent.java
index be5005b..284aa99 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEvent.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEvent.java
@@ -35,61 +35,60 @@ import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionEvent;
 
 public class DefaultBillingEvent implements BillingEvent {
-    final private Account account;
-    final private int billCycleDay;
-    final private Subscription subscription;
-    final private DateTime effectiveDate;
-    final private PlanPhase planPhase;
-    final private Plan plan;
-    final private BigDecimal fixedPrice;
-    final private BigDecimal recurringPrice;
-    final private Currency currency;
-    final private String description;
-    final private BillingModeType billingModeType;
-    final private BillingPeriod billingPeriod;
-    final private SubscriptionTransitionType type;
-    final private Long totalOrdering;
-    final private DateTimeZone timeZone;
-
-    public DefaultBillingEvent(Account account, SubscriptionEvent transition, Subscription subscription, int billCycleDay, Currency currency, Catalog catalog) throws CatalogApiException {
+    private final Account account;
+    private final int billCycleDay;
+    private final Subscription subscription;
+    private final DateTime effectiveDate;
+    private final PlanPhase planPhase;
+    private final Plan plan;
+    private final BigDecimal fixedPrice;
+    private final BigDecimal recurringPrice;
+    private final Currency currency;
+    private final String description;
+    private final BillingModeType billingModeType;
+    private final BillingPeriod billingPeriod;
+    private final SubscriptionTransitionType type;
+    private final Long totalOrdering;
+    private final DateTimeZone timeZone;
+
+    public DefaultBillingEvent(final Account account, final SubscriptionEvent transition, final Subscription subscription, final int billCycleDay, final Currency currency, final Catalog catalog) throws CatalogApiException {
 
         this.account = account;
         this.billCycleDay = billCycleDay;
         this.subscription = subscription;
         effectiveDate = transition.getEffectiveTransitionTime();
-        String planPhaseName = (transition.getTransitionType() != SubscriptionTransitionType.CANCEL) ?
+        final String planPhaseName = (transition.getTransitionType() != SubscriptionTransitionType.CANCEL) ?
                 transition.getNextPhase() : transition.getPreviousPhase();
         planPhase = (planPhaseName != null) ? catalog.findPhase(planPhaseName, transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
-                
-        String planName = (transition.getTransitionType() != SubscriptionTransitionType.CANCEL) ?
+
+        final String planName = (transition.getTransitionType() != SubscriptionTransitionType.CANCEL) ?
                 transition.getNextPlan() : transition.getPreviousPlan();
         plan = (planName != null) ? catalog.findPlan(planName, transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
-             
-        String nextPhaseName = transition.getNextPhase();
-        PlanPhase nextPhase = (nextPhaseName != null) ? catalog.findPhase(nextPhaseName, transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
 
-        String prevPhaseName = transition.getPreviousPhase();
-        PlanPhase prevPhase = (prevPhaseName != null) ? catalog.findPhase(prevPhaseName, transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
+        final String nextPhaseName = transition.getNextPhase();
+        final PlanPhase nextPhase = (nextPhaseName != null) ? catalog.findPhase(nextPhaseName, transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
+
+        final String prevPhaseName = transition.getPreviousPhase();
+        final PlanPhase prevPhase = (prevPhaseName != null) ? catalog.findPhase(prevPhaseName, transition.getEffectiveTransitionTime(), transition.getSubscriptionStartDate()) : null;
+
 
-        
-        
         fixedPrice = (nextPhase != null && nextPhase.getFixedPrice() != null) ? nextPhase.getFixedPrice().getPrice(currency) : null;
         recurringPrice = (nextPhase != null && nextPhase.getRecurringPrice() != null) ? nextPhase.getRecurringPrice().getPrice(currency) : null;
-        
+
         this.currency = currency;
         description = transition.getTransitionType().toString();
         billingModeType = BillingModeType.IN_ADVANCE;
-        billingPeriod =  (transition.getTransitionType() != SubscriptionTransitionType.CANCEL) ?
+        billingPeriod = (transition.getTransitionType() != SubscriptionTransitionType.CANCEL) ?
                 nextPhase.getBillingPeriod() : prevPhase.getBillingPeriod();
         type = transition.getTransitionType();
         totalOrdering = transition.getTotalOrdering();
         timeZone = account.getTimeZone();
     }
 
-    public DefaultBillingEvent(Account account, Subscription subscription, DateTime effectiveDate, Plan plan, PlanPhase planPhase,
-                               BigDecimal fixedPrice, BigDecimal recurringPrice, Currency currency,
-                               BillingPeriod billingPeriod, int billCycleDay, BillingModeType billingModeType,
-                               String description, long totalOrdering, SubscriptionTransitionType type, DateTimeZone timeZone) {
+    public DefaultBillingEvent(final Account account, final Subscription subscription, final DateTime effectiveDate, final Plan plan, final PlanPhase planPhase,
+                               final BigDecimal fixedPrice, final BigDecimal recurringPrice, final Currency currency,
+                               final BillingPeriod billingPeriod, final int billCycleDay, final BillingModeType billingModeType,
+                               final String description, final long totalOrdering, final SubscriptionTransitionType type, final DateTimeZone timeZone) {
         this.account = account;
         this.subscription = subscription;
         this.effectiveDate = effectiveDate;
@@ -109,26 +108,26 @@ public class DefaultBillingEvent implements BillingEvent {
 
 
     @Override
-    public int compareTo(BillingEvent e1) {
-    	 if (!getSubscription().getId().equals(e1.getSubscription().getId())) { // First order by subscription
-    		 return getSubscription().getId().compareTo(e1.getSubscription().getId());
-    	 } else { // subscriptions are the same
-    		 if (! getEffectiveDate().equals(e1.getEffectiveDate())) { // Secondly order by date
-                 return getEffectiveDate().compareTo(e1.getEffectiveDate());
-    		 } else { // dates and subscriptions are the same
-    			 return getTotalOrdering().compareTo(e1.getTotalOrdering());
-    		 }
-    	 }
+    public int compareTo(final BillingEvent e1) {
+        if (!getSubscription().getId().equals(e1.getSubscription().getId())) { // First order by subscription
+            return getSubscription().getId().compareTo(e1.getSubscription().getId());
+        } else { // subscriptions are the same
+            if (!getEffectiveDate().equals(e1.getEffectiveDate())) { // Secondly order by date
+                return getEffectiveDate().compareTo(e1.getEffectiveDate());
+            } else { // dates and subscriptions are the same
+                return getTotalOrdering().compareTo(e1.getTotalOrdering());
+            }
+        }
     }
 
     @Override
     public Account getAccount() {
-         return account;
+        return account;
     }
 
     @Override
     public int getBillCycleDay() {
-         return billCycleDay;
+        return billCycleDay;
     }
 
     @Override
@@ -193,7 +192,7 @@ public class DefaultBillingEvent implements BillingEvent {
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
+        final StringBuilder sb = new StringBuilder();
         sb.append("BillingEvent {subscriptionId = ").append(subscription.getId().toString()).append(", ");
         sb.append("plan = ").append(plan.getName()).append(", ");
         sb.append("phase = ").append(planPhase.getName()).append(", ");
@@ -227,26 +226,55 @@ public class DefaultBillingEvent implements BillingEvent {
     }
 
     @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        DefaultBillingEvent that = (DefaultBillingEvent) o;
-
-        if (billCycleDay != that.billCycleDay) return false;
-        if (billingModeType != that.billingModeType) return false;
-        if (billingPeriod != that.billingPeriod) return false;
-        if (currency != that.currency) return false;
-        if (!description.equals(that.description)) return false;
-        if (!effectiveDate.equals(that.effectiveDate)) return false;
-        if (fixedPrice != null ? !fixedPrice.equals(that.fixedPrice) : that.fixedPrice != null) return false;
-        if (!plan.equals(that.plan)) return false;
-        if (!planPhase.equals(that.planPhase)) return false;
-        if (recurringPrice != null ? !recurringPrice.equals(that.recurringPrice) : that.recurringPrice != null)
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final DefaultBillingEvent that = (DefaultBillingEvent) o;
+
+        if (billCycleDay != that.billCycleDay) {
+            return false;
+        }
+        if (billingModeType != that.billingModeType) {
+            return false;
+        }
+        if (billingPeriod != that.billingPeriod) {
+            return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (!description.equals(that.description)) {
             return false;
-        if (!subscription.equals(that.subscription)) return false;
-        if (!totalOrdering.equals(that.totalOrdering)) return false;
-        if (type != that.type) return false;
+        }
+        if (!effectiveDate.equals(that.effectiveDate)) {
+            return false;
+        }
+        if (fixedPrice != null ? !fixedPrice.equals(that.fixedPrice) : that.fixedPrice != null) {
+            return false;
+        }
+        if (!plan.equals(that.plan)) {
+            return false;
+        }
+        if (!planPhase.equals(that.planPhase)) {
+            return false;
+        }
+        if (recurringPrice != null ? !recurringPrice.equals(that.recurringPrice) : that.recurringPrice != null) {
+            return false;
+        }
+        if (!subscription.equals(that.subscription)) {
+            return false;
+        }
+        if (!totalOrdering.equals(that.totalOrdering)) {
+            return false;
+        }
+        if (type != that.type) {
+            return false;
+        }
 
         return true;
     }
@@ -273,4 +301,4 @@ public class DefaultBillingEvent implements BillingEvent {
     public DateTimeZone getTimeZone() {
         return timeZone;
     }
-}
\ No newline at end of file
+}
diff --git a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEventSet.java b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEventSet.java
index d26f70b..33b84e5 100644
--- a/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEventSet.java
+++ b/junction/src/main/java/com/ning/billing/junction/plumbing/billing/DefaultBillingEventSet.java
@@ -28,33 +28,33 @@ import com.ning.billing.junction.api.BillingEventSet;
 public class DefaultBillingEventSet extends TreeSet<BillingEvent> implements SortedSet<BillingEvent>, BillingEventSet {
     private static final long serialVersionUID = 1L;
 
-    private boolean    accountAutoInvoiceOff           = false;
+    private boolean accountAutoInvoiceOff = false;
     private List<UUID> subscriptionIdsWithAutoInvoiceOff = new ArrayList<UUID>();
-    
+
     /* (non-Javadoc)
-     * @see com.ning.billing.junction.plumbing.billing.BillingEventSet#isAccountAutoInvoiceOff()
-     */
+    * @see com.ning.billing.junction.plumbing.billing.BillingEventSet#isAccountAutoInvoiceOff()
+    */
     @Override
     public boolean isAccountAutoInvoiceOff() {
         return accountAutoInvoiceOff;
     }
-    
+
     /* (non-Javadoc)
-     * @see com.ning.billing.junction.plumbing.billing.BillingEventSet#getSubscriptionIdsWithAutoInvoiceOff()
-     */
+    * @see com.ning.billing.junction.plumbing.billing.BillingEventSet#getSubscriptionIdsWithAutoInvoiceOff()
+    */
     @Override
     public List<UUID> getSubscriptionIdsWithAutoInvoiceOff() {
         return subscriptionIdsWithAutoInvoiceOff;
     }
 
-    public void setAccountAutoInvoiceIsOff(boolean accountAutoInvoiceIsOff) {
+    public void setAccountAutoInvoiceIsOff(final boolean accountAutoInvoiceIsOff) {
         this.accountAutoInvoiceOff = accountAutoInvoiceIsOff;
     }
 
-    public void setSubscriptionIdsWithAutoInvoiceOff(List<UUID> subscriptionIdsWithAutoInvoiceOff) {
+    public void setSubscriptionIdsWithAutoInvoiceOff(final List<UUID> subscriptionIdsWithAutoInvoiceOff) {
         this.subscriptionIdsWithAutoInvoiceOff = subscriptionIdsWithAutoInvoiceOff;
     }
-    
+
     public boolean isLast(final BillingEvent event) {
         return last() == event;
     }
@@ -65,7 +65,6 @@ public class DefaultBillingEventSet extends TreeSet<BillingEvent> implements Sor
                 + ", subscriptionIdsWithAutoInvoiceOff=" + subscriptionIdsWithAutoInvoiceOff + ", Events="
                 + super.toString() + "]";
     }
-    
-    
-    
+
+
 }
diff --git a/junction/src/test/java/com/ning/billing/junction/api/blocking/TestBlockingApi.java b/junction/src/test/java/com/ning/billing/junction/api/blocking/TestBlockingApi.java
index c6241d8..b8f4343 100644
--- a/junction/src/test/java/com/ning/billing/junction/api/blocking/TestBlockingApi.java
+++ b/junction/src/test/java/com/ning/billing/junction/api/blocking/TestBlockingApi.java
@@ -20,7 +20,6 @@ import java.io.IOException;
 import java.util.SortedSet;
 import java.util.UUID;
 
-import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
@@ -43,21 +42,22 @@ import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 import com.ning.billing.mock.glue.MockEntitlementModule;
 import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.io.IOUtils;
 
-@Guice(modules = { MockModule.class, MockEntitlementModule.class })
+@Guice(modules = {MockModule.class, MockEntitlementModule.class})
 public class TestBlockingApi {
-    private Logger log = LoggerFactory.getLogger(TestBlockingDao.class);
-    
+    private final Logger log = LoggerFactory.getLogger(TestBlockingDao.class);
+
     @Inject
     private MysqlTestingHelper helper;
-    
-    @Inject 
+
+    @Inject
     private BlockingApi api;
-    
+
     @Inject
     private ClockMock clock;
 
-    @BeforeClass(groups={"slow"})
+    @BeforeClass(groups = {"slow"})
     public void setup() throws IOException {
         log.info("Starting set up TestBlockingApi");
 
@@ -65,82 +65,80 @@ public class TestBlockingApi {
 
         helper.startMysql();
         helper.initDb(utilDdl);
-     
     }
-    
-    @BeforeMethod(groups={"slow"})
-    public void clean() {       
+
+    @BeforeMethod(groups = {"slow"})
+    public void clean() {
         helper.cleanupTable("blocking_states");
         clock.resetDeltaFromReality();
     }
-    
+
     @AfterClass(groups = "slow")
-    public void stopMysql()
-    {
+    public void stopMysql() {
         helper.stopMysql();
     }
 
-    @Test(groups={"slow"}, enabled=true)
-    public void testApi() { 
+    @Test(groups = {"slow"}, enabled = true)
+    public void testApi() {
 
-        UUID uuid = UUID.randomUUID();
-        String overdueStateName = "WayPassedItMan";
-        String service = "TEST";
-        
-        boolean blockChange = true;
-        boolean blockEntitlement = false;
-        boolean blockBilling = false;
+        final UUID uuid = UUID.randomUUID();
+        final String overdueStateName = "WayPassedItMan";
+        final String service = "TEST";
 
-        BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement,blockBilling);
+        final boolean blockChange = true;
+        final boolean blockEntitlement = false;
+        final boolean blockBilling = false;
+
+        final BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
         api.setBlockingState(state1);
         clock.setDeltaFromReality(1000 * 3600 * 24);
-        
-        String overdueStateName2 = "NoReallyThisCantGoOn";
-        BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement,blockBilling);
+
+        final String overdueStateName2 = "NoReallyThisCantGoOn";
+        final BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
         api.setBlockingState(state2);
-        
-        SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
-        ((ZombieControl)bundle).addResult("getId", uuid);
-        
+
+        final SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
+        ((ZombieControl) bundle).addResult("getId", uuid);
+
         Assert.assertEquals(api.getBlockingStateFor(bundle).getStateName(), overdueStateName2);
         Assert.assertEquals(api.getBlockingStateFor(bundle.getId()).getStateName(), overdueStateName2);
-        
+
     }
-    
-    @Test(groups={"slow"}, enabled=true)
-    public void testApiHistory() throws Exception { 
-        UUID uuid = UUID.randomUUID();
-        String overdueStateName = "WayPassedItMan";
-        String service = "TEST";
-        
-        boolean blockChange = true;
-        boolean blockEntitlement = false;
-        boolean blockBilling = false;
-
-        BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement,blockBilling);
+
+    @Test(groups = {"slow"}, enabled = true)
+    public void testApiHistory() throws Exception {
+        final UUID uuid = UUID.randomUUID();
+        final String overdueStateName = "WayPassedItMan";
+        final String service = "TEST";
+
+        final boolean blockChange = true;
+        final boolean blockEntitlement = false;
+        final boolean blockBilling = false;
+
+        final BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
         api.setBlockingState(state1);
-        
+
         clock.setDeltaFromReality(1000 * 3600 * 24);
 
-        String overdueStateName2 = "NoReallyThisCantGoOn";
-        BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement,blockBilling);
+        final String overdueStateName2 = "NoReallyThisCantGoOn";
+        final BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
         api.setBlockingState(state2);
-        
-        SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
-        ((ZombieControl)bundle).addResult("getId", uuid);
-        
-     
-        SortedSet<BlockingState> history1 = api.getBlockingHistory(bundle);
-        SortedSet<BlockingState> history2 = api.getBlockingHistory(bundle.getId());
-        
+
+        final SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
+        ((ZombieControl) bundle).addResult("getId", uuid);
+
+
+        final SortedSet<BlockingState> history1 = api.getBlockingHistory(bundle);
+        final SortedSet<BlockingState> history2 = api.getBlockingHistory(bundle.getId());
+
         Assert.assertEquals(history1.size(), 2);
         Assert.assertEquals(history1.first().getStateName(), overdueStateName);
         Assert.assertEquals(history1.last().getStateName(), overdueStateName2);
-        
+
         Assert.assertEquals(history2.size(), 2);
         Assert.assertEquals(history2.first().getStateName(), overdueStateName);
         Assert.assertEquals(history2.last().getStateName(), overdueStateName2);
-       
+
     }
-    
+
 }
diff --git a/junction/src/test/java/com/ning/billing/junction/blocking/MockBlockingChecker.java b/junction/src/test/java/com/ning/billing/junction/blocking/MockBlockingChecker.java
index bf131ae..ccf372b 100644
--- a/junction/src/test/java/com/ning/billing/junction/blocking/MockBlockingChecker.java
+++ b/junction/src/test/java/com/ning/billing/junction/blocking/MockBlockingChecker.java
@@ -26,34 +26,34 @@ import com.ning.billing.junction.block.BlockingChecker;
 public class MockBlockingChecker implements BlockingChecker {
 
     @Override
-    public void checkBlockedChange(Blockable blockable) throws BlockingApiException {
+    public void checkBlockedChange(final Blockable blockable) throws BlockingApiException {
         // Intentionally blank
-        
+
     }
 
     @Override
-    public void checkBlockedEntitlement(Blockable blockable) throws BlockingApiException {
-     // Intentionally blank
+    public void checkBlockedEntitlement(final Blockable blockable) throws BlockingApiException {
+        // Intentionally blank
     }
 
     @Override
-    public void checkBlockedBilling(Blockable blockable) throws BlockingApiException {
-     // Intentionally blank
+    public void checkBlockedBilling(final Blockable blockable) throws BlockingApiException {
+        // Intentionally blank
     }
 
     @Override
-    public void checkBlockedChange(UUID bundleId, Type type) throws BlockingApiException {
-     // Intentionally blank 
+    public void checkBlockedChange(final UUID bundleId, final Type type) throws BlockingApiException {
+        // Intentionally blank
     }
 
     @Override
-    public void checkBlockedEntitlement(UUID bundleId, Type type) throws BlockingApiException {
-     // Intentionally blank
+    public void checkBlockedEntitlement(final UUID bundleId, final Type type) throws BlockingApiException {
+        // Intentionally blank
     }
 
     @Override
-    public void checkBlockedBilling(UUID bundleId, Type type) throws BlockingApiException {
-     // Intentionally blank 
+    public void checkBlockedBilling(final UUID bundleId, final Type type) throws BlockingApiException {
+        // Intentionally blank
     }
 
 }
diff --git a/junction/src/test/java/com/ning/billing/junction/blocking/TestBlockingChecker.java b/junction/src/test/java/com/ning/billing/junction/blocking/TestBlockingChecker.java
index 1d70eac..43a2e79 100644
--- a/junction/src/test/java/com/ning/billing/junction/blocking/TestBlockingChecker.java
+++ b/junction/src/test/java/com/ning/billing/junction/blocking/TestBlockingChecker.java
@@ -42,18 +42,18 @@ import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 import com.ning.billing.util.clock.Clock;
 
 public class TestBlockingChecker {
-   
+
     private BlockingState bundleState;
     private BlockingState subscriptionState;
     private BlockingState accountState;
-    
-    private BlockingStateDao dao = new BlockingStateDao() {
+
+    private final BlockingStateDao dao = new BlockingStateDao() {
 
         @Override
-        public BlockingState getBlockingStateFor(Blockable blockable) {
-            if(blockable.getId() == account.getId()) {
+        public BlockingState getBlockingStateFor(final Blockable blockable) {
+            if (blockable.getId() == account.getId()) {
                 return accountState;
-            } else  if(blockable.getId() == subscription.getId()) {
+            } else if (blockable.getId() == subscription.getId()) {
                 return subscriptionState;
             } else {
                 return bundleState;
@@ -61,10 +61,10 @@ public class TestBlockingChecker {
         }
 
         @Override
-        public BlockingState getBlockingStateFor(UUID blockableId) {
-            if(blockableId == account.getId()) {
+        public BlockingState getBlockingStateFor(final UUID blockableId) {
+            if (blockableId == account.getId()) {
                 return accountState;
-            } else  if(blockableId == subscription.getId()) {
+            } else if (blockableId == subscription.getId()) {
                 return subscriptionState;
             } else {
                 return bundleState;
@@ -72,31 +72,31 @@ public class TestBlockingChecker {
         }
 
         @Override
-        public SortedSet<BlockingState> getBlockingHistoryFor(Blockable overdueable) {
+        public SortedSet<BlockingState> getBlockingHistoryFor(final Blockable overdueable) {
             throw new UnsupportedOperationException();
         }
 
         @Override
-        public SortedSet<BlockingState> getBlockingHistoryFor(UUID overdueableId) {
+        public SortedSet<BlockingState> getBlockingHistoryFor(final UUID overdueableId) {
             throw new UnsupportedOperationException();
         }
 
         @Override
-        public <T extends Blockable> void setBlockingState(BlockingState state, Clock clock) {
+        public <T extends Blockable> void setBlockingState(final BlockingState state, final Clock clock) {
             throw new UnsupportedOperationException();
         }
-        
+
     };
     private BlockingChecker checker;
     private Subscription subscription;
     private Account account;
     private SubscriptionBundle bundle;
-    
-    @BeforeClass(groups={"fast"})
+
+    @BeforeClass(groups = {"fast"})
     public void setup() {
         account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
         ((ZombieControl) account).addResult("getId", UUID.randomUUID());
-        
+
         bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
         ((ZombieControl) bundle).addResult("getAccountId", account.getId());
         ((ZombieControl) bundle).addResult("getId", UUID.randomUUID());
@@ -106,41 +106,41 @@ public class TestBlockingChecker {
         ((ZombieControl) subscription).addResult("getId", UUID.randomUUID());
         ((ZombieControl) subscription).addResult("getBundleId", bundle.getId());
 
-        
-        Injector i = Guice.createInjector(new AbstractModule() {
+
+        final Injector i = Guice.createInjector(new AbstractModule() {
 
             @Override
             protected void configure() {
                 bind(BlockingChecker.class).to(DefaultBlockingChecker.class).asEagerSingleton();
-                
-                bind(BlockingStateDao.class).toInstance(dao);             
-                
-                EntitlementUserApi entitlementUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
+
+                bind(BlockingStateDao.class).toInstance(dao);
+
+                final EntitlementUserApi entitlementUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
                 bind(EntitlementUserApi.class).toInstance(entitlementUserApi);
-                ((ZombieControl) entitlementUserApi).addResult("getBundleFromId",bundle);
-                
+                ((ZombieControl) entitlementUserApi).addResult("getBundleFromId", bundle);
+
             }
-            
+
         });
         checker = i.getInstance(BlockingChecker.class);
     }
 
 
-    private void setStateBundle(boolean bC, boolean bE, boolean bB) {
-        bundleState = new DefaultBlockingState(UUID.randomUUID(), "state", Blockable.Type.SUBSCRIPTION_BUNDLE, "test-service", bC, bE,bB);
+    private void setStateBundle(final boolean bC, final boolean bE, final boolean bB) {
+        bundleState = new DefaultBlockingState(UUID.randomUUID(), "state", Blockable.Type.SUBSCRIPTION_BUNDLE, "test-service", bC, bE, bB);
         ((ZombieControl) bundle).addResult("getBlockingState", bundleState);
     }
 
-    private void setStateAccount(boolean bC, boolean bE, boolean bB) {
-        accountState = new DefaultBlockingState(UUID.randomUUID(), "state", Blockable.Type.SUBSCRIPTION_BUNDLE, "test-service", bC, bE,bB);
+    private void setStateAccount(final boolean bC, final boolean bE, final boolean bB) {
+        accountState = new DefaultBlockingState(UUID.randomUUID(), "state", Blockable.Type.SUBSCRIPTION_BUNDLE, "test-service", bC, bE, bB);
     }
 
-    private void setStateSubscription(boolean bC, boolean bE, boolean bB) {
-        subscriptionState = new DefaultBlockingState(UUID.randomUUID(), "state", Blockable.Type.SUBSCRIPTION_BUNDLE, "test-service", bC, bE,bB);
+    private void setStateSubscription(final boolean bC, final boolean bE, final boolean bB) {
+        subscriptionState = new DefaultBlockingState(UUID.randomUUID(), "state", Blockable.Type.SUBSCRIPTION_BUNDLE, "test-service", bC, bE, bB);
         ((ZombieControl) subscription).addResult("getBlockingState", subscriptionState);
     }
 
-    @Test(groups={"fast"}, enabled = true)
+    @Test(groups = {"fast"}, enabled = true)
     public void testSubscriptionChecker() throws Exception {
         setStateAccount(false, false, false);
         setStateBundle(false, false, false);
@@ -148,7 +148,7 @@ public class TestBlockingChecker {
         checker.checkBlockedChange(subscription);
         checker.checkBlockedEntitlement(subscription);
         checker.checkBlockedBilling(subscription);
-        
+
         //BLOCKED SUBSCRIPTION
         setStateSubscription(true, false, false);
         checker.checkBlockedEntitlement(subscription);
@@ -159,7 +159,7 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateSubscription(false, true, false);
         checker.checkBlockedChange(subscription);
         checker.checkBlockedBilling(subscription);
@@ -169,13 +169,13 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateSubscription(false, false, true);
         checker.checkBlockedChange(subscription);
         checker.checkBlockedEntitlement(subscription);
         try {
-           checker.checkBlockedBilling(subscription);
-           Assert.fail("The call should have been blocked!");
+            checker.checkBlockedBilling(subscription);
+            Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
@@ -191,7 +191,7 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateBundle(false, true, false);
         checker.checkBlockedChange(subscription);
         checker.checkBlockedBilling(subscription);
@@ -201,18 +201,18 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateBundle(false, false, true);
         checker.checkBlockedChange(subscription);
         checker.checkBlockedEntitlement(subscription);
         try {
-           checker.checkBlockedBilling(subscription);
-           Assert.fail("The call should have been blocked!");
+            checker.checkBlockedBilling(subscription);
+            Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
-        
+
+
         //BLOCKED ACCOUNT
         setStateSubscription(false, false, false);
         setStateBundle(false, false, false);
@@ -225,7 +225,7 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateAccount(false, true, false);
         checker.checkBlockedChange(subscription);
         checker.checkBlockedBilling(subscription);
@@ -235,21 +235,21 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateAccount(false, false, true);
         checker.checkBlockedChange(subscription);
         checker.checkBlockedEntitlement(subscription);
         try {
-           checker.checkBlockedBilling(subscription);
-           Assert.fail("The call should have been blocked!");
+            checker.checkBlockedBilling(subscription);
+            Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
-        
+
+
     }
-    
-    @Test(groups={"fast"}, enabled = true)
+
+    @Test(groups = {"fast"}, enabled = true)
     public void testBundleChecker() throws Exception {
         setStateAccount(false, false, false);
         setStateBundle(false, false, false);
@@ -269,7 +269,7 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateBundle(false, true, false);
         checker.checkBlockedChange(bundle);
         checker.checkBlockedBilling(bundle);
@@ -279,18 +279,18 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateBundle(false, false, true);
         checker.checkBlockedChange(bundle);
         checker.checkBlockedEntitlement(bundle);
         try {
-           checker.checkBlockedBilling(bundle);
-           Assert.fail("The call should have been blocked!");
+            checker.checkBlockedBilling(bundle);
+            Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
-        
+
+
         //BLOCKED ACCOUNT
         setStateSubscription(false, false, false);
         setStateBundle(false, false, false);
@@ -303,7 +303,7 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateAccount(false, true, false);
         checker.checkBlockedChange(bundle);
         checker.checkBlockedBilling(bundle);
@@ -313,21 +313,21 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateAccount(false, false, true);
         checker.checkBlockedChange(bundle);
         checker.checkBlockedEntitlement(bundle);
         try {
-           checker.checkBlockedBilling(bundle);
-           Assert.fail("The call should have been blocked!");
+            checker.checkBlockedBilling(bundle);
+            Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
-  
+
+
     }
-    
-    @Test(groups={"fast"}, enabled = true)
+
+    @Test(groups = {"fast"}, enabled = true)
     public void testAccountChecker() throws Exception {
         setStateAccount(false, false, false);
         setStateBundle(false, false, false);
@@ -348,7 +348,7 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateAccount(false, true, false);
         checker.checkBlockedChange(account);
         checker.checkBlockedBilling(account);
@@ -358,21 +358,19 @@ public class TestBlockingChecker {
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
+
         setStateAccount(false, false, true);
         checker.checkBlockedChange(account);
         checker.checkBlockedEntitlement(account);
         try {
-           checker.checkBlockedBilling(account);
-           Assert.fail("The call should have been blocked!");
+            checker.checkBlockedBilling(account);
+            Assert.fail("The call should have been blocked!");
         } catch (BlockingApiException e) {
             //Expected behavior
         }
-        
 
-        
+
     }
-    
 
-     
+
 }
diff --git a/junction/src/test/java/com/ning/billing/junction/dao/TestBlockingDao.java b/junction/src/test/java/com/ning/billing/junction/dao/TestBlockingDao.java
index 8e02e55..4659778 100644
--- a/junction/src/test/java/com/ning/billing/junction/dao/TestBlockingDao.java
+++ b/junction/src/test/java/com/ning/billing/junction/dao/TestBlockingDao.java
@@ -20,7 +20,6 @@ import java.io.IOException;
 import java.util.SortedSet;
 import java.util.UUID;
 
-import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
@@ -40,18 +39,19 @@ import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 import com.ning.billing.mock.glue.MockEntitlementModule;
 import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.io.IOUtils;
 
 @Guice(modules = {MockModule.class, MockEntitlementModule.class})
 public class TestBlockingDao {
-    private Logger log = LoggerFactory.getLogger(TestBlockingDao.class);
-    
+    private final Logger log = LoggerFactory.getLogger(TestBlockingDao.class);
+
     @Inject
     private MysqlTestingHelper helper;
-    
+
     @Inject
     private BlockingStateDao dao;
 
-    @BeforeClass(groups={"slow"})
+    @BeforeClass(groups = {"slow"})
     public void setup() throws IOException {
         log.info("Starting set up TestBlockingDao");
 
@@ -59,78 +59,76 @@ public class TestBlockingDao {
 
         helper.startMysql();
         helper.initDb(utilDdl);
-
     }
-    
+
     @AfterClass(groups = "slow")
-    public void stopMysql()
-    {
+    public void stopMysql() {
         if (helper != null) {
             helper.stopMysql();
         }
     }
 
-    @Test(groups={"slow"}, enabled=true)
-    public void testDao() { 
-        ClockMock clock = new ClockMock();
-        UUID uuid = UUID.randomUUID();
-        String overdueStateName = "WayPassedItMan";
-        String service = "TEST";
-        
-        boolean blockChange = true;
-        boolean blockEntitlement = false;
-        boolean blockBilling = false;
-
-        BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement,blockBilling);
+    @Test(groups = {"slow"}, enabled = true)
+    public void testDao() {
+        final ClockMock clock = new ClockMock();
+        final UUID uuid = UUID.randomUUID();
+        final String overdueStateName = "WayPassedItMan";
+        final String service = "TEST";
+
+        final boolean blockChange = true;
+        final boolean blockEntitlement = false;
+        final boolean blockBilling = false;
+
+        final BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
         dao.setBlockingState(state1, clock);
         clock.setDeltaFromReality(1000 * 3600 * 24);
-        
-        String overdueStateName2 = "NoReallyThisCantGoOn";
-        BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement,blockBilling);
+
+        final String overdueStateName2 = "NoReallyThisCantGoOn";
+        final BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
         dao.setBlockingState(state2, clock);
-        
-        SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
-        ((ZombieControl)bundle).addResult("getId", uuid);
-        
+
+        final SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
+        ((ZombieControl) bundle).addResult("getId", uuid);
+
         Assert.assertEquals(dao.getBlockingStateFor(bundle).getStateName(), state2.getStateName());
         Assert.assertEquals(dao.getBlockingStateFor(bundle.getId()).getStateName(), overdueStateName2);
-        
+
     }
-    
-    @Test(groups={"slow"}, enabled=true)
-    public void testDaoHistory() throws Exception { 
-        ClockMock clock = new ClockMock();
-        UUID uuid = UUID.randomUUID();
-        String overdueStateName = "WayPassedItMan";
-        String service = "TEST";
-        
-        boolean blockChange = true;
-        boolean blockEntitlement = false;
-        boolean blockBilling = false;
-
-        BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement,blockBilling);
+
+    @Test(groups = {"slow"}, enabled = true)
+    public void testDaoHistory() throws Exception {
+        final ClockMock clock = new ClockMock();
+        final UUID uuid = UUID.randomUUID();
+        final String overdueStateName = "WayPassedItMan";
+        final String service = "TEST";
+
+        final boolean blockChange = true;
+        final boolean blockEntitlement = false;
+        final boolean blockBilling = false;
+
+        final BlockingState state1 = new DefaultBlockingState(uuid, overdueStateName, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
         dao.setBlockingState(state1, clock);
         clock.setDeltaFromReality(1000 * 3600 * 24);
-        
-        String overdueStateName2 = "NoReallyThisCantGoOn";
-        BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement,blockBilling);
+
+        final String overdueStateName2 = "NoReallyThisCantGoOn";
+        final BlockingState state2 = new DefaultBlockingState(uuid, overdueStateName2, Blockable.Type.SUBSCRIPTION_BUNDLE, service, blockChange, blockEntitlement, blockBilling);
         dao.setBlockingState(state2, clock);
-        
-        SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
-        ((ZombieControl)bundle).addResult("getId", uuid);
-        
-     
-        SortedSet<BlockingState> history1 = dao.getBlockingHistoryFor(bundle);
-        SortedSet<BlockingState> history2 = dao.getBlockingHistoryFor(bundle.getId());
-        
+
+        final SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
+        ((ZombieControl) bundle).addResult("getId", uuid);
+
+
+        final SortedSet<BlockingState> history1 = dao.getBlockingHistoryFor(bundle);
+        final SortedSet<BlockingState> history2 = dao.getBlockingHistoryFor(bundle.getId());
+
         Assert.assertEquals(history1.size(), 2);
         Assert.assertEquals(history1.first().getStateName(), overdueStateName);
         Assert.assertEquals(history1.last().getStateName(), overdueStateName2);
-        
+
         Assert.assertEquals(history2.size(), 2);
         Assert.assertEquals(history2.first().getStateName(), overdueStateName);
         Assert.assertEquals(history2.last().getStateName(), overdueStateName2);
-       
+
     }
-    
+
 }
diff --git a/junction/src/test/java/com/ning/billing/junction/MockBlockingModule.java b/junction/src/test/java/com/ning/billing/junction/MockBlockingModule.java
index 75814aa..2b7a0a9 100644
--- a/junction/src/test/java/com/ning/billing/junction/MockBlockingModule.java
+++ b/junction/src/test/java/com/ning/billing/junction/MockBlockingModule.java
@@ -23,11 +23,11 @@ import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 
 public class MockBlockingModule extends AbstractModule {
-    public static final String CLEAR_STATE="Clear";
+    public static final String CLEAR_STATE = "Clear";
 
     @Override
     protected void configure() {
-        BlockingApi BlockingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(BlockingApi.class);
+        final BlockingApi BlockingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(BlockingApi.class);
         ((ZombieControl) BlockingApi).addResult("getOverdueStateNameFor", MockBlockingModule.CLEAR_STATE);
         bind(BlockingStateDao.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(BlockingStateDao.class));
         bind(BlockingApi.class).toInstance(BlockingApi);
diff --git a/junction/src/test/java/com/ning/billing/junction/MockModule.java b/junction/src/test/java/com/ning/billing/junction/MockModule.java
index e542d2e..1291437 100644
--- a/junction/src/test/java/com/ning/billing/junction/MockModule.java
+++ b/junction/src/test/java/com/ning/billing/junction/MockModule.java
@@ -33,9 +33,9 @@ public class MockModule extends DefaultJunctionModule {
         install(new MockClockModule());
         install(new MockDbHelperModule());
         install(new CallContextModule());
-       install(new CatalogModule());
+        install(new CatalogModule());
     }
-    
+
     @Override
     public void installBillingApi() {
         // no billinggApi
@@ -43,10 +43,8 @@ public class MockModule extends DefaultJunctionModule {
 
     @Override
     public void installAccountUserApi() {
-        
+
     }
 
-    
-    
 
 }
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/MockSubscription.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/MockSubscription.java
index a9c54cb..2e52c0f 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/MockSubscription.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/MockSubscription.java
@@ -41,20 +41,20 @@ public class MockSubscription implements Subscription {
         return sub.getId();
     }
 
-    public boolean cancel(DateTime requestedDate, boolean eot, CallContext context) throws EntitlementUserApiException {
+    public boolean cancel(final DateTime requestedDate, final boolean eot, final CallContext context) throws EntitlementUserApiException {
         return sub.cancel(requestedDate, eot, context);
     }
 
-    public boolean uncancel(CallContext context) throws EntitlementUserApiException {
+    public boolean uncancel(final CallContext context) throws EntitlementUserApiException {
         return sub.uncancel(context);
     }
 
-    public boolean changePlan(String productName, BillingPeriod term, String planSet, DateTime requestedDate,
-            CallContext context) throws EntitlementUserApiException {
+    public boolean changePlan(final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate,
+                              final CallContext context) throws EntitlementUserApiException {
         return sub.changePlan(productName, term, planSet, requestedDate, context);
     }
 
-    public boolean recreate(PlanPhaseSpecifier spec, DateTime requestedDate, CallContext context)
+    public boolean recreate(final PlanPhaseSpecifier spec, final DateTime requestedDate, final CallContext context)
             throws EntitlementUserApiException {
         return sub.recreate(spec, requestedDate, context);
     }
@@ -114,6 +114,6 @@ public class MockSubscription implements Subscription {
     public List<SubscriptionEvent> getBillingTransitions() {
         return sub.getBillingTransitions();
     }
-    
-    
+
+
 }
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/MockSubscriptionEvent.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/MockSubscriptionEvent.java
index 90f610f..9c6e75d 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/MockSubscriptionEvent.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/MockSubscriptionEvent.java
@@ -17,11 +17,11 @@ package com.ning.billing.junction.plumbing.billing;
 
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import org.joda.time.DateTime;
-
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 import com.ning.billing.entitlement.api.user.SubscriptionEvent;
@@ -47,26 +47,26 @@ public class MockSubscriptionEvent implements SubscriptionEvent {
     private final SubscriptionTransitionType transitionType;
 
     private final DateTime startDate;
-   
+
     @JsonCreator
-    public MockSubscriptionEvent(@JsonProperty("eventId") UUID eventId,
-            @JsonProperty("subscriptionId") UUID subscriptionId,
-            @JsonProperty("bundleId") UUID bundleId,
-            @JsonProperty("requestedTransitionTime") DateTime requestedTransitionTime,
-            @JsonProperty("effectiveTransitionTime") DateTime effectiveTransitionTime,
-            @JsonProperty("previousState") SubscriptionState previousState,
-            @JsonProperty("previousPlan") String previousPlan,
-            @JsonProperty("previousPhase") String previousPhase,
-            @JsonProperty("previousPriceList") String previousPriceList,
-            @JsonProperty("nextState") SubscriptionState nextState,
-            @JsonProperty("nextPlan") String nextPlan,
-            @JsonProperty("nextPhase") String nextPhase,
-            @JsonProperty("nextPriceList") String nextPriceList,
-            @JsonProperty("totalOrdering") Long totalOrdering,
-            @JsonProperty("userToken") UUID userToken,
-            @JsonProperty("transitionType") SubscriptionTransitionType transitionType,
-            @JsonProperty("remainingEventsForUserOperation") Integer remainingEventsForUserOperation,
-            @JsonProperty("startDate") DateTime startDate) {
+    public MockSubscriptionEvent(@JsonProperty("eventId") final UUID eventId,
+                                 @JsonProperty("subscriptionId") final UUID subscriptionId,
+                                 @JsonProperty("bundleId") final UUID bundleId,
+                                 @JsonProperty("requestedTransitionTime") final DateTime requestedTransitionTime,
+                                 @JsonProperty("effectiveTransitionTime") final DateTime effectiveTransitionTime,
+                                 @JsonProperty("previousState") final SubscriptionState previousState,
+                                 @JsonProperty("previousPlan") final String previousPlan,
+                                 @JsonProperty("previousPhase") final String previousPhase,
+                                 @JsonProperty("previousPriceList") final String previousPriceList,
+                                 @JsonProperty("nextState") final SubscriptionState nextState,
+                                 @JsonProperty("nextPlan") final String nextPlan,
+                                 @JsonProperty("nextPhase") final String nextPhase,
+                                 @JsonProperty("nextPriceList") final String nextPriceList,
+                                 @JsonProperty("totalOrdering") final Long totalOrdering,
+                                 @JsonProperty("userToken") final UUID userToken,
+                                 @JsonProperty("transitionType") final SubscriptionTransitionType transitionType,
+                                 @JsonProperty("remainingEventsForUserOperation") final Integer remainingEventsForUserOperation,
+                                 @JsonProperty("startDate") final DateTime startDate) {
         super();
         this.eventId = eventId;
         this.subscriptionId = subscriptionId;
@@ -87,7 +87,7 @@ public class MockSubscriptionEvent implements SubscriptionEvent {
         this.remainingEventsForUserOperation = remainingEventsForUserOperation;
         this.startDate = startDate;
     }
-    
+
     @JsonIgnore
     @Override
     public BusEventType getBusEventType() {
@@ -151,12 +151,12 @@ public class MockSubscriptionEvent implements SubscriptionEvent {
     public String getNextPriceList() {
         return nextPriceList;
     }
-    
+
     @Override
     public UUID getUserToken() {
         return userToken;
     }
-    
+
     @Override
     public Integer getRemainingEventsForUserOperation() {
         return remainingEventsForUserOperation;
@@ -182,7 +182,7 @@ public class MockSubscriptionEvent implements SubscriptionEvent {
     public SubscriptionTransitionType getTransitionType() {
         return transitionType;
     }
-    
+
     @JsonProperty("startDate")
     @Override
     public DateTime getSubscriptionStartDate() {
@@ -199,7 +199,7 @@ public class MockSubscriptionEvent implements SubscriptionEvent {
         result = prime
                 * result
                 + ((effectiveTransitionTime == null) ? 0
-                        : effectiveTransitionTime.hashCode());
+                : effectiveTransitionTime.hashCode());
         result = prime * result + ((eventId == null) ? 0 : eventId.hashCode());
         result = prime * result
                 + ((nextPhase == null) ? 0 : nextPhase.hashCode());
@@ -216,17 +216,17 @@ public class MockSubscriptionEvent implements SubscriptionEvent {
         result = prime
                 * result
                 + ((previousPriceList == null) ? 0 : previousPriceList
-                        .hashCode());
+                .hashCode());
         result = prime * result
                 + ((previousState == null) ? 0 : previousState.hashCode());
         result = prime
                 * result
                 + ((remainingEventsForUserOperation == null) ? 0
-                        : remainingEventsForUserOperation.hashCode());
+                : remainingEventsForUserOperation.hashCode());
         result = prime
                 * result
                 + ((requestedTransitionTime == null) ? 0
-                        : requestedTransitionTime.hashCode());
+                : requestedTransitionTime.hashCode());
         result = prime * result
                 + ((subscriptionId == null) ? 0 : subscriptionId.hashCode());
         result = prime * result
@@ -239,94 +239,128 @@ public class MockSubscriptionEvent implements SubscriptionEvent {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        MockSubscriptionEvent other = (MockSubscriptionEvent) obj;
+        }
+        final MockSubscriptionEvent other = (MockSubscriptionEvent) obj;
         if (bundleId == null) {
-            if (other.bundleId != null)
+            if (other.bundleId != null) {
                 return false;
-        } else if (!bundleId.equals(other.bundleId))
+            }
+        } else if (!bundleId.equals(other.bundleId)) {
             return false;
+        }
         if (effectiveTransitionTime == null) {
-            if (other.effectiveTransitionTime != null)
+            if (other.effectiveTransitionTime != null) {
                 return false;
+            }
         } else if (effectiveTransitionTime
-                .compareTo(other.effectiveTransitionTime) != 0)
+                .compareTo(other.effectiveTransitionTime) != 0) {
             return false;
+        }
         if (eventId == null) {
-            if (other.eventId != null)
+            if (other.eventId != null) {
                 return false;
-        } else if (!eventId.equals(other.eventId))
+            }
+        } else if (!eventId.equals(other.eventId)) {
             return false;
+        }
         if (nextPhase == null) {
-            if (other.nextPhase != null)
+            if (other.nextPhase != null) {
                 return false;
-        } else if (!nextPhase.equals(other.nextPhase))
+            }
+        } else if (!nextPhase.equals(other.nextPhase)) {
             return false;
+        }
         if (nextPlan == null) {
-            if (other.nextPlan != null)
+            if (other.nextPlan != null) {
                 return false;
-        } else if (!nextPlan.equals(other.nextPlan))
+            }
+        } else if (!nextPlan.equals(other.nextPlan)) {
             return false;
+        }
         if (nextPriceList == null) {
-            if (other.nextPriceList != null)
+            if (other.nextPriceList != null) {
                 return false;
-        } else if (!nextPriceList.equals(other.nextPriceList))
+            }
+        } else if (!nextPriceList.equals(other.nextPriceList)) {
             return false;
-        if (nextState != other.nextState)
+        }
+        if (nextState != other.nextState) {
             return false;
+        }
         if (previousPhase == null) {
-            if (other.previousPhase != null)
+            if (other.previousPhase != null) {
                 return false;
-        } else if (!previousPhase.equals(other.previousPhase))
+            }
+        } else if (!previousPhase.equals(other.previousPhase)) {
             return false;
+        }
         if (previousPlan == null) {
-            if (other.previousPlan != null)
+            if (other.previousPlan != null) {
                 return false;
-        } else if (!previousPlan.equals(other.previousPlan))
+            }
+        } else if (!previousPlan.equals(other.previousPlan)) {
             return false;
+        }
         if (previousPriceList == null) {
-            if (other.previousPriceList != null)
+            if (other.previousPriceList != null) {
                 return false;
-        } else if (!previousPriceList.equals(other.previousPriceList))
+            }
+        } else if (!previousPriceList.equals(other.previousPriceList)) {
             return false;
-        if (previousState != other.previousState)
+        }
+        if (previousState != other.previousState) {
             return false;
+        }
         if (remainingEventsForUserOperation == null) {
-            if (other.remainingEventsForUserOperation != null)
+            if (other.remainingEventsForUserOperation != null) {
                 return false;
+            }
         } else if (!remainingEventsForUserOperation
-                .equals(other.remainingEventsForUserOperation))
+                .equals(other.remainingEventsForUserOperation)) {
             return false;
+        }
         if (requestedTransitionTime == null) {
-            if (other.requestedTransitionTime != null)
+            if (other.requestedTransitionTime != null) {
                 return false;
+            }
         } else if (requestedTransitionTime
-                .compareTo(other.requestedTransitionTime) != 0)
+                .compareTo(other.requestedTransitionTime) != 0) {
             return false;
+        }
         if (subscriptionId == null) {
-            if (other.subscriptionId != null)
+            if (other.subscriptionId != null) {
                 return false;
-        } else if (!subscriptionId.equals(other.subscriptionId))
+            }
+        } else if (!subscriptionId.equals(other.subscriptionId)) {
             return false;
+        }
         if (totalOrdering == null) {
-            if (other.totalOrdering != null)
+            if (other.totalOrdering != null) {
                 return false;
-        } else if (!totalOrdering.equals(other.totalOrdering))
+            }
+        } else if (!totalOrdering.equals(other.totalOrdering)) {
             return false;
-        if (transitionType != other.transitionType)
+        }
+        if (transitionType != other.transitionType) {
             return false;
+        }
         if (userToken == null) {
-            if (other.userToken != null)
+            if (other.userToken != null) {
                 return false;
-        } else if (!userToken.equals(other.userToken))
+            }
+        } else if (!userToken.equals(other.userToken)) {
             return false;
+        }
         return true;
     }
-    
+
 }
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java
index f4aab90..ae5f680 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java
@@ -17,12 +17,6 @@
 package com.ning.billing.junction.plumbing.billing;
 
 
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -82,23 +76,29 @@ import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.Tag;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
 public class TestBillingApi {
-    
+
     class MockPrice implements InternationalPrice {
         private final BigDecimal price;
-        
-        public MockPrice(String val) {
+
+        public MockPrice(final String val) {
             price = new BigDecimal(val);
         }
-        
+
         @Override
         public boolean isZero() {
             return price.compareTo(BigDecimal.ZERO) == 0;
         }
-        
+
         @Override
         public Price[] getPrices() {
-            return new Price[]{ 
+            return new Price[]{
                     new Price() {
 
                         @Override
@@ -114,68 +114,65 @@ public class TestBillingApi {
                     }
             };
         }
-        
+
         @Override
-        public BigDecimal getPrice(Currency currency) throws CatalogApiException {
-             return price;
+        public BigDecimal getPrice(final Currency currency) throws CatalogApiException {
+            return price;
         }
-    };
-    
+    }
+
     private static final String DISABLED_BUNDLE = "disabled-bundle";
     private static final String CLEAR_BUNDLE = "clear-bundle";
 
-	private static final UUID eventId = new UUID(0L,0L);
-	private static final UUID subId = new UUID(1L,0L);
-	private static final UUID bunId = new UUID(2L,0L);
+    private static final UUID eventId = new UUID(0L, 0L);
+    private static final UUID subId = new UUID(1L, 0L);
+    private static final UUID bunId = new UUID(2L, 0L);
 
-	private CatalogService catalogService;
-	private List<SubscriptionBundle> bundles;
-	private List<Subscription> subscriptions;
+    private CatalogService catalogService;
 
-	private List<SubscriptionEvent> subscriptionTransitions;
-	private EntitlementUserApi entitlementApi;
+    private List<SubscriptionEvent> subscriptionTransitions;
+    private EntitlementUserApi entitlementApi;
 
-    private BlockingCalculator blockCalculator = new BlockingCalculator(null) {
+    private final BlockingCalculator blockCalculator = new BlockingCalculator(null) {
         @Override
-        public void insertBlockingEvents(SortedSet<BillingEvent> billingEvents) {
-           
+        public void insertBlockingEvents(final SortedSet<BillingEvent> billingEvents) {
+
         }
-        
-    };
 
+    };
 
 
-	private Clock clock;
-	private Subscription subscription;
-	private DateTime subscriptionStartDate;
+    private Clock clock;
+    private Subscription subscription;
+    private DateTime subscriptionStartDate;
     private Plan subscriptionPlan;
     private TagUserApi tagApi;
 
-	@BeforeSuite(groups={"fast", "slow"})
-	public void setup() throws ServiceException {
+    @BeforeSuite(groups = {"fast", "slow"})
+    public void setup() throws ServiceException {
         catalogService = new MockCatalogService(new MockCatalog());
         clock = new ClockMock();
-	}
+    }
+
+    @BeforeMethod(groups = {"fast", "slow"})
+    public void setupEveryTime() {
+        final List<SubscriptionBundle> bundles = new ArrayList<SubscriptionBundle>();
+        final SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
+        ((ZombieControl) bundle).addResult("getId", bunId);
 
-	@BeforeMethod(groups={"fast", "slow"})
-	public void setupEveryTime() {
-		bundles = new ArrayList<SubscriptionBundle>();
-		final SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
-		((ZombieControl)bundle).addResult("getId", bunId);
-		        
-		        //new SubscriptionBundleData( eventId,"TestKey", subId,  clock.getUTCNow().minusDays(4), null);
-		bundles.add(bundle);
+        //new SubscriptionBundleData( eventId,"TestKey", subId,  clock.getUTCNow().minusDays(4), null);
+        bundles.add(bundle);
 
 
-		subscriptionTransitions = new LinkedList<SubscriptionEvent>();
-		subscriptions = new LinkedList<Subscription>();
+        subscriptionTransitions = new LinkedList<SubscriptionEvent>();
+        final List<Subscription> subscriptions = new LinkedList<Subscription>();
 
-		subscriptionStartDate = clock.getUTCNow().minusDays(3);
-		subscription = new MockSubscription() {
-		    @Override
+        subscriptionStartDate = clock.getUTCNow().minusDays(3);
+        subscription = new MockSubscription() {
+            @Override
             public List<SubscriptionEvent> getBillingTransitions() {
-		    	return subscriptionTransitions;
-		    }
+                return subscriptionTransitions;
+            }
 
             @Override
             public Plan getCurrentPlan() {
@@ -196,11 +193,11 @@ public class TestBillingApi {
             public DateTime getStartDate() {
                 return subscriptionStartDate;
             }
-            
-		    
-		};
 
-		subscriptions.add(subscription);
+
+        };
+
+        subscriptions.add(subscription);
 
         entitlementApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
         ((ZombieControl) entitlementApi).addResult("getBundlesForAccount", bundles);
@@ -208,358 +205,359 @@ public class TestBillingApi {
         ((ZombieControl) entitlementApi).addResult("getSubscriptionFromId", subscription);
         ((ZombieControl) entitlementApi).addResult("getBundleFromId", bundle);
         ((ZombieControl) entitlementApi).addResult("getBaseSubscription", subscription);
-        
+
         tagApi = mock(TagUserApi.class);
 
         assertTrue(true);
-	}
+    }
 
-    @Test(enabled=true, groups="fast")
-	public void testBillingEventsEmpty() {
-        UUID accountId = UUID.randomUUID();
-        Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+    @Test(enabled = true, groups = "fast")
+    public void testBillingEventsEmpty() {
+        final UUID accountId = UUID.randomUUID();
+        final Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
         ((ZombieControl) account).addResult("getId", accountId).addResult("getCurrency", Currency.USD);
 
-        AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        final AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        ((ZombieControl) accountApi).addResult("getAccountById", account);
+
+        final BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
+        final CallContextFactory factory = new DefaultCallContextFactory(clock);
+
+        final BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
+
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L, 0L));
+        Assert.assertEquals(events.size(), 0);
+    }
+
+    @Test(enabled = true, groups = "fast")
+    public void testBillingEventsNoBillingPeriod() throws CatalogApiException {
+        final DateTime now = clock.getUTCNow();
+        final DateTime then = now.minusDays(1);
+        final Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
+        final PlanPhase nextPhase = nextPlan.getAllPhases()[0]; // The trial has no billing period
+        final PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
+
+        final SubscriptionEvent t = new MockSubscriptionEvent(
+                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE,
+                nextPlan.getName(), nextPhase.getName(),
+                nextPriceList.getName(), 1L, null,
+                SubscriptionTransitionType.CREATE, 0, null);
+
+        subscriptionTransitions.add(t);
+
+        final AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        final Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+        ((ZombieControl) account).addResult("getBillCycleDay", 32);
+        ((ZombieControl) account).addResult("getCurrency", Currency.USD);
+        ((ZombieControl) account).addResult("getId", UUID.randomUUID());
+        ((ZombieControl) account).addResult("getTimeZone", DateTimeZone.UTC);
         ((ZombieControl) accountApi).addResult("getAccountById", account);
 
-        BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
-        CallContextFactory factory = new DefaultCallContextFactory(clock);
-
-		BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
-
-		SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
-		Assert.assertEquals(events.size(), 0);
-	}
-
-    @Test(enabled=true, groups="fast")
-	public void testBillingEventsNoBillingPeriod() throws CatalogApiException {
-		DateTime now = clock.getUTCNow();
-		DateTime then = now.minusDays(1);
-		Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
-		PlanPhase nextPhase = nextPlan.getAllPhases()[0]; // The trial has no billing period
-        PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
-
-        SubscriptionEvent t = new MockSubscriptionEvent(
-                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE, 
-                nextPlan.getName(), nextPhase.getName(), 
-                nextPriceList.getName(), 1L,null, 
-                SubscriptionTransitionType.CREATE, 0, null); 
-
-		subscriptionTransitions.add(t);
-
-        AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
-        Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
-        ((ZombieControl)account).addResult("getBillCycleDay", 32);
-        ((ZombieControl)account).addResult("getCurrency", Currency.USD);
-        ((ZombieControl)account).addResult("getId", UUID.randomUUID());
-        ((ZombieControl)account).addResult("getTimeZone", DateTimeZone.UTC);
-        ((ZombieControl)accountApi).addResult("getAccountById", account);
-		       
-        BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
-        CallContextFactory factory = new DefaultCallContextFactory(clock);
-        BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
-        SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
-
-		checkFirstEvent(events, nextPlan, 32, subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
-	}
-
-    @Test(enabled=false, groups="fast")
-	public void testBillingEventsAnnual() throws CatalogApiException {
-		DateTime now = clock.getUTCNow();
-		DateTime then = now.minusDays(1);
-		Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
-		PlanPhase nextPhase = nextPlan.getAllPhases()[1];
-		PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
-        SubscriptionEvent t = new MockSubscriptionEvent(
-                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE, 
-                nextPlan.getName(), nextPhase.getName(), 
-                nextPriceList.getName(), 1L,null, 
-                SubscriptionTransitionType.CREATE, 0, null); 
-
-		subscriptionTransitions.add(t);
-
-		Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
-		((ZombieControl)account).addResult("getBillCycleDay", 1).addResult("getTimeZone", DateTimeZone.UTC)
-                                .addResult("getCurrency", Currency.USD);
-
-        ((MockCatalog)catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.SUBSCRIPTION);
-        
-		AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
-		((ZombieControl)accountApi).addResult("getAccountById", account);
-
-        BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
-        CallContextFactory factory = new DefaultCallContextFactory(clock);
-
-        BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
-        SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
-
-		checkFirstEvent(events, nextPlan, subscription.getStartDate().plusDays(30).getDayOfMonth(), subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
-	}
-
-    @Test(enabled=true, groups="fast")
-	public void testBillingEventsMonthly() throws CatalogApiException {
-		DateTime now = clock.getUTCNow();
-		DateTime then = now.minusDays(1);
-		Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
-		PlanPhase nextPhase = nextPlan.getAllPhases()[1];
-        PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
-
-        SubscriptionEvent t = new MockSubscriptionEvent(
-                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE, 
-                nextPlan.getName(), nextPhase.getName(), 
-                nextPriceList.getName(), 1L,null, 
-                SubscriptionTransitionType.CREATE, 0, null); 
-
-
-		subscriptionTransitions.add(t);
-
-        AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
-        Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
-        ((ZombieControl)account).addResult("getBillCycleDay", 32);
-        ((ZombieControl)account).addResult("getCurrency", Currency.USD);
-        ((ZombieControl)account).addResult("getId", UUID.randomUUID());
-        ((ZombieControl)account).addResult("getTimeZone", DateTimeZone.UTC);
-        ((ZombieControl)accountApi).addResult("getAccountById", account);
-
-        ((MockCatalog)catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.ACCOUNT);
-        
-        BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
-        CallContextFactory factory = new DefaultCallContextFactory(clock);
-        BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
-
-        SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
-
-		checkFirstEvent(events, nextPlan, 32, subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
-	}
-
-    @Test(enabled=false, groups="fast")
-	public void testBillingEventsAddOn() throws CatalogApiException {
-		DateTime now = clock.getUTCNow();
-		DateTime then = now.minusDays(1);
-		Plan nextPlan = catalogService.getFullCatalog().findPlan("Horn1USD", now);
-		PlanPhase nextPhase = nextPlan.getAllPhases()[0];
-        PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
-
-        SubscriptionEvent t = new MockSubscriptionEvent(
-                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE, 
-                nextPlan.getName(), nextPhase.getName(), 
-                nextPriceList.getName(), 1L,null, 
-                SubscriptionTransitionType.CREATE, 0, null); 
-
-		subscriptionTransitions.add(t);
-
-		Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
-		((ZombieControl)account).addResult("getBillCycleDay", 1).addResult("getTimeZone", DateTimeZone.UTC);
-        ((ZombieControl)account).addResult("getCurrency", Currency.USD);
-        ((ZombieControl)account).addResult("getId", UUID.randomUUID());
-        ((ZombieControl)account).addResult("getTimeZone", DateTimeZone.UTC);
-
-        AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
-        ((ZombieControl)accountApi).addResult("getAccountById", account);
-             
-        ((MockCatalog)catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.BUNDLE);
-        
-        BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
-        CallContextFactory factory = new DefaultCallContextFactory(clock);
-        
-        BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
+        final BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
+        final CallContextFactory factory = new DefaultCallContextFactory(clock);
+        final BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L, 0L));
+
+        checkFirstEvent(events, nextPlan, 32, subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
+    }
+
+    @Test(enabled = false, groups = "fast")
+    public void testBillingEventsAnnual() throws CatalogApiException {
+        final DateTime now = clock.getUTCNow();
+        final DateTime then = now.minusDays(1);
+        final Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
+        final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
+        final PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
+        final SubscriptionEvent t = new MockSubscriptionEvent(
+                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE,
+                nextPlan.getName(), nextPhase.getName(),
+                nextPriceList.getName(), 1L, null,
+                SubscriptionTransitionType.CREATE, 0, null);
+
+        subscriptionTransitions.add(t);
+
+        final Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+        ((ZombieControl) account).addResult("getBillCycleDay", 1).addResult("getTimeZone", DateTimeZone.UTC)
+                                 .addResult("getCurrency", Currency.USD);
+
+        ((MockCatalog) catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.SUBSCRIPTION);
+
+        final AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        ((ZombieControl) accountApi).addResult("getAccountById", account);
+
+        final BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
+        final CallContextFactory factory = new DefaultCallContextFactory(clock);
+
+        final BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L, 0L));
+
+        checkFirstEvent(events, nextPlan, subscription.getStartDate().plusDays(30).getDayOfMonth(), subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
+    }
+
+    @Test(enabled = true, groups = "fast")
+    public void testBillingEventsMonthly() throws CatalogApiException {
+        final DateTime now = clock.getUTCNow();
+        final DateTime then = now.minusDays(1);
+        final Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
+        final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
+        final PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
+
+        final SubscriptionEvent t = new MockSubscriptionEvent(
+                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE,
+                nextPlan.getName(), nextPhase.getName(),
+                nextPriceList.getName(), 1L, null,
+                SubscriptionTransitionType.CREATE, 0, null);
+
+
+        subscriptionTransitions.add(t);
+
+        final AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        final Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+        ((ZombieControl) account).addResult("getBillCycleDay", 32);
+        ((ZombieControl) account).addResult("getCurrency", Currency.USD);
+        ((ZombieControl) account).addResult("getId", UUID.randomUUID());
+        ((ZombieControl) account).addResult("getTimeZone", DateTimeZone.UTC);
+        ((ZombieControl) accountApi).addResult("getAccountById", account);
+
+        ((MockCatalog) catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.ACCOUNT);
+
+        final BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
+        final CallContextFactory factory = new DefaultCallContextFactory(clock);
+        final BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
+
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L, 0L));
+
+        checkFirstEvent(events, nextPlan, 32, subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
+    }
+
+    @Test(enabled = false, groups = "fast")
+    public void testBillingEventsAddOn() throws CatalogApiException {
+        final DateTime now = clock.getUTCNow();
+        final DateTime then = now.minusDays(1);
+        final Plan nextPlan = catalogService.getFullCatalog().findPlan("Horn1USD", now);
+        final PlanPhase nextPhase = nextPlan.getAllPhases()[0];
+        final PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
+
+        final SubscriptionEvent t = new MockSubscriptionEvent(
+                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE,
+                nextPlan.getName(), nextPhase.getName(),
+                nextPriceList.getName(), 1L, null,
+                SubscriptionTransitionType.CREATE, 0, null);
+
+        subscriptionTransitions.add(t);
+
+        final Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+        ((ZombieControl) account).addResult("getBillCycleDay", 1).addResult("getTimeZone", DateTimeZone.UTC);
+        ((ZombieControl) account).addResult("getCurrency", Currency.USD);
+        ((ZombieControl) account).addResult("getId", UUID.randomUUID());
+        ((ZombieControl) account).addResult("getTimeZone", DateTimeZone.UTC);
+
+        final AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        ((ZombieControl) accountApi).addResult("getAccountById", account);
+
+        ((MockCatalog) catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.BUNDLE);
+
+        final BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
+        final CallContextFactory factory = new DefaultCallContextFactory(clock);
+
+        final BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
         subscriptionPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
 
-        SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L, 0L));
 
-		checkFirstEvent(events, nextPlan, subscription.getStartDate().plusDays(30).getDayOfMonth(), subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
-	}
+        checkFirstEvent(events, nextPlan, subscription.getStartDate().plusDays(30).getDayOfMonth(), subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString());
+    }
 
-    @Test(enabled=true, groups="fast")
+    @Test(enabled = true, groups = "fast")
     public void testBillingEventsWithBlock() throws CatalogApiException {
-        DateTime now = clock.getUTCNow();
-        DateTime then = now.minusDays(1);
-        Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
-        PlanPhase nextPhase = nextPlan.getAllPhases()[1];
-        PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
-
-        
-        SubscriptionEvent t = new MockSubscriptionEvent(
-                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE, 
-                nextPlan.getName(), nextPhase.getName(), 
-                nextPriceList.getName(), 1L,null, 
-                SubscriptionTransitionType.CREATE, 0, null); 
+        final DateTime now = clock.getUTCNow();
+        final DateTime then = now.minusDays(1);
+        final Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
+        final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
+        final PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
+
+
+        final SubscriptionEvent t = new MockSubscriptionEvent(
+                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE,
+                nextPlan.getName(), nextPhase.getName(),
+                nextPriceList.getName(), 1L, null,
+                SubscriptionTransitionType.CREATE, 0, null);
 
         subscriptionTransitions.add(t);
 
-        AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
-        Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
-        ((ZombieControl)account).addResult("getBillCycleDay", 32);
-        ((ZombieControl)account).addResult("getCurrency", Currency.USD);
-        ((ZombieControl)account).addResult("getTimeZone", DateTimeZone.UTC);
-        ((ZombieControl)accountApi).addResult("getAccountById", account);
-        ((ZombieControl)account).addResult("getId", UUID.randomUUID());
+        final AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        final Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+        ((ZombieControl) account).addResult("getBillCycleDay", 32);
+        ((ZombieControl) account).addResult("getCurrency", Currency.USD);
+        ((ZombieControl) account).addResult("getTimeZone", DateTimeZone.UTC);
+        ((ZombieControl) accountApi).addResult("getAccountById", account);
+        ((ZombieControl) account).addResult("getId", UUID.randomUUID());
+
+        ((MockCatalog) catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.ACCOUNT);
 
-        ((MockCatalog)catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.ACCOUNT);
-        
         final SortedSet<BlockingState> blockingStates = new TreeSet<BlockingState>();
-        blockingStates.add(new DefaultBlockingState(bunId,DISABLED_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
-        blockingStates.add(new DefaultBlockingState(bunId,CLEAR_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
-        
-        BlockingCalculator blockingCal = new BlockingCalculator(new BlockingApi() {
-            
+        blockingStates.add(new DefaultBlockingState(bunId, DISABLED_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
+        blockingStates.add(new DefaultBlockingState(bunId, CLEAR_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
+
+        final BlockingCalculator blockingCal = new BlockingCalculator(new BlockingApi() {
+
             @Override
-            public <T extends Blockable> void setBlockingState(BlockingState state) {}
-            
+            public <T extends Blockable> void setBlockingState(final BlockingState state) {
+            }
+
             @Override
-            public BlockingState getBlockingStateFor(UUID overdueableId) {
+            public BlockingState getBlockingStateFor(final UUID overdueableId) {
                 return null;
             }
-            
+
             @Override
-            public BlockingState getBlockingStateFor(Blockable overdueable) {
+            public BlockingState getBlockingStateFor(final Blockable overdueable) {
                 return null;
             }
-            
+
             @Override
-            public SortedSet<BlockingState> getBlockingHistory(UUID overdueableId) {
-                if(overdueableId == bunId) {
+            public SortedSet<BlockingState> getBlockingHistory(final UUID overdueableId) {
+                if (overdueableId == bunId) {
                     return blockingStates;
                 }
                 return new TreeSet<BlockingState>();
             }
-            
+
             @Override
-            public SortedSet<BlockingState> getBlockingHistory(Blockable overdueable) {
+            public SortedSet<BlockingState> getBlockingHistory(final Blockable overdueable) {
                 return new TreeSet<BlockingState>();
             }
         });
-        
-        BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
-        CallContextFactory factory = new DefaultCallContextFactory(clock);
-        BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockingCal, catalogService, tagApi);
-        SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L,0L));
+
+        final BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
+        final CallContextFactory factory = new DefaultCallContextFactory(clock);
+        final BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockingCal, catalogService, tagApi);
+        final SortedSet<BillingEvent> events = api.getBillingEventsForAccountAndUpdateAccountBCD(new UUID(0L, 0L));
 
         Assert.assertEquals(events.size(), 3);
-        Iterator<BillingEvent> it = events.iterator();
-       
+        final Iterator<BillingEvent> it = events.iterator();
+
         checkEvent(it.next(), nextPlan, 32, subId, now, nextPhase, SubscriptionTransitionType.CREATE.toString(), nextPhase.getFixedPrice(), nextPhase.getRecurringPrice());
         checkEvent(it.next(), nextPlan, 32, subId, now.plusDays(1), nextPhase, SubscriptionTransitionType.CANCEL.toString(), new MockPrice("0"), new MockPrice("0"));
         checkEvent(it.next(), nextPlan, 32, subId, now.plusDays(2), nextPhase, SubscriptionTransitionType.RE_CREATE.toString(), nextPhase.getFixedPrice(), nextPhase.getRecurringPrice());
-        
+
     }
-    
-    @Test(enabled=true, groups="fast")
+
+    @Test(enabled = true, groups = "fast")
     public void testBillingEventsAutoInvoicingOffAccount() throws CatalogApiException {
-        DateTime now = clock.getUTCNow();
-        DateTime then = now.minusDays(1);
-        Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
-        PlanPhase nextPhase = nextPlan.getAllPhases()[1];
-        PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
+        final DateTime now = clock.getUTCNow();
+        final DateTime then = now.minusDays(1);
+        final Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
+        final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
+        final PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
 
-        SubscriptionEvent t = new MockSubscriptionEvent(
-                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE, 
-                nextPlan.getName(), nextPhase.getName(), 
-                nextPriceList.getName(), 1L,null, 
-                SubscriptionTransitionType.CREATE, 0, null); 
+        final SubscriptionEvent t = new MockSubscriptionEvent(
+                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE,
+                nextPlan.getName(), nextPhase.getName(),
+                nextPriceList.getName(), 1L, null,
+                SubscriptionTransitionType.CREATE, 0, null);
 
 
         subscriptionTransitions.add(t);
 
-        AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
-        Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
-        ((ZombieControl)account).addResult("getBillCycleDay", 32);
-        ((ZombieControl)account).addResult("getCurrency", Currency.USD);
-        ((ZombieControl)account).addResult("getId", UUID.randomUUID());
-        ((ZombieControl)accountApi).addResult("getAccountById", account);
-        
-         Map<String, Tag> tags = new HashMap<String, Tag>();
-        Tag aioTag = mock(Tag.class);
+        final AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        final Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+        ((ZombieControl) account).addResult("getBillCycleDay", 32);
+        ((ZombieControl) account).addResult("getCurrency", Currency.USD);
+        ((ZombieControl) account).addResult("getId", UUID.randomUUID());
+        ((ZombieControl) accountApi).addResult("getAccountById", account);
+
+        final Map<String, Tag> tags = new HashMap<String, Tag>();
+        final Tag aioTag = mock(Tag.class);
         when(aioTag.getTagDefinitionName()).thenReturn(ControlTagType.AUTO_INVOICING_OFF.name());
-        tags.put(ControlTagType.AUTO_INVOICING_OFF.name(),aioTag);
+        tags.put(ControlTagType.AUTO_INVOICING_OFF.name(), aioTag);
         when(tagApi.getTags(account.getId(), ObjectType.ACCOUNT)).thenReturn(tags);
         assertEquals(tagApi.getTags(account.getId(), ObjectType.ACCOUNT), tags);
 
-        ((MockCatalog)catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.ACCOUNT);
-        
-        BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
-        CallContextFactory factory = new DefaultCallContextFactory(clock);
-        BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
+        ((MockCatalog) catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.ACCOUNT);
+
+        final BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
+        final CallContextFactory factory = new DefaultCallContextFactory(clock);
+        final BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
+
+        final BillingEventSet events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
 
-        BillingEventSet events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
-        
         assertEquals(events.isAccountAutoInvoiceOff(), true);
-        assertEquals(events.size(),0);
+        assertEquals(events.size(), 0);
     }
 
-    
-    @Test(enabled=true, groups="fast")
+
+    @Test(enabled = true, groups = "fast")
     public void testBillingEventsAutoInvoicingOffBundle() throws CatalogApiException {
-        DateTime now = clock.getUTCNow();
-        DateTime then = now.minusDays(1);
-        Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
-        PlanPhase nextPhase = nextPlan.getAllPhases()[1];
-        PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
+        final DateTime now = clock.getUTCNow();
+        final DateTime then = now.minusDays(1);
+        final Plan nextPlan = catalogService.getFullCatalog().findPlan("PickupTrialEvergreen10USD", now);
+        final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
+        final PriceList nextPriceList = catalogService.getFullCatalog().findPriceList(PriceListSet.DEFAULT_PRICELIST_NAME, now);
 
-        SubscriptionEvent t = new MockSubscriptionEvent(
-                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE, 
-                nextPlan.getName(), nextPhase.getName(), 
-                nextPriceList.getName(), 1L,null, 
-                SubscriptionTransitionType.CREATE, 0, null); 
+        final SubscriptionEvent t = new MockSubscriptionEvent(
+                eventId, subId, bunId, then, now, null, null, null, null, SubscriptionState.ACTIVE,
+                nextPlan.getName(), nextPhase.getName(),
+                nextPriceList.getName(), 1L, null,
+                SubscriptionTransitionType.CREATE, 0, null);
 
 
         subscriptionTransitions.add(t);
 
-        AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
-        Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
-        ((ZombieControl)account).addResult("getBillCycleDay", 32);
-        ((ZombieControl)account).addResult("getCurrency", Currency.USD);
-        ((ZombieControl)account).addResult("getId", UUID.randomUUID());
-        ((ZombieControl)accountApi).addResult("getAccountById", account);
-        
-         Map<String, Tag> tags = new HashMap<String, Tag>();
-        Tag aioTag = mock(Tag.class);
+        final AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+        final Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+        ((ZombieControl) account).addResult("getBillCycleDay", 32);
+        ((ZombieControl) account).addResult("getCurrency", Currency.USD);
+        ((ZombieControl) account).addResult("getId", UUID.randomUUID());
+        ((ZombieControl) accountApi).addResult("getAccountById", account);
+
+        final Map<String, Tag> tags = new HashMap<String, Tag>();
+        final Tag aioTag = mock(Tag.class);
         when(aioTag.getTagDefinitionName()).thenReturn(ControlTagType.AUTO_INVOICING_OFF.name());
-        tags.put(ControlTagType.AUTO_INVOICING_OFF.name(),aioTag);
+        tags.put(ControlTagType.AUTO_INVOICING_OFF.name(), aioTag);
         when(tagApi.getTags(bunId, ObjectType.BUNDLE)).thenReturn(tags);
- 
-        ((MockCatalog)catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.ACCOUNT);
-        
-        BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
-        CallContextFactory factory = new DefaultCallContextFactory(clock);
-        BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
-
-        BillingEventSet events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
-        
+
+        ((MockCatalog) catalogService.getFullCatalog()).setBillingAlignment(BillingAlignment.ACCOUNT);
+
+        final BillCycleDayCalculator bcdCalculator = new BillCycleDayCalculator(catalogService, entitlementApi);
+        final CallContextFactory factory = new DefaultCallContextFactory(clock);
+        final BillingApi api = new DefaultBillingApi(null, factory, accountApi, bcdCalculator, entitlementApi, blockCalculator, catalogService, tagApi);
+
+        final BillingEventSet events = api.getBillingEventsForAccountAndUpdateAccountBCD(account.getId());
+
         assertEquals(events.getSubscriptionIdsWithAutoInvoiceOff().size(), 1);
         assertEquals(events.getSubscriptionIdsWithAutoInvoiceOff().get(0), subId);
-        assertEquals(events.size(),0);
+        assertEquals(events.size(), 0);
     }
 
-    private void checkFirstEvent(SortedSet<BillingEvent> events, Plan nextPlan,
-            int BCD, UUID id, DateTime time, PlanPhase nextPhase, String desc) throws CatalogApiException {
-		Assert.assertEquals(events.size(), 1);
-		checkEvent(events.first(), nextPlan,
-	            BCD, id, time, nextPhase, desc, nextPhase.getFixedPrice(), nextPhase.getRecurringPrice());
-	}
-
-	private void checkEvent(BillingEvent event, Plan nextPlan,
-	            int BCD, UUID id, DateTime time, PlanPhase nextPhase, String desc, InternationalPrice fixedPrice, InternationalPrice recurringPrice) throws CatalogApiException {
-        if(fixedPrice != null) {
-			Assert.assertEquals(fixedPrice.getPrice(Currency.USD), event.getFixedPrice());
+    private void checkFirstEvent(final SortedSet<BillingEvent> events, final Plan nextPlan,
+                                 final int BCD, final UUID id, final DateTime time, final PlanPhase nextPhase, final String desc) throws CatalogApiException {
+        Assert.assertEquals(events.size(), 1);
+        checkEvent(events.first(), nextPlan,
+                   BCD, id, time, nextPhase, desc, nextPhase.getFixedPrice(), nextPhase.getRecurringPrice());
+    }
+
+    private void checkEvent(final BillingEvent event, final Plan nextPlan,
+                            final int BCD, final UUID id, final DateTime time, final PlanPhase nextPhase, final String desc, final InternationalPrice fixedPrice, final InternationalPrice recurringPrice) throws CatalogApiException {
+        if (fixedPrice != null) {
+            Assert.assertEquals(fixedPrice.getPrice(Currency.USD), event.getFixedPrice());
         } else {
             assertNull(event.getFixedPrice());
-		}
+        }
 
-		if(recurringPrice != null) {
-			Assert.assertEquals(recurringPrice.getPrice(Currency.USD), event.getRecurringPrice());
+        if (recurringPrice != null) {
+            Assert.assertEquals(recurringPrice.getPrice(Currency.USD), event.getRecurringPrice());
         } else {
             assertNull(event.getRecurringPrice());
-		}
-
-		Assert.assertEquals(BCD, event.getBillCycleDay());
-		Assert.assertEquals(id, event.getSubscription().getId());
-		Assert.assertEquals(time.getDayOfMonth(), event.getEffectiveDate().getDayOfMonth());
-		Assert.assertEquals(nextPhase, event.getPlanPhase());
-		Assert.assertEquals(nextPlan, event.getPlan());
-		Assert.assertEquals(nextPhase.getBillingPeriod(), event.getBillingPeriod());
-		Assert.assertEquals(BillingModeType.IN_ADVANCE, event.getBillingMode());
-		Assert.assertEquals(desc, event.getTransitionType().toString());
-	}
+        }
+
+        Assert.assertEquals(BCD, event.getBillCycleDay());
+        Assert.assertEquals(id, event.getSubscription().getId());
+        Assert.assertEquals(time.getDayOfMonth(), event.getEffectiveDate().getDayOfMonth());
+        Assert.assertEquals(nextPhase, event.getPlanPhase());
+        Assert.assertEquals(nextPlan, event.getPlan());
+        Assert.assertEquals(nextPhase.getBillingPeriod(), event.getBillingPeriod());
+        Assert.assertEquals(BillingModeType.IN_ADVANCE, event.getBillingMode());
+        Assert.assertEquals(desc, event.getTransitionType().toString());
+    }
 }
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java
index 9ca10cd..ce0b6dc 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.junction.plumbing.billing;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Hashtable;
@@ -60,6 +56,10 @@ import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
 
 public class TestBlockingCalculator {
 
@@ -72,8 +72,8 @@ public class TestBlockingCalculator {
     private Subscription subscription2;
     private Subscription subscription3;
     private Subscription subscription4;
-    private UUID bundleId1 = UUID.randomUUID();
-    private UUID bundleId2 = UUID.randomUUID();
+    private final UUID bundleId1 = UUID.randomUUID();
+    private final UUID bundleId2 = UUID.randomUUID();
     private Clock clock;
     private BlockingCalculator odc;
 
@@ -81,8 +81,8 @@ public class TestBlockingCalculator {
     public void setUpBeforeClass() throws Exception {
 
         clock = new ClockMock();
-        
-        Injector i = Guice.createInjector(new AbstractModule() {
+
+        final Injector i = Guice.createInjector(new AbstractModule() {
 
             @Override
             protected void configure() {
@@ -105,13 +105,13 @@ public class TestBlockingCalculator {
                 ((ZombieControl) subscription2).addResult("getId", UUID.randomUUID());
                 ((ZombieControl) subscription3).addResult("getId", UUID.randomUUID());
                 ((ZombieControl) subscription4).addResult("getId", UUID.randomUUID());
-         
-         
+
+
                 bind(BlockingStateDao.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(BlockingStateDao.class));
-                bind(BlockingApi.class).toInstance(blockingApi);              
-                              
+                bind(BlockingApi.class).toInstance(blockingApi);
+
             }
-            
+
         });
         odc = i.getInstance(BlockingCalculator.class);
 
@@ -123,88 +123,88 @@ public class TestBlockingCalculator {
     // S1 --A-------------------------------------
     // S2 --B------C------------------------------
     // S3 ------------------D---------------------
-    
+
 
     //Result
     // S1 --A--[-------]--------------------------
     // S2 --B--[-------]--------------------------
     // S3 ------------------D---------------------
-    
+
     public void testInsertBlockingEvents() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, null));
-        BillingEvent A = createRealEvent(now.minusDays(1).minusHours(1), subscription1);
-        BillingEvent B = createRealEvent(now.minusDays(1), subscription2);
-        BillingEvent C = createRealEvent(now.plusDays(1), subscription2);
-        BillingEvent D = createRealEvent(now.plusDays(3), subscription3);
+        final BillingEvent A = createRealEvent(now.minusDays(1).minusHours(1), subscription1);
+        final BillingEvent B = createRealEvent(now.minusDays(1), subscription2);
+        final BillingEvent C = createRealEvent(now.plusDays(1), subscription2);
+        final BillingEvent D = createRealEvent(now.plusDays(3), subscription3);
         billingEvents.add(A);
         billingEvents.add(B);
         billingEvents.add(C);
         billingEvents.add(D);
 
-        SortedSet<BlockingState> blockingStates = new TreeSet<BlockingState>();
-        blockingStates.add(new DefaultBlockingState(bundleId1,DISABLED_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now));
-        blockingStates.add(new DefaultBlockingState(bundleId1,CLEAR_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
-        
-        ((ZombieControl)blockingApi).addResult("getBlockingHistory", blockingStates);
-        
-        
+        final SortedSet<BlockingState> blockingStates = new TreeSet<BlockingState>();
+        blockingStates.add(new DefaultBlockingState(bundleId1, DISABLED_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now));
+        blockingStates.add(new DefaultBlockingState(bundleId1, CLEAR_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
+
+        ((ZombieControl) blockingApi).addResult("getBlockingHistory", blockingStates);
+
+
         odc.insertBlockingEvents(billingEvents);
-        
+
         assertEquals(billingEvents.size(), 7);
-        
-        SortedSet<BillingEvent> s1Events = odc.filter(billingEvents, subscription1);
-        Iterator<BillingEvent> it1 = s1Events.iterator();
+
+        final SortedSet<BillingEvent> s1Events = odc.filter(billingEvents, subscription1);
+        final Iterator<BillingEvent> it1 = s1Events.iterator();
         assertEquals(it1.next(), A);
         assertEquals(it1.next().getTransitionType(), SubscriptionTransitionType.CANCEL);
         assertEquals(it1.next().getTransitionType(), SubscriptionTransitionType.RE_CREATE);
-        
-        SortedSet<BillingEvent> s2Events = odc.filter(billingEvents, subscription2);
-        Iterator<BillingEvent> it2 = s2Events.iterator();       
+
+        final SortedSet<BillingEvent> s2Events = odc.filter(billingEvents, subscription2);
+        final Iterator<BillingEvent> it2 = s2Events.iterator();
         assertEquals(it2.next(), B);
         assertEquals(it2.next().getTransitionType(), SubscriptionTransitionType.CANCEL);
         assertEquals(it2.next().getTransitionType(), SubscriptionTransitionType.RE_CREATE);
-                
-        SortedSet<BillingEvent> s3Events = odc.filter(billingEvents, subscription3);
-        Iterator<BillingEvent> it3 = s3Events.iterator();       
-        assertEquals(it3.next(),D);
+
+        final SortedSet<BillingEvent> s3Events = odc.filter(billingEvents, subscription3);
+        final Iterator<BillingEvent> it3 = s3Events.iterator();
+        assertEquals(it3.next(), D);
     }
 
     // Open ended duration with a previous event
     // --X--[----------------------------------
-   @Test
+    @Test
     public void testEventsToRemoveOpenPrev() {
-       DateTime now = clock.getUTCNow();
-       List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-       SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-       
-       disabledDuration.add(new DisabledDuration(now, null));
-       billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
-       
-       SortedSet<BillingEvent> results = odc.eventsToRemove( disabledDuration, billingEvents, subscription1);
-       
-       assertEquals(results.size(), 0);
-   }
-
-   // Open with previous and following events
-   // --X--[----Y-----------------------------
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
+        disabledDuration.add(new DisabledDuration(now, null));
+        billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
+
+        final SortedSet<BillingEvent> results = odc.eventsToRemove(disabledDuration, billingEvents, subscription1);
+
+        assertEquals(results.size(), 0);
+    }
+
+    // Open with previous and following events
+    // --X--[----Y-----------------------------
     @Test
     public void testEventsToRemoveOpenPrevFollow() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, null));
-        BillingEvent e1 = createRealEvent(now.minusDays(1), subscription1);
-        BillingEvent e2  = createRealEvent(now.plusDays(1), subscription1);
+        final BillingEvent e1 = createRealEvent(now.minusDays(1), subscription1);
+        final BillingEvent e2 = createRealEvent(now.plusDays(1), subscription1);
         billingEvents.add(e1);
         billingEvents.add(e2);
-        
-        SortedSet<BillingEvent> results = odc.eventsToRemove( disabledDuration, billingEvents,  subscription1);
-        
+
+        final SortedSet<BillingEvent> results = odc.eventsToRemove(disabledDuration, billingEvents, subscription1);
+
         assertEquals(results.size(), 1);
         assertEquals(results.first(), e2);
     }
@@ -213,54 +213,54 @@ public class TestBlockingCalculator {
     // -----[----X-----------------------------
     @Test
     public void testEventsToRemoveOpenFollow() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, null));
-        BillingEvent e1  = createRealEvent(now.plusDays(1), subscription1);
+        final BillingEvent e1 = createRealEvent(now.plusDays(1), subscription1);
         billingEvents.add(e1);
-        
-        SortedSet<BillingEvent> results = odc.eventsToRemove( disabledDuration, billingEvents,  subscription1);
-        
+
+        final SortedSet<BillingEvent> results = odc.eventsToRemove(disabledDuration, billingEvents, subscription1);
+
         assertEquals(results.size(), 1);
         assertEquals(results.first(), e1);
-   }
+    }
 
     // Closed duration with a single previous event
     // --X--[------------]---------------------
-        @Test
+    @Test
     public void testEventsToRemoveClosedPrev() {
-            DateTime now = clock.getUTCNow();
-            List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-            SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-            
-            disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
-            BillingEvent e1  = createRealEvent(now.minusDays(1), subscription1);
-            billingEvents.add(e1);
-            
-            SortedSet<BillingEvent> results = odc.eventsToRemove( disabledDuration, billingEvents,  subscription1);
-            
-            assertEquals(results.size(), 0);
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
+        disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
+        final BillingEvent e1 = createRealEvent(now.minusDays(1), subscription1);
+        billingEvents.add(e1);
+
+        final SortedSet<BillingEvent> results = odc.eventsToRemove(disabledDuration, billingEvents, subscription1);
+
+        assertEquals(results.size(), 0);
     }
 
     // Closed duration with a previous event and in-between event
     // --X--[------Y-----]---------------------
     @Test
     public void testEventsToRemoveClosedPrevBetw() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
-        BillingEvent e1 = createRealEvent(now.minusDays(1), subscription1);
-        BillingEvent e2  = createRealEvent(now.plusDays(1), subscription1);
+        final BillingEvent e1 = createRealEvent(now.minusDays(1), subscription1);
+        final BillingEvent e2 = createRealEvent(now.plusDays(1), subscription1);
         billingEvents.add(e1);
-        billingEvents.add(e2);        
-       
-        
-        SortedSet<BillingEvent> results = odc.eventsToRemove( disabledDuration, billingEvents, subscription1);
-        
+        billingEvents.add(e2);
+
+
+        final SortedSet<BillingEvent> results = odc.eventsToRemove(disabledDuration, billingEvents, subscription1);
+
         assertEquals(results.size(), 1);
         assertEquals(results.first(), e2);
     }
@@ -269,39 +269,39 @@ public class TestBlockingCalculator {
     // --X--[------Y-----]-------Z-------------
     @Test
     public void testEventsToRemoveClosedPrevBetwNext() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
-        BillingEvent e1 = createRealEvent(now.minusDays(1), subscription1);
-        BillingEvent e2  = createRealEvent(now.plusDays(1), subscription1);
-        BillingEvent e3  = createRealEvent(now.plusDays(3), subscription1);
+        final BillingEvent e1 = createRealEvent(now.minusDays(1), subscription1);
+        final BillingEvent e2 = createRealEvent(now.plusDays(1), subscription1);
+        final BillingEvent e3 = createRealEvent(now.plusDays(3), subscription1);
         billingEvents.add(e1);
-        billingEvents.add(e2);        
-        billingEvents.add(e3);        
-        
-        SortedSet<BillingEvent> results = odc.eventsToRemove( disabledDuration, billingEvents, subscription1);
-        
+        billingEvents.add(e2);
+        billingEvents.add(e3);
+
+        final SortedSet<BillingEvent> results = odc.eventsToRemove(disabledDuration, billingEvents, subscription1);
+
         assertEquals(results.size(), 1);
         assertEquals(results.first(), e2);
-   }
+    }
 
     // Closed with no previous event but in-between events
     // -----[------Y-----]---------------------
     @Test
     public void testEventsToRemoveClosedBetwn() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
-        BillingEvent e2  = createRealEvent(now.plusDays(1), subscription1);
-        billingEvents.add(e2);        
-      
-        
-        SortedSet<BillingEvent> results = odc.eventsToRemove( disabledDuration, billingEvents, subscription1);
-        
+        final BillingEvent e2 = createRealEvent(now.plusDays(1), subscription1);
+        billingEvents.add(e2);
+
+
+        final SortedSet<BillingEvent> results = odc.eventsToRemove(disabledDuration, billingEvents, subscription1);
+
         assertEquals(results.size(), 1);
         assertEquals(results.first(), e2);
     }
@@ -310,19 +310,19 @@ public class TestBlockingCalculator {
     // -----[------Y-----]-------Z-------------
     @Test
     public void testEventsToRemoveClosedBetweenFollow() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
 
-        BillingEvent e2  = createRealEvent(now.plusDays(1), subscription1);
-        BillingEvent e3  = createRealEvent(now.plusDays(3), subscription1);
-        billingEvents.add(e2);        
-        billingEvents.add(e3);        
-        
-        SortedSet<BillingEvent> results = odc.eventsToRemove( disabledDuration, billingEvents, subscription1);
-        
+        final BillingEvent e2 = createRealEvent(now.plusDays(1), subscription1);
+        final BillingEvent e3 = createRealEvent(now.plusDays(3), subscription1);
+        billingEvents.add(e2);
+        billingEvents.add(e3);
+
+        final SortedSet<BillingEvent> results = odc.eventsToRemove(disabledDuration, billingEvents, subscription1);
+
         assertEquals(results.size(), 1);
         assertEquals(results.first(), e2);
     }
@@ -331,54 +331,54 @@ public class TestBlockingCalculator {
     // -----[------------]-------Z-------------
     @Test
     public void testEventsToRemoveClosedFollow() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
 
-        BillingEvent e3  = createRealEvent(now.plusDays(3), subscription1);
-       
-        billingEvents.add(e3);        
-        
-        SortedSet<BillingEvent> results = odc.eventsToRemove( disabledDuration, billingEvents, subscription1);
-        
+        final BillingEvent e3 = createRealEvent(now.plusDays(3), subscription1);
+
+        billingEvents.add(e3);
+
+        final SortedSet<BillingEvent> results = odc.eventsToRemove(disabledDuration, billingEvents, subscription1);
+
         assertEquals(results.size(), 0);
-     }
-    
+    }
+
     // Open ended duration with a previous event
     // --X--[----------------------------------
-   @Test
+    @Test
     public void testCreateNewEventsOpenPrev() {
-       DateTime now = clock.getUTCNow();
-       List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-       SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-       
-       disabledDuration.add(new DisabledDuration(now, null));
-       billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
-       
-       SortedSet<BillingEvent> results = odc.createNewEvents( disabledDuration, billingEvents,  account, subscription1);
-       
-       assertEquals(results.size(), 1);
-       assertEquals(results.first().getEffectiveDate(), now);
-       assertEquals(results.first().getRecurringPrice(), BigDecimal.ZERO);
-       assertEquals(results.first().getTransitionType(), SubscriptionTransitionType.CANCEL);
-   }
-
-   // Open with previous and following events
-   // --X--[----Y-----------------------------
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
+        disabledDuration.add(new DisabledDuration(now, null));
+        billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
+
+        final SortedSet<BillingEvent> results = odc.createNewEvents(disabledDuration, billingEvents, account, subscription1);
+
+        assertEquals(results.size(), 1);
+        assertEquals(results.first().getEffectiveDate(), now);
+        assertEquals(results.first().getRecurringPrice(), BigDecimal.ZERO);
+        assertEquals(results.first().getTransitionType(), SubscriptionTransitionType.CANCEL);
+    }
+
+    // Open with previous and following events
+    // --X--[----Y-----------------------------
     @Test
     public void testCreateNewEventsOpenPrevFollow() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, null));
         billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
         billingEvents.add(createRealEvent(now.plusDays(1), subscription1));
-        
-        SortedSet<BillingEvent> results = odc.createNewEvents( disabledDuration, billingEvents,  account, subscription1);
-        
+
+        final SortedSet<BillingEvent> results = odc.createNewEvents(disabledDuration, billingEvents, account, subscription1);
+
         assertEquals(results.size(), 1);
         assertEquals(results.first().getEffectiveDate(), now);
         assertEquals(results.first().getRecurringPrice(), BigDecimal.ZERO);
@@ -389,54 +389,54 @@ public class TestBlockingCalculator {
     // -----[----X-----------------------------
     @Test
     public void testCreateNewEventsOpenFollow() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, null));
         billingEvents.add(createRealEvent(now.plusDays(1), subscription1));
-        
-        SortedSet<BillingEvent> results = odc.createNewEvents( disabledDuration, billingEvents,  account, subscription1);
-        
+
+        final SortedSet<BillingEvent> results = odc.createNewEvents(disabledDuration, billingEvents, account, subscription1);
+
         assertEquals(results.size(), 0);
-   }
+    }
 
     // Closed duration with a single previous event
     // --X--[------------]---------------------
-        @Test
+    @Test
     public void testCreateNewEventsClosedPrev() {
-            DateTime now = clock.getUTCNow();
-            List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-            SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-            
-            disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
-            billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
-            
-            SortedSet<BillingEvent> results = odc.createNewEvents( disabledDuration, billingEvents,  account, subscription1);
-            
-            assertEquals(results.size(), 2);
-            assertEquals(results.first().getEffectiveDate(), now);
-            assertEquals(results.first().getRecurringPrice(), BigDecimal.ZERO);
-            assertEquals(results.first().getTransitionType(), SubscriptionTransitionType.CANCEL);
-            assertEquals(results.last().getEffectiveDate(), now.plusDays(2));
-            assertEquals(results.last().getRecurringPrice(), billingEvents.first().getRecurringPrice());
-            assertEquals(results.last().getTransitionType(), SubscriptionTransitionType.RE_CREATE);
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
+        disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
+        billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
+
+        final SortedSet<BillingEvent> results = odc.createNewEvents(disabledDuration, billingEvents, account, subscription1);
+
+        assertEquals(results.size(), 2);
+        assertEquals(results.first().getEffectiveDate(), now);
+        assertEquals(results.first().getRecurringPrice(), BigDecimal.ZERO);
+        assertEquals(results.first().getTransitionType(), SubscriptionTransitionType.CANCEL);
+        assertEquals(results.last().getEffectiveDate(), now.plusDays(2));
+        assertEquals(results.last().getRecurringPrice(), billingEvents.first().getRecurringPrice());
+        assertEquals(results.last().getTransitionType(), SubscriptionTransitionType.RE_CREATE);
     }
 
     // Closed duration with a previous event and in-between event
     // --X--[------Y-----]---------------------
     @Test
     public void testCreateNewEventsClosedPrevBetw() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
         billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
         billingEvents.add(createRealEvent(now.plusDays(1), subscription1));
-        
-        SortedSet<BillingEvent> results = odc.createNewEvents( disabledDuration, billingEvents,  account, subscription1);
-        
+
+        final SortedSet<BillingEvent> results = odc.createNewEvents(disabledDuration, billingEvents, account, subscription1);
+
         assertEquals(results.size(), 2);
         assertEquals(results.first().getEffectiveDate(), now);
         assertEquals(results.first().getRecurringPrice(), BigDecimal.ZERO);
@@ -450,17 +450,17 @@ public class TestBlockingCalculator {
     // --X--[------Y-----]-------Z-------------
     @Test
     public void testCreateNewEventsClosedPrevBetwNext() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
         billingEvents.add(createRealEvent(now.minusDays(1), subscription1));
         billingEvents.add(createRealEvent(now.plusDays(1), subscription1));
         billingEvents.add(createRealEvent(now.plusDays(3), subscription1));
-        
-        SortedSet<BillingEvent> results = odc.createNewEvents( disabledDuration, billingEvents,  account, subscription1);
-        
+
+        final SortedSet<BillingEvent> results = odc.createNewEvents(disabledDuration, billingEvents, account, subscription1);
+
         assertEquals(results.size(), 2);
         assertEquals(results.first().getEffectiveDate(), now);
         assertEquals(results.first().getRecurringPrice(), BigDecimal.ZERO);
@@ -468,21 +468,21 @@ public class TestBlockingCalculator {
         assertEquals(results.last().getEffectiveDate(), now.plusDays(2));
         assertEquals(results.last().getRecurringPrice(), billingEvents.first().getRecurringPrice());
         assertEquals(results.last().getTransitionType(), SubscriptionTransitionType.RE_CREATE);
-   }
+    }
 
     // Closed with no previous event but in-between events
     // -----[------Y-----]---------------------
     @Test
     public void testCreateNewEventsClosedBetwn() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
         billingEvents.add(createRealEvent(now.plusDays(1), subscription1));
-        
-        SortedSet<BillingEvent> results = odc.createNewEvents( disabledDuration, billingEvents,  account, subscription1);
-        
+
+        final SortedSet<BillingEvent> results = odc.createNewEvents(disabledDuration, billingEvents, account, subscription1);
+
         assertEquals(results.size(), 1);
         assertEquals(results.last().getEffectiveDate(), now.plusDays(2));
         assertEquals(results.last().getRecurringPrice(), billingEvents.first().getRecurringPrice());
@@ -493,15 +493,15 @@ public class TestBlockingCalculator {
     // -----[------Y-----]-------Z-------------
     @Test
     public void testCreateNewEventsClosedBetweenFollow() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
         billingEvents.add(createRealEvent(now.plusDays(1), subscription1));
-        
-        SortedSet<BillingEvent> results = odc.createNewEvents( disabledDuration, billingEvents,  account, subscription1);
-        
+
+        final SortedSet<BillingEvent> results = odc.createNewEvents(disabledDuration, billingEvents, account, subscription1);
+
         assertEquals(results.size(), 1);
         assertEquals(results.last().getEffectiveDate(), now.plusDays(2));
         assertEquals(results.last().getRecurringPrice(), billingEvents.first().getRecurringPrice());
@@ -512,40 +512,40 @@ public class TestBlockingCalculator {
     // -----[------------]-------Z-------------
     @Test
     public void testCreateNewEventsClosedFollow() {
-        DateTime now = clock.getUTCNow();
-        List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
-        SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
-        
+        final DateTime now = clock.getUTCNow();
+        final List<DisabledDuration> disabledDuration = new ArrayList<BlockingCalculator.DisabledDuration>();
+        final SortedSet<BillingEvent> billingEvents = new TreeSet<BillingEvent>();
+
         disabledDuration.add(new DisabledDuration(now, now.plusDays(2)));
         billingEvents.add(createRealEvent(now.plusDays(3), subscription1));
-        
-        SortedSet<BillingEvent> results = odc.createNewEvents( disabledDuration, billingEvents,  account, subscription1);
-        
+
+        final SortedSet<BillingEvent> results = odc.createNewEvents(disabledDuration, billingEvents, account, subscription1);
+
         assertEquals(results.size(), 0);
-     }
+    }
 
     @Test
     public void testPrecedingBillingEventForSubscription() {
-        DateTime now = new DateTime();
-        
-        SortedSet<BillingEvent> events = new TreeSet<BillingEvent>();
+        final DateTime now = new DateTime();
+
+        final SortedSet<BillingEvent> events = new TreeSet<BillingEvent>();
 
         events.add(createRealEvent(now.minusDays(10), subscription1));
         events.add(createRealEvent(now.minusDays(6), subscription1));
         events.add(createRealEvent(now.minusDays(5), subscription1));
         events.add(createRealEvent(now.minusDays(1), subscription1));
-        
-        BillingEvent minus11 = odc.precedingBillingEventForSubscription(now.minusDays(11), events, subscription1);
+
+        final BillingEvent minus11 = odc.precedingBillingEventForSubscription(now.minusDays(11), events, subscription1);
         assertNull(minus11);
-        
-        BillingEvent minus5andAHalf= odc.precedingBillingEventForSubscription(now.minusDays(5).minusHours(12), events, subscription1);
+
+        final BillingEvent minus5andAHalf = odc.precedingBillingEventForSubscription(now.minusDays(5).minusHours(12), events, subscription1);
         assertNotNull(minus5andAHalf);
         assertEquals(minus5andAHalf.getEffectiveDate(), now.minusDays(6));
-      
-        
+
+
     }
-    
-    protected BillingEvent createRealEvent(DateTime effectiveDate, Subscription subscription) {
+
+    protected BillingEvent createRealEvent(final DateTime effectiveDate, final Subscription subscription) {
         final Account account = this.account;
         final int billCycleDay = 1;
         final PlanPhase planPhase = new MockPlanPhase();
@@ -557,29 +557,29 @@ public class TestBlockingCalculator {
         final BillingModeType billingModeType = BillingModeType.IN_ADVANCE;
         final BillingPeriod billingPeriod = BillingPeriod.MONTHLY;
         final SubscriptionTransitionType type = SubscriptionTransitionType.CHANGE;
-        final Long totalOrdering = 0L; 
+        final Long totalOrdering = 0L;
         final DateTimeZone tz = DateTimeZone.UTC;
 
         return new DefaultBillingEvent(account, subscription, effectiveDate, plan, planPhase,
-                fixedPrice, recurringPrice, currency,
-                billingPeriod, billCycleDay, billingModeType,
-                description, totalOrdering, type, tz);
+                                       fixedPrice, recurringPrice, currency,
+                                       billingPeriod, billCycleDay, billingModeType,
+                                       description, totalOrdering, type, tz);
     }
 
 
     @Test
     public void testFilter() {
-        SortedSet<BillingEvent> events = new TreeSet<BillingEvent>();
-        
+        final SortedSet<BillingEvent> events = new TreeSet<BillingEvent>();
+
         events.add(createBillingEvent(subscription1));
         events.add(createBillingEvent(subscription1));
         events.add(createBillingEvent(subscription1));
         events.add(createBillingEvent(subscription2));
-        
-        SortedSet<BillingEvent> result1 = odc.filter(events, subscription1);
-        SortedSet<BillingEvent> result2 = odc.filter(events, subscription2);
-        SortedSet<BillingEvent> result3 = odc.filter(events, subscription3);
-        
+
+        final SortedSet<BillingEvent> result1 = odc.filter(events, subscription1);
+        final SortedSet<BillingEvent> result2 = odc.filter(events, subscription2);
+        final SortedSet<BillingEvent> result3 = odc.filter(events, subscription3);
+
         assertEquals(result1.size(), 3);
         assertEquals(result1.first().getSubscription(), subscription1);
         assertEquals(result1.last().getSubscription(), subscription1);
@@ -590,147 +590,147 @@ public class TestBlockingCalculator {
 
     @Test
     public void testCreateNewDisableEvent() {
-        DateTime now = clock.getUTCNow();
-        BillingEvent event = new MockBillingEvent();
-        
-        BillingEvent result = odc.createNewDisableEvent(now, event);
-        assertEquals(result.getBillCycleDay(),event.getBillCycleDay());
+        final DateTime now = clock.getUTCNow();
+        final BillingEvent event = new MockBillingEvent();
+
+        final BillingEvent result = odc.createNewDisableEvent(now, event);
+        assertEquals(result.getBillCycleDay(), event.getBillCycleDay());
         assertEquals(result.getEffectiveDate(), now);
         assertEquals(result.getPlanPhase(), event.getPlanPhase());
         assertEquals(result.getPlan(), event.getPlan());
-        assertEquals(result.getFixedPrice(),BigDecimal.ZERO);
+        assertEquals(result.getFixedPrice(), BigDecimal.ZERO);
         assertEquals(result.getRecurringPrice(), BigDecimal.ZERO);
         assertEquals(result.getCurrency(), event.getCurrency());
         assertEquals(result.getDescription(), "");
         assertEquals(result.getBillingMode(), event.getBillingMode());
         assertEquals(result.getBillingPeriod(), event.getBillingPeriod());
-        assertEquals(result.getTransitionType(),  SubscriptionTransitionType.CANCEL);
+        assertEquals(result.getTransitionType(), SubscriptionTransitionType.CANCEL);
         assertEquals(result.getTotalOrdering(), new Long(0));
     }
 
     @Test
     public void testCreateNewReenableEvent() {
-        DateTime now = clock.getUTCNow();
-        BillingEvent event = new MockBillingEvent();
-        
-        BillingEvent result = odc.createNewReenableEvent(now, event);
-        assertEquals(result.getBillCycleDay(),event.getBillCycleDay());
+        final DateTime now = clock.getUTCNow();
+        final BillingEvent event = new MockBillingEvent();
+
+        final BillingEvent result = odc.createNewReenableEvent(now, event);
+        assertEquals(result.getBillCycleDay(), event.getBillCycleDay());
         assertEquals(result.getEffectiveDate(), now);
         assertEquals(result.getPlanPhase(), event.getPlanPhase());
         assertEquals(result.getPlan(), event.getPlan());
-        assertEquals(result.getFixedPrice(),event.getFixedPrice());
+        assertEquals(result.getFixedPrice(), event.getFixedPrice());
         assertEquals(result.getRecurringPrice(), event.getRecurringPrice());
         assertEquals(result.getCurrency(), event.getCurrency());
         assertEquals(result.getDescription(), "");
         assertEquals(result.getBillingMode(), event.getBillingMode());
         assertEquals(result.getBillingPeriod(), event.getBillingPeriod());
-        assertEquals(result.getTransitionType(),  SubscriptionTransitionType.RE_CREATE);
+        assertEquals(result.getTransitionType(), SubscriptionTransitionType.RE_CREATE);
         assertEquals(result.getTotalOrdering(), new Long(0));
     }
-    
+
     private class MockBillingEvent extends DefaultBillingEvent {
         public MockBillingEvent() {
             super(account, subscription1, clock.getUTCNow(), null, null, BigDecimal.ZERO, BigDecimal.TEN, Currency.USD, BillingPeriod.ANNUAL,
-                    4, BillingModeType.IN_ADVANCE, "", 3L, SubscriptionTransitionType.CREATE, DateTimeZone.UTC);
-        }        
+                  4, BillingModeType.IN_ADVANCE, "", 3L, SubscriptionTransitionType.CREATE, DateTimeZone.UTC);
+        }
     }
 
     @Test
     public void testCreateBundleSubscriptionMap() {
-        SortedSet<BillingEvent> events = new TreeSet<BillingEvent>();
+        final SortedSet<BillingEvent> events = new TreeSet<BillingEvent>();
         events.add(createBillingEvent(subscription1));
         events.add(createBillingEvent(subscription2));
         events.add(createBillingEvent(subscription3));
         events.add(createBillingEvent(subscription4));
-        
-        Hashtable<UUID,List<Subscription>> map = odc.createBundleSubscriptionMap(events);
-        
+
+        final Hashtable<UUID, List<Subscription>> map = odc.createBundleSubscriptionMap(events);
+
         assertNotNull(map);
-        assertEquals(map.keySet().size(),2);
+        assertEquals(map.keySet().size(), 2);
         assertEquals(map.get(bundleId1).size(), 3);
         assertEquals(map.get(bundleId2).size(), 1);
-        
+
     }
 
-    private BillingEvent createBillingEvent(Subscription subscription) {
-        BillingEvent result =  BrainDeadProxyFactory.createBrainDeadProxyFor(BillingEvent.class, Comparable.class);
-        ((ZombieControl)result).addResult("getSubscription", subscription);
-        ((ZombieControl)result).addResult("compareTo", 1);
+    private BillingEvent createBillingEvent(final Subscription subscription) {
+        final BillingEvent result = BrainDeadProxyFactory.createBrainDeadProxyFor(BillingEvent.class, Comparable.class);
+        ((ZombieControl) result).addResult("getSubscription", subscription);
+        ((ZombieControl) result).addResult("compareTo", 1);
         return result;
     }
 
     @Test
     public void testCreateDisablePairs() {
         SortedSet<BlockingState> blockingEvents;
-        UUID ovdId = UUID.randomUUID();
-        DateTime now = clock.getUTCNow();
-        
+        final UUID ovdId = UUID.randomUUID();
+        final DateTime now = clock.getUTCNow();
+
         //simple events open clear -> disabled
         blockingEvents = new TreeSet<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId,CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE,"test", false, false, false, now));
-        blockingEvents.add(new DefaultBlockingState(ovdId,DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true,now.plusDays(1)));
-        
+        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now));
+        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
+
         List<DisabledDuration> pairs = odc.createBlockingDurations(blockingEvents);
         assertEquals(pairs.size(), 1);
         assertNotNull(pairs.get(0).getStart());
-        assertEquals(pairs.get(0).getStart(),now.plusDays(1));
+        assertEquals(pairs.get(0).getStart(), now.plusDays(1));
         assertNull(pairs.get(0).getEnd());
-        
+
         //simple events closed clear -> disabled
         blockingEvents = new TreeSet<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId,CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE,"test", false, false, false,now));
-        blockingEvents.add(new DefaultBlockingState(ovdId,DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true,now.plusDays(1)));
-        blockingEvents.add(new DefaultBlockingState(ovdId,CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE,"test", false, false, false,now.plusDays(2)));
-        
+        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now));
+        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
+        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
+
         pairs = odc.createBlockingDurations(blockingEvents);
         assertEquals(pairs.size(), 1);
         assertNotNull(pairs.get(0).getStart());
-        assertEquals(pairs.get(0).getStart(),now.plusDays(1));
+        assertEquals(pairs.get(0).getStart(), now.plusDays(1));
         assertNotNull(pairs.get(0).getEnd());
-        assertEquals(pairs.get(0).getEnd(),now.plusDays(2));
+        assertEquals(pairs.get(0).getEnd(), now.plusDays(2));
 
         //simple BUNDLE events closed clear -> disabled
         blockingEvents = new TreeSet<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId,CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE,"test", false, false, false,now));
-        blockingEvents.add(new DefaultBlockingState(ovdId,DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true,now.plusDays(1)));
-        blockingEvents.add(new DefaultBlockingState(ovdId,CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE,"test", false, false, false,now.plusDays(2)));
-        
+        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now));
+        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
+        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
+
         pairs = odc.createBlockingDurations(blockingEvents);
         assertEquals(pairs.size(), 1);
         assertNotNull(pairs.get(0).getStart());
-        assertEquals(pairs.get(0).getStart(),now.plusDays(1));
+        assertEquals(pairs.get(0).getStart(), now.plusDays(1));
         assertNotNull(pairs.get(0).getEnd());
-        assertEquals(pairs.get(0).getEnd(),now.plusDays(2));
-        
-        
+        assertEquals(pairs.get(0).getEnd(), now.plusDays(2));
+
+
         //two or more disableds in a row
         blockingEvents = new TreeSet<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId,CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE,"test", false, false, false,now));
-        blockingEvents.add(new DefaultBlockingState(ovdId,DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true,now.plusDays(1)));
-        blockingEvents.add(new DefaultBlockingState(ovdId,DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true,now.plusDays(2)));
-        blockingEvents.add(new DefaultBlockingState(ovdId,CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE,"test", false, false, false,now.plusDays(3)));
-        
+        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now));
+        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
+        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(2)));
+        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(3)));
+
         pairs = odc.createBlockingDurations(blockingEvents);
         assertEquals(pairs.size(), 1);
         assertNotNull(pairs.get(0).getStart());
-        assertEquals(pairs.get(0).getStart(),now.plusDays(1));
+        assertEquals(pairs.get(0).getStart(), now.plusDays(1));
         assertNotNull(pairs.get(0).getEnd());
-        assertEquals(pairs.get(0).getEnd(),now.plusDays(3));
+        assertEquals(pairs.get(0).getEnd(), now.plusDays(3));
+
 
-       
         blockingEvents = new TreeSet<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId,CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE,"test", false, false, false,now));
-        blockingEvents.add(new DefaultBlockingState(ovdId,DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true,now.plusDays(1)));
-        blockingEvents.add(new DefaultBlockingState(ovdId,DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true,now.plusDays(2)));
-        blockingEvents.add(new DefaultBlockingState(ovdId,DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true,now.plusDays(3)));
-        blockingEvents.add(new DefaultBlockingState(ovdId,CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE,"test", false, false, false,now.plusDays(4)));
-        
+        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now));
+        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
+        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(2)));
+        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(3)));
+        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(4)));
+
         pairs = odc.createBlockingDurations(blockingEvents);
         assertEquals(pairs.size(), 1);
         assertNotNull(pairs.get(0).getStart());
-        assertEquals(pairs.get(0).getStart(),now.plusDays(1));
+        assertEquals(pairs.get(0).getStart(), now.plusDays(1));
         assertNotNull(pairs.get(0).getEnd());
-        assertEquals(pairs.get(0).getEnd(),now.plusDays(4));
-  
+        assertEquals(pairs.get(0).getEnd(), now.plusDays(4));
+
     }
 }
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestDefaultBillingEvent.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestDefaultBillingEvent.java
index 10fdc1c..6a6abfb 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestDefaultBillingEvent.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestDefaultBillingEvent.java
@@ -16,14 +16,13 @@
 
 package com.ning.billing.junction.plumbing.billing;
 
+import javax.annotation.Nullable;
 import java.math.BigDecimal;
 import java.util.Iterator;
 import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.UUID;
 
-import javax.annotation.Nullable;
-
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.testng.Assert;
@@ -38,125 +37,121 @@ import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
-
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
-import com.ning.billing.entitlement.api.user.Subscription;
-
 import com.ning.billing.entitlement.api.billing.BillingEvent;
 import com.ning.billing.entitlement.api.billing.BillingModeType;
-import com.ning.billing.junction.plumbing.billing.DefaultBillingEvent;
-
+import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 
 public class TestDefaultBillingEvent {
-	public static final UUID ID_ZERO = new UUID(0L,0L);
-	public static final UUID ID_ONE = new UUID(0L,1L);
-	public static final UUID ID_TWO = new UUID(0L,2L);
+    public static final UUID ID_ZERO = new UUID(0L, 0L);
+    public static final UUID ID_ONE = new UUID(0L, 1L);
+    public static final UUID ID_TWO = new UUID(0L, 2L);
 
-	@Test(groups={"fast"})
-	public void testEventOrderingSubscription() {
+    @Test(groups = {"fast"})
+    public void testEventOrderingSubscription() {
 
-		BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
-		BillingEvent event1 = createEvent(subscription(ID_ONE), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
-		BillingEvent event2 = createEvent(subscription(ID_TWO), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+        final BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+        final BillingEvent event1 = createEvent(subscription(ID_ONE), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+        final BillingEvent event2 = createEvent(subscription(ID_TWO), new DateTime("2012-01-31T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
 
-		SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
-		set.add(event2);
-		set.add(event1);
-		set.add(event0);
+        final SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
+        set.add(event2);
+        set.add(event1);
+        set.add(event0);
 
-		Iterator<BillingEvent> it = set.iterator();
+        final Iterator<BillingEvent> it = set.iterator();
 
-		Assert.assertEquals(event0, it.next());
-		Assert.assertEquals(event1, it.next());
-		Assert.assertEquals(event2, it.next());
-	}
+        Assert.assertEquals(event0, it.next());
+        Assert.assertEquals(event1, it.next());
+        Assert.assertEquals(event2, it.next());
+    }
 
-	@Test(groups={"fast"})
-	public void testEventOrderingDate() {
+    @Test(groups = {"fast"})
+    public void testEventOrderingDate() {
 
-		BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
-		BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-02-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
-		BillingEvent event2 = createEvent(subscription(ID_ZERO), new DateTime("2012-03-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+        final BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+        final BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-02-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+        final BillingEvent event2 = createEvent(subscription(ID_ZERO), new DateTime("2012-03-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
 
-		SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
-		set.add(event2);
-		set.add(event1);
-		set.add(event0);
+        final SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
+        set.add(event2);
+        set.add(event1);
+        set.add(event0);
 
-		Iterator<BillingEvent> it = set.iterator();
+        final Iterator<BillingEvent> it = set.iterator();
 
-		Assert.assertEquals(event0, it.next());
-		Assert.assertEquals(event1, it.next());
-		Assert.assertEquals(event2, it.next());
-	}
+        Assert.assertEquals(event0, it.next());
+        Assert.assertEquals(event1, it.next());
+        Assert.assertEquals(event2, it.next());
+    }
 
-	@Test(groups={"fast"})
-	public void testEventTotalOrdering() {
+    @Test(groups = {"fast"})
+    public void testEventTotalOrdering() {
 
-		BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE, 1L);
-		BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CANCEL, 2L);
-		BillingEvent event2 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.RE_CREATE, 3L);
+        final BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE, 1L);
+        final BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CANCEL, 2L);
+        final BillingEvent event2 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.RE_CREATE, 3L);
 
-		SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
-		set.add(event2);
-		set.add(event1);
-		set.add(event0);
+        final SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
+        set.add(event2);
+        set.add(event1);
+        set.add(event0);
 
-		Iterator<BillingEvent> it = set.iterator();
+        final Iterator<BillingEvent> it = set.iterator();
 
-		Assert.assertEquals(event0, it.next());
-		Assert.assertEquals(event1, it.next());
-		Assert.assertEquals(event2, it.next());
-	}
+        Assert.assertEquals(event0, it.next());
+        Assert.assertEquals(event1, it.next());
+        Assert.assertEquals(event2, it.next());
+    }
 
-	@Test(groups={"fast"})
-	public void testEventOrderingMix() {
+    @Test(groups = {"fast"})
+    public void testEventOrderingMix() {
 
-		BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
-		BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-02T00:02:04.000Z"), SubscriptionTransitionType.CHANGE);
-		BillingEvent event2 = createEvent(subscription(ID_ONE), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CANCEL);
+        final BillingEvent event0 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CREATE);
+        final BillingEvent event1 = createEvent(subscription(ID_ZERO), new DateTime("2012-01-02T00:02:04.000Z"), SubscriptionTransitionType.CHANGE);
+        final BillingEvent event2 = createEvent(subscription(ID_ONE), new DateTime("2012-01-01T00:02:04.000Z"), SubscriptionTransitionType.CANCEL);
 
-		SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
-		set.add(event2);
-		set.add(event1);
-		set.add(event0);
+        final SortedSet<BillingEvent> set = new TreeSet<BillingEvent>();
+        set.add(event2);
+        set.add(event1);
+        set.add(event0);
 
-		Iterator<BillingEvent> it = set.iterator();
+        final Iterator<BillingEvent> it = set.iterator();
 
-		Assert.assertEquals(event0, it.next());
-		Assert.assertEquals(event1, it.next());
-		Assert.assertEquals(event2, it.next());
-	}
+        Assert.assertEquals(event0, it.next());
+        Assert.assertEquals(event1, it.next());
+        Assert.assertEquals(event2, it.next());
+    }
 
-    private BillingEvent createEvent(Subscription sub, DateTime effectiveDate, SubscriptionTransitionType type) {
+    private BillingEvent createEvent(final Subscription sub, final DateTime effectiveDate, final SubscriptionTransitionType type) {
         return createEvent(sub, effectiveDate, type, 1L);
     }
 
-    private BillingEvent createEvent(Subscription sub, DateTime effectiveDate, SubscriptionTransitionType type, long totalOrdering) {
-		int billCycleDay = 1;
-
-		Plan shotgun = new MockPlan();
-		PlanPhase shotgunMonthly = createMockMonthlyPlanPhase(null, BigDecimal.ZERO, PhaseType.TRIAL);
-
-		return new DefaultBillingEvent(null, sub , effectiveDate,
-				shotgun, shotgunMonthly,
-				BigDecimal.ZERO, null, Currency.USD, BillingPeriod.NO_BILLING_PERIOD, billCycleDay,
-				BillingModeType.IN_ADVANCE, "Test Event 1", totalOrdering, type, DateTimeZone.UTC);
-	}
-
-	private MockPlanPhase createMockMonthlyPlanPhase(@Nullable final BigDecimal recurringRate,
-			final BigDecimal fixedRate, PhaseType phaseType) {
-		return new MockPlanPhase(new MockInternationalPrice(new DefaultPrice(recurringRate, Currency.USD)),
-				new MockInternationalPrice(new DefaultPrice(fixedRate, Currency.USD)),
-				BillingPeriod.MONTHLY, phaseType);
-	}
-
-	private Subscription subscription(final UUID id) {
-	    Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
-	    ((ZombieControl) subscription).addResult("getId", id);
-	    return subscription;
-	}
+    private BillingEvent createEvent(final Subscription sub, final DateTime effectiveDate, final SubscriptionTransitionType type, final long totalOrdering) {
+        final int billCycleDay = 1;
+
+        final Plan shotgun = new MockPlan();
+        final PlanPhase shotgunMonthly = createMockMonthlyPlanPhase(null, BigDecimal.ZERO, PhaseType.TRIAL);
+
+        return new DefaultBillingEvent(null, sub, effectiveDate,
+                                       shotgun, shotgunMonthly,
+                                       BigDecimal.ZERO, null, Currency.USD, BillingPeriod.NO_BILLING_PERIOD, billCycleDay,
+                                       BillingModeType.IN_ADVANCE, "Test Event 1", totalOrdering, type, DateTimeZone.UTC);
+    }
+
+    private MockPlanPhase createMockMonthlyPlanPhase(@Nullable final BigDecimal recurringRate,
+                                                     final BigDecimal fixedRate, final PhaseType phaseType) {
+        return new MockPlanPhase(new MockInternationalPrice(new DefaultPrice(recurringRate, Currency.USD)),
+                                 new MockInternationalPrice(new DefaultPrice(fixedRate, Currency.USD)),
+                                 BillingPeriod.MONTHLY, phaseType);
+    }
+
+    private Subscription subscription(final UUID id) {
+        final Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+        ((ZombieControl) subscription).addResult("getId", id);
+        return subscription;
+    }
 
 }

overdue/pom.xml 19(+7 -12)

diff --git a/overdue/pom.xml b/overdue/pom.xml
index d421155..3104bae 100644
--- a/overdue/pom.xml
+++ b/overdue/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-overdue</artifactId>
@@ -28,7 +28,7 @@
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-util</artifactId>
         </dependency>
-          <dependency>
+        <dependency>
             <groupId>com.google.inject</groupId>
             <artifactId>guice</artifactId>
             <scope>provided</scope>
@@ -41,27 +41,22 @@
             <groupId>joda-time</groupId>
             <artifactId>joda-time</artifactId>
         </dependency>
-         <dependency>
+        <dependency>
             <groupId>org.jdbi</groupId>
             <artifactId>jdbi</artifactId>
         </dependency>
-        <dependency> 
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
-         </dependency>
-        
+        </dependency>
+
         <!-- TEST SCOPE -->
         <dependency>
             <groupId>org.testng</groupId>
             <artifactId>testng</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <scope>test</scope>
-        </dependency>
-                
+
         <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-util</artifactId>
diff --git a/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckNotifier.java b/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckNotifier.java
index d13fdef..0d58473 100644
--- a/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckNotifier.java
+++ b/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckNotifier.java
@@ -27,47 +27,52 @@ import com.ning.billing.config.NotificationConfig;
 import com.ning.billing.overdue.OverdueProperties;
 import com.ning.billing.overdue.listener.OverdueListener;
 import com.ning.billing.overdue.service.DefaultOverdueService;
+import com.ning.billing.util.notificationq.NotificationKey;
 import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 
-public class DefaultOverdueCheckNotifier implements  OverdueCheckNotifier { 
+public class DefaultOverdueCheckNotifier implements OverdueCheckNotifier {
 
-    private final static Logger log = LoggerFactory.getLogger(DefaultOverdueCheckNotifier.class);
+    private static final Logger log = LoggerFactory.getLogger(DefaultOverdueCheckNotifier.class);
 
     public static final String OVERDUE_CHECK_NOTIFIER_QUEUE = "overdue-check-queue";
 
     private final NotificationQueueService notificationQueueService;
-	private final OverdueProperties config;
+    private final OverdueProperties config;
 
     private NotificationQueue overdueQueue;
-	private final OverdueListener listener;
+    private final OverdueListener listener;
 
     @Inject
-	public DefaultOverdueCheckNotifier(NotificationQueueService notificationQueueService,
-	        OverdueProperties config, OverdueListener listener){
-		this.notificationQueueService = notificationQueueService;
-		this.config = config;
+    public DefaultOverdueCheckNotifier(final NotificationQueueService notificationQueueService,
+            final OverdueProperties config, final OverdueListener listener) {
+        this.notificationQueueService = notificationQueueService;
+        this.config = config;
         this.listener = listener;
-	}
+    }
 
     @Override
     public void initialize() {
-		try {
+        try {
             overdueQueue = notificationQueueService.createNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME,
-            		OVERDUE_CHECK_NOTIFIER_QUEUE,
+                    OVERDUE_CHECK_NOTIFIER_QUEUE,
                     new NotificationQueueHandler() {
                 @Override
-                public void handleReadyNotification(String notificationKey, DateTime eventDate) {
-                	try {
-                 		UUID key = UUID.fromString(notificationKey);
-                        processEvent(key , eventDate);
-                   	} catch (IllegalArgumentException e) {
-                		log.error("The key returned from the NextBillingNotificationQueue is not a valid UUID", e);
-                		return;
-                	}
+                public void handleReadyNotification(final NotificationKey notificationKey, final DateTime eventDate) {
+                    try {
+                        if (! (notificationKey instanceof OverdueCheckNotificationKey)) {
+                            log.error("Overdue service received Unexpected notificationKey {}", notificationKey.getClass().getName());
+                            return;
+                        }
+                        final OverdueCheckNotificationKey key = (OverdueCheckNotificationKey) notificationKey; 
+                        processEvent(key.getUuidKey(), eventDate);
+                    } catch (IllegalArgumentException e) {
+                        log.error("The key returned from the NextBillingNotificationQueue is not a valid UUID", e);
+                        return;
+                    }
 
                 }
             },
@@ -76,11 +81,13 @@ public class DefaultOverdueCheckNotifier implements  OverdueCheckNotifier {
                 public boolean isNotificationProcessingOff() {
                     return config.isNotificationProcessingOff();
                 }
+
                 @Override
                 public long getSleepTimeMs() {
                     return config.getSleepTimeMs();
                 }
-            });
+            }
+            );
         } catch (NotificationQueueAlreadyExists e) {
             throw new RuntimeException(e);
         }
@@ -88,23 +95,23 @@ public class DefaultOverdueCheckNotifier implements  OverdueCheckNotifier {
 
     @Override
     public void start() {
-    	overdueQueue.startQueue();
+        overdueQueue.startQueue();
     }
 
     @Override
     public void stop() {
         if (overdueQueue != null) {
-        	overdueQueue.stopQueue();
-        	try {
-        	    notificationQueueService.deleteNotificationQueue(overdueQueue.getServiceName(), overdueQueue.getQueueName());
-        	} catch (NoSuchNotificationQueue e) {
-        	    log.error("Error deleting a queue by its own name - this should never happen", e);
-        	}
+            overdueQueue.stopQueue();
+            try {
+                notificationQueueService.deleteNotificationQueue(overdueQueue.getServiceName(), overdueQueue.getQueueName());
+            } catch (NoSuchNotificationQueue e) {
+                log.error("Error deleting a queue by its own name - this should never happen", e);
+            }
         }
     }
 
-    private void processEvent(UUID overdueableId, DateTime eventDateTime) {
-        listener.handleNextOverdueCheck(overdueableId); 
+    private void processEvent(final UUID overdueableId, final DateTime eventDateTime) {
+        listener.handleNextOverdueCheck(overdueableId);
     }
 
 
diff --git a/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java b/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java
index 03d4330..79cfdf9 100644
--- a/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java
+++ b/overdue/src/main/java/com/ning/billing/ovedue/notification/DefaultOverdueCheckPoster.java
@@ -16,8 +16,9 @@
 
 package com.ning.billing.ovedue.notification;
 
+import java.io.IOException;
+
 import org.joda.time.DateTime;
-import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -30,45 +31,41 @@ import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
 
 public class DefaultOverdueCheckPoster implements OverdueCheckPoster {
-    private final static Logger log = LoggerFactory.getLogger(DefaultOverdueCheckNotifier.class);
+    private static final Logger log = LoggerFactory.getLogger(DefaultOverdueCheckNotifier.class);
 
-	private final NotificationQueueService notificationQueueService;
+    private final NotificationQueueService notificationQueueService;
 
-	@Inject
+    @Inject
     public DefaultOverdueCheckPoster(
-			NotificationQueueService notificationQueueService) {
-		super();
-		this.notificationQueueService = notificationQueueService;
-	}
+            final NotificationQueueService notificationQueueService) {
+        super();
+        this.notificationQueueService = notificationQueueService;
+    }
 
-	@Override
-	public void insertOverdueCheckNotification(final Blockable overdueable, final DateTime futureNotificationTime) {
-    	NotificationQueue checkOverdueQueue;
-		try {
-			checkOverdueQueue = notificationQueueService.getNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME,
-					DefaultOverdueCheckNotifier.OVERDUE_CHECK_NOTIFIER_QUEUE);
-			 log.info("Queuing overdue check notification. id: {}, timestamp: {}", overdueable.getId().toString(), futureNotificationTime.toString());
+    @Override
+    public void insertOverdueCheckNotification(final Blockable overdueable, final DateTime futureNotificationTime) {
+        final NotificationQueue checkOverdueQueue;
+        try {
+            checkOverdueQueue = notificationQueueService.getNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME,
+                                                                              DefaultOverdueCheckNotifier.OVERDUE_CHECK_NOTIFIER_QUEUE);
+            log.info("Queuing overdue check notification. id: {}, timestamp: {}", overdueable.getId().toString(), futureNotificationTime.toString());
 
-	            checkOverdueQueue.recordFutureNotification(futureNotificationTime, new NotificationKey(){
-	                @Override
-	                public String toString() {
-	                    return overdueable.getId().toString();
-	                }
-	    	    });
-		} catch (NoSuchNotificationQueue e) {
-			log.error("Attempting to put items on a non-existent queue (DefaultOverdueCheck).", e);
-		}
-		
+            checkOverdueQueue.recordFutureNotification(futureNotificationTime, new OverdueCheckNotificationKey(overdueable.getId()));
+        } catch (NoSuchNotificationQueue e) {
+            log.error("Attempting to put items on a non-existent queue (DefaultOverdueCheck).", e);
+        } catch (IOException e) {
+            log.error("Failed to serialize notifcationKey for {}", overdueable.toString());            
+        }
     }
-	
-	
-	@Override
-	public void clearNotificationsFor(final Blockable overdueable) {
-	    NotificationQueue checkOverdueQueue;
+
+
+    @Override
+    public void clearNotificationsFor(final Blockable overdueable) {
+        final NotificationQueue checkOverdueQueue;
         try {
             checkOverdueQueue = notificationQueueService.getNotificationQueue(DefaultOverdueService.OVERDUE_SERVICE_NAME,
-                DefaultOverdueCheckNotifier.OVERDUE_CHECK_NOTIFIER_QUEUE);
-            NotificationKey key = new NotificationKey() {
+                                                                              DefaultOverdueCheckNotifier.OVERDUE_CHECK_NOTIFIER_QUEUE);
+            final NotificationKey key = new NotificationKey() {
                 @Override
                 public String toString() {
                     return overdueable.getId().toString();
@@ -78,6 +75,6 @@ public class DefaultOverdueCheckPoster implements OverdueCheckPoster {
         } catch (NoSuchNotificationQueue e) {
             log.error("Attempting to clear items from a non-existent queue (DefaultOverdueCheck).", e);
         }
-	}
+    }
 
 }
diff --git a/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckNotificationKey.java b/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckNotificationKey.java
new file mode 100644
index 0000000..3483e8d
--- /dev/null
+++ b/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckNotificationKey.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2011 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.ovedue.notification;
+
+import java.util.UUID;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.ning.billing.util.notificationq.DefaultUUIDNotificationKey;
+
+public class OverdueCheckNotificationKey extends DefaultUUIDNotificationKey {
+    @JsonCreator
+    public OverdueCheckNotificationKey(@JsonProperty("uuidKey") UUID uuidKey) {
+        super(uuidKey);
+    }
+}
diff --git a/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckPoster.java b/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckPoster.java
index 3a2aa48..18f492a 100644
--- a/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckPoster.java
+++ b/overdue/src/main/java/com/ning/billing/ovedue/notification/OverdueCheckPoster.java
@@ -17,15 +17,14 @@
 package com.ning.billing.ovedue.notification;
 
 import org.joda.time.DateTime;
-import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
 import com.ning.billing.junction.api.Blockable;
 
 
 public interface OverdueCheckPoster {
 
-	void insertOverdueCheckNotification(Blockable blockable, DateTime futureNotificationTime);
-	
+    void insertOverdueCheckNotification(Blockable blockable, DateTime futureNotificationTime);
+
     void clearNotificationsFor(Blockable blockable);
 
-}
\ No newline at end of file
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
index 5979869..c659083 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/api/DefaultOverdueUserApi.java
@@ -28,7 +28,6 @@ import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.overdue.OverdueApiException;
 import com.ning.billing.overdue.OverdueState;
 import com.ning.billing.overdue.OverdueUserApi;
-import com.ning.billing.overdue.calculator.BillingStateCalculator;
 import com.ning.billing.overdue.config.OverdueConfig;
 import com.ning.billing.overdue.config.api.BillingState;
 import com.ning.billing.overdue.config.api.OverdueError;
@@ -36,55 +35,55 @@ import com.ning.billing.overdue.config.api.OverdueStateSet;
 import com.ning.billing.overdue.wrapper.OverdueWrapper;
 import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
 
-public class DefaultOverdueUserApi implements OverdueUserApi { 
+public class DefaultOverdueUserApi implements OverdueUserApi {
     Logger log = LoggerFactory.getLogger(DefaultOverdueUserApi.class);
-    
+
     private final OverdueWrapperFactory factory;
-    private final BlockingApi accessApi; 
-    
+    private final BlockingApi accessApi;
+
     private OverdueConfig overdueConfig;
-   
+
     @Inject
-    public DefaultOverdueUserApi(OverdueWrapperFactory factory,BlockingApi accessApi, CatalogService catalogService) {
+    public DefaultOverdueUserApi(final OverdueWrapperFactory factory, final BlockingApi accessApi, final CatalogService catalogService) {
         this.factory = factory;
         this.accessApi = accessApi;
     }
-    
+
     @SuppressWarnings("unchecked")
     @Override
-    public <T extends Blockable> OverdueState<T> getOverdueStateFor(T overdueable) throws OverdueError {
+    public <T extends Blockable> OverdueState<T> getOverdueStateFor(final T overdueable) throws OverdueError {
         try {
-            String stateName = accessApi.getBlockingStateFor(overdueable).getStateName();
-            OverdueStateSet<SubscriptionBundle> states = overdueConfig.getBundleStateSet();
+            final String stateName = accessApi.getBlockingStateFor(overdueable).getStateName();
+            final OverdueStateSet<SubscriptionBundle> states = overdueConfig.getBundleStateSet();
             return (OverdueState<T>) states.findState(stateName);
         } catch (OverdueApiException e) {
-            throw new OverdueError(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED,overdueable.getId(), overdueable.getClass().getSimpleName());
+            throw new OverdueError(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED, overdueable.getId(), overdueable.getClass().getSimpleName());
         }
     }
-     
+
     @Override
-    public <T extends Blockable> BillingState<T> getBillingStateFor(T overdueable) throws OverdueError {
+    public <T extends Blockable> BillingState<T> getBillingStateFor(final T overdueable) throws OverdueError {
         log.info(String.format("Billing state of of %s requested", overdueable.getId()));
-        OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(overdueable);
+        final OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(overdueable);
         return wrapper.billingState();
     }
-    
+
     @Override
-    public <T extends Blockable> OverdueState<T> refreshOverdueStateFor(T blockable) throws OverdueError, OverdueApiException {
+    public <T extends Blockable> OverdueState<T> refreshOverdueStateFor(final T blockable) throws OverdueError, OverdueApiException {
         log.info(String.format("Refresh of %s requested", blockable.getId()));
-        OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(blockable);
+        final OverdueWrapper<T> wrapper = factory.createOverdueWrapperFor(blockable);
         return wrapper.refresh();
-    } 
- 
+    }
+
 
     @Override
     public <T extends Blockable> void setOverrideBillingStateForAccount(
-            T overdueable, BillingState<T> state) {
+            final T overdueable, final BillingState<T> state) {
         throw new UnsupportedOperationException();
     }
 
-    public void setOverdueConfig(OverdueConfig config) {
+    public void setOverdueConfig(final OverdueConfig config) {
         this.overdueConfig = config;
     }
- 
+
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
index cc0acb2..3f9704b 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/applicator/OverdueStateApplicator.java
@@ -31,7 +31,7 @@ import com.ning.billing.overdue.OverdueState;
 import com.ning.billing.overdue.config.api.OverdueError;
 import com.ning.billing.util.clock.Clock;
 
-public class OverdueStateApplicator<T extends Blockable>{
+public class OverdueStateApplicator<T extends Blockable> {
 
     private final BlockingApi blockingApi;
     private final Clock clock;
@@ -39,63 +39,63 @@ public class OverdueStateApplicator<T extends Blockable>{
 
 
     @Inject
-    public OverdueStateApplicator(BlockingApi accessApi, Clock clock, OverdueCheckPoster poster) {
+    public OverdueStateApplicator(final BlockingApi accessApi, final Clock clock, final OverdueCheckPoster poster) {
         this.blockingApi = accessApi;
         this.clock = clock;
         this.poster = poster;
     }
 
-    public void apply(T overdueable, String previousOverdueStateName, OverdueState<T> nextOverdueState) throws OverdueError {
-        if(previousOverdueStateName.equals(nextOverdueState.getName())) {
+    public void apply(final T overdueable, final String previousOverdueStateName, final OverdueState<T> nextOverdueState) throws OverdueError {
+        if (previousOverdueStateName.equals(nextOverdueState.getName())) {
             return; // nothing to do
         }
 
         storeNewState(overdueable, nextOverdueState);
         try {
-            Period reevaluationInterval     = nextOverdueState.getReevaluationInterval();
-            if(!nextOverdueState.isClearState()) {
+            final Period reevaluationInterval = nextOverdueState.getReevaluationInterval();
+            if (!nextOverdueState.isClearState()) {
                 createFutureNotification(overdueable, clock.getUTCNow().plus(reevaluationInterval));
             }
-        } catch(OverdueApiException e) {
-            if(e.getCode() != ErrorCode.OVERDUE_NO_REEVALUATION_INTERVAL.getCode()) {
+        } catch (OverdueApiException e) {
+            if (e.getCode() != ErrorCode.OVERDUE_NO_REEVALUATION_INTERVAL.getCode()) {
                 throw new OverdueError(e);
             }
         }
 
-        if(nextOverdueState.isClearState()) {
+        if (nextOverdueState.isClearState()) {
             clear(overdueable);
         }
     }
 
 
-    protected void storeNewState(T blockable, OverdueState<T> nextOverdueState) throws OverdueError {
+    protected void storeNewState(final T blockable, final OverdueState<T> nextOverdueState) throws OverdueError {
         try {
-            blockingApi.setBlockingState(new DefaultBlockingState(blockable.getId(), nextOverdueState.getName(), Blockable.Type.get(blockable), 
-                    OverdueService.OVERDUE_SERVICE_NAME, blockChanges(nextOverdueState), blockEntitlement(nextOverdueState), blockBilling(nextOverdueState)));
+            blockingApi.setBlockingState(new DefaultBlockingState(blockable.getId(), nextOverdueState.getName(), Blockable.Type.get(blockable),
+                                                                  OverdueService.OVERDUE_SERVICE_NAME, blockChanges(nextOverdueState), blockEntitlement(nextOverdueState), blockBilling(nextOverdueState)));
         } catch (Exception e) {
             throw new OverdueError(e, ErrorCode.OVERDUE_CAT_ERROR_ENCOUNTERED, blockable.getId(), blockable.getClass().getName());
         }
     }
 
-    private boolean blockChanges(OverdueState<T> nextOverdueState) {
+    private boolean blockChanges(final OverdueState<T> nextOverdueState) {
         return nextOverdueState.blockChanges();
     }
 
-    private boolean blockBilling(OverdueState<T> nextOverdueState) {
+    private boolean blockBilling(final OverdueState<T> nextOverdueState) {
         return nextOverdueState.disableEntitlementAndChangesBlocked();
     }
 
-    private boolean blockEntitlement(OverdueState<T> nextOverdueState) {
+    private boolean blockEntitlement(final OverdueState<T> nextOverdueState) {
         return nextOverdueState.disableEntitlementAndChangesBlocked();
     }
 
-    protected void createFutureNotification(T overdueable,
-            DateTime timeOfNextCheck) {
+    protected void createFutureNotification(final T overdueable,
+                                            final DateTime timeOfNextCheck) {
         poster.insertOverdueCheckNotification(overdueable, timeOfNextCheck);
 
     }
 
-    protected void clear(T blockable) {
+    protected void clear(final T blockable) {
         //Need to clear the overrride table here too (when we add it)
         poster.clearNotificationsFor(blockable);
     }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
index a6108db..a8cb2a9 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculator.java
@@ -39,28 +39,28 @@ public abstract class BillingStateCalculator<T extends Blockable> {
 
     private final InvoiceUserApi invoiceApi;
     private final Clock clock;
-    
+
     protected class InvoiceDateComparator implements Comparator<Invoice> {
         @Override
-        public int compare(Invoice i1, Invoice i2) {
-            DateTime d1 = i1.getInvoiceDate();
-            DateTime d2 = i2.getInvoiceDate();
-            if(d1.compareTo(d2) == 0) {
+        public int compare(final Invoice i1, final Invoice i2) {
+            final DateTime d1 = i1.getInvoiceDate();
+            final DateTime d2 = i2.getInvoiceDate();
+            if (d1.compareTo(d2) == 0) {
                 return i1.hashCode() - i2.hashCode(); // consistent (arbitrary) resolution for tied dates
             }
             return d1.compareTo(d2);
         }
     }
 
-    @Inject 
-    public BillingStateCalculator(InvoiceUserApi invoiceApi, Clock clock) {
+    @Inject
+    public BillingStateCalculator(final InvoiceUserApi invoiceApi, final Clock clock) {
         this.invoiceApi = invoiceApi;
         this.clock = clock;
     }
-    
+
     public abstract BillingState<T> calculateBillingState(T overdueable) throws OverdueError;
-    
-    protected Invoice earliest(SortedSet<Invoice> unpaidInvoices) {
+
+    protected Invoice earliest(final SortedSet<Invoice> unpaidInvoices) {
         try {
             return unpaidInvoices.first();
         } catch (NoSuchElementException e) {
@@ -68,18 +68,18 @@ public abstract class BillingStateCalculator<T extends Blockable> {
         }
     }
 
-    protected BigDecimal sumBalance(SortedSet<Invoice> unpaidInvoices) {
+    protected BigDecimal sumBalance(final SortedSet<Invoice> unpaidInvoices) {
         BigDecimal sum = BigDecimal.ZERO;
-        Iterator<Invoice> it = unpaidInvoices.iterator();
-        while(it.hasNext()) {
+        final Iterator<Invoice> it = unpaidInvoices.iterator();
+        while (it.hasNext()) {
             sum = sum.add(it.next().getBalance());
         }
         return sum;
     }
 
-    protected SortedSet<Invoice> unpaidInvoicesForAccount(UUID accountId) {
-        Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(accountId, clock.getUTCNow());
-        SortedSet<Invoice> sortedInvoices = new TreeSet<Invoice>(new InvoiceDateComparator());
+    protected SortedSet<Invoice> unpaidInvoicesForAccount(final UUID accountId) {
+        final Collection<Invoice> invoices = invoiceApi.getUnpaidInvoicesByAccountId(accountId, clock.getUTCNow());
+        final SortedSet<Invoice> sortedInvoices = new TreeSet<Invoice>(new InvoiceDateComparator());
         sortedInvoices.addAll(invoices);
         return sortedInvoices;
     }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
index 1292a59..64a3968 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/calculator/BillingStateCalculatorBundle.java
@@ -41,52 +41,52 @@ import com.ning.billing.overdue.config.api.PaymentResponse;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.tag.Tag;
 
-public class BillingStateCalculatorBundle  extends BillingStateCalculator<SubscriptionBundle>{
+public class BillingStateCalculatorBundle extends BillingStateCalculator<SubscriptionBundle> {
 
-    private EntitlementUserApi entitlementApi;
+    private final EntitlementUserApi entitlementApi;
 
-    @Inject 
-    public BillingStateCalculatorBundle(EntitlementUserApi entitlementApi, InvoiceUserApi invoiceApi, Clock clock) {
+    @Inject
+    public BillingStateCalculatorBundle(final EntitlementUserApi entitlementApi, final InvoiceUserApi invoiceApi, final Clock clock) {
         super(invoiceApi, clock);
         this.entitlementApi = entitlementApi;
     }
 
     @Override
-    public BillingStateBundle calculateBillingState(SubscriptionBundle bundle) throws OverdueError {
+    public BillingStateBundle calculateBillingState(final SubscriptionBundle bundle) throws OverdueError {
         try {
-            SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForBundle(bundle.getId(), bundle.getAccountId());
+            final SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForBundle(bundle.getId(), bundle.getAccountId());
 
-            Subscription basePlan = entitlementApi.getBaseSubscription(bundle.getId());
+            final Subscription basePlan = entitlementApi.getBaseSubscription(bundle.getId());
 
-            UUID id = bundle.getId();
-            int numberOfUnpaidInvoices = unpaidInvoices.size(); 
-            BigDecimal unpaidInvoiceBalance = sumBalance(unpaidInvoices);
+            final UUID id = bundle.getId();
+            final int numberOfUnpaidInvoices = unpaidInvoices.size();
+            final BigDecimal unpaidInvoiceBalance = sumBalance(unpaidInvoices);
             DateTime dateOfEarliestUnpaidInvoice = null;
             UUID idOfEarliestUnpaidInvoice = null;
-            Invoice invoice = earliest(unpaidInvoices);
-            if(invoice != null) {
+            final Invoice invoice = earliest(unpaidInvoices);
+            if (invoice != null) {
                 dateOfEarliestUnpaidInvoice = invoice.getInvoiceDate();
                 idOfEarliestUnpaidInvoice = invoice.getId();
             }
-            PaymentResponse responseForLastFailedPayment = PaymentResponse.INSUFFICIENT_FUNDS; //TODO MDW
-            Tag[] tags = new Tag[]{}; //TODO MDW
-            Product basePlanProduct = basePlan.getCurrentPlan().getProduct();
-            BillingPeriod basePlanBillingPeriod = basePlan.getCurrentPlan().getBillingPeriod();
-            PriceList basePlanPriceList = basePlan.getCurrentPriceList();
-            PhaseType basePlanPhaseType = basePlan.getCurrentPhase().getPhaseType();
+            final PaymentResponse responseForLastFailedPayment = PaymentResponse.INSUFFICIENT_FUNDS; //TODO MDW
+            final Tag[] tags = new Tag[]{}; //TODO MDW
+            final Product basePlanProduct = basePlan.getCurrentPlan().getProduct();
+            final BillingPeriod basePlanBillingPeriod = basePlan.getCurrentPlan().getBillingPeriod();
+            final PriceList basePlanPriceList = basePlan.getCurrentPriceList();
+            final PhaseType basePlanPhaseType = basePlan.getCurrentPhase().getPhaseType();
 
 
-            return new BillingStateBundle( 
-                    id, 
-                    numberOfUnpaidInvoices, 
+            return new BillingStateBundle(
+                    id,
+                    numberOfUnpaidInvoices,
                     unpaidInvoiceBalance,
                     dateOfEarliestUnpaidInvoice,
                     idOfEarliestUnpaidInvoice,
                     responseForLastFailedPayment,
-                    tags, 
+                    tags,
                     basePlanProduct,
-                    basePlanBillingPeriod, 
-                    basePlanPriceList, 
+                    basePlanBillingPeriod,
+                    basePlanPriceList,
                     basePlanPhaseType);
         } catch (EntitlementUserApiException e) {
             throw new OverdueError(e);
@@ -94,21 +94,21 @@ public class BillingStateCalculatorBundle  extends BillingStateCalculator<Subscr
 
     }
 
-    public SortedSet<Invoice> unpaidInvoicesForBundle(UUID bundleId, UUID accountId) {
-        SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForAccount(accountId);
-        SortedSet<Invoice> result = new TreeSet<Invoice>(new InvoiceDateComparator());
+    public SortedSet<Invoice> unpaidInvoicesForBundle(final UUID bundleId, final UUID accountId) {
+        final SortedSet<Invoice> unpaidInvoices = unpaidInvoicesForAccount(accountId);
+        final SortedSet<Invoice> result = new TreeSet<Invoice>(new InvoiceDateComparator());
         result.addAll(unpaidInvoices);
-        for(Invoice invoice : unpaidInvoices) {
-            if(!invoiceHasAnItemFromBundle(invoice, bundleId)) {
+        for (final Invoice invoice : unpaidInvoices) {
+            if (!invoiceHasAnItemFromBundle(invoice, bundleId)) {
                 result.remove(invoice);
             }
         }
         return result;
     }
 
-    private boolean invoiceHasAnItemFromBundle(Invoice invoice, UUID bundleId) {
-        for(InvoiceItem item : invoice.getInvoiceItems()) {
-            if(item.getBundleId().equals(bundleId)) {
+    private boolean invoiceHasAnItemFromBundle(final Invoice invoice, final UUID bundleId) {
+        for (final InvoiceItem item : invoice.getInvoiceItems()) {
+            if (item.getBundleId().equals(bundleId)) {
                 return true;
             }
         }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultCondition.java b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultCondition.java
index 6289724..6f43038 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultCondition.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultCondition.java
@@ -16,13 +16,12 @@
 
 package com.ning.billing.overdue.config;
 
-import java.math.BigDecimal;
-import java.net.URI;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
+import java.math.BigDecimal;
+import java.net.URI;
 
 import org.joda.time.DateTime;
 
@@ -40,72 +39,76 @@ import com.ning.billing.util.tag.Tag;
 @XmlAccessorType(XmlAccessType.NONE)
 
 public class DefaultCondition<T extends Blockable> extends ValidatingConfig<OverdueConfig> implements Condition<T> {
-	@XmlElement(required=false, name="numberOfUnpaidInvoicesEqualsOrExceeds")
-	private Integer numberOfUnpaidInvoicesEqualsOrExceeds;
-
-	@XmlElement(required=false, name="totalUnpaidInvoiceBalanceEqualsOrExceeds")
-	private BigDecimal totalUnpaidInvoiceBalanceEqualsOrExceeds;
-
-	@XmlElement(required=false, name="timeSinceEarliestUnpaidInvoiceEqualsOrExceeds")
-	private DefaultDuration timeSinceEarliestUnpaidInvoiceEqualsOrExceeds;
-
-	@XmlElementWrapper(required=false, name="responseForLastFailedPaymentIn")
-	@XmlElement(required=false, name="response")
-	private PaymentResponse[] responseForLastFailedPayment;
-
-	@XmlElement(required=false, name="controlTag")
-	private ControlTagType controlTag;
-	
-	/* (non-Javadoc)
-     * @see com.ning.billing.catalog.overdue.Condition#evaluate(com.ning.billing.catalog.api.overdue.BillingState, org.joda.time.DateTime)
-     */
-	@Override
-    public boolean evaluate(BillingState<T> state, DateTime now) {
-	    DateTime unpaidInvoiceTriggerDate = null;
-	    if( timeSinceEarliestUnpaidInvoiceEqualsOrExceeds != null && state.getDateOfEarliestUnpaidInvoice() != null) {  // no date => no unpaid invoices
-	        unpaidInvoiceTriggerDate = state.getDateOfEarliestUnpaidInvoice().plus(timeSinceEarliestUnpaidInvoiceEqualsOrExceeds.toJodaPeriod());
-	    }
-        
-		return 
-				(numberOfUnpaidInvoicesEqualsOrExceeds == null || state.getNumberOfUnpaidInvoices() >= numberOfUnpaidInvoicesEqualsOrExceeds.intValue() ) &&
-				(totalUnpaidInvoiceBalanceEqualsOrExceeds == null || totalUnpaidInvoiceBalanceEqualsOrExceeds.compareTo(state.getBalanceOfUnpaidInvoices()) <= 0) &&
-				(timeSinceEarliestUnpaidInvoiceEqualsOrExceeds == null ||
-				    (unpaidInvoiceTriggerDate != null && !unpaidInvoiceTriggerDate.isAfter(now))) &&
-				(responseForLastFailedPayment == null || responseIsIn(state.getResponseForLastFailedPayment(), responseForLastFailedPayment)) &&
-				(controlTag == null || isTagIn(controlTag, state.getTags()));
-	}
-	
-	private boolean responseIsIn(PaymentResponse actualResponse,
-			PaymentResponse[] responseForLastFailedPayment) {
-		for(PaymentResponse response: responseForLastFailedPayment) {
-			if(response.equals(actualResponse)) return true;
-		}
-		return false;
-	}
-
-	private boolean isTagIn(ControlTagType tag, Tag[] tags) {
-		for(Tag t : tags) {
-			if (t.getTagDefinitionName().equals(tag.toString())) return true;
-		}
-		return false;
-	}
-
-	@Override
-	public ValidationErrors validate(OverdueConfig root,
-			ValidationErrors errors) {
-		return errors;
-	}
-
-	@Override
-	public void initialize(OverdueConfig root, URI uri) {
-	}
+    @XmlElement(required = false, name = "numberOfUnpaidInvoicesEqualsOrExceeds")
+    private Integer numberOfUnpaidInvoicesEqualsOrExceeds;
+
+    @XmlElement(required = false, name = "totalUnpaidInvoiceBalanceEqualsOrExceeds")
+    private BigDecimal totalUnpaidInvoiceBalanceEqualsOrExceeds;
+
+    @XmlElement(required = false, name = "timeSinceEarliestUnpaidInvoiceEqualsOrExceeds")
+    private DefaultDuration timeSinceEarliestUnpaidInvoiceEqualsOrExceeds;
+
+    @XmlElementWrapper(required = false, name = "responseForLastFailedPaymentIn")
+    @XmlElement(required = false, name = "response")
+    private PaymentResponse[] responseForLastFailedPayment;
+
+    @XmlElement(required = false, name = "controlTag")
+    private ControlTagType controlTag;
+
+    /* (non-Javadoc)
+    * @see com.ning.billing.catalog.overdue.Condition#evaluate(com.ning.billing.catalog.api.overdue.BillingState, org.joda.time.DateTime)
+    */
+    @Override
+    public boolean evaluate(final BillingState<T> state, final DateTime now) {
+        DateTime unpaidInvoiceTriggerDate = null;
+        if (timeSinceEarliestUnpaidInvoiceEqualsOrExceeds != null && state.getDateOfEarliestUnpaidInvoice() != null) {  // no date => no unpaid invoices
+            unpaidInvoiceTriggerDate = state.getDateOfEarliestUnpaidInvoice().plus(timeSinceEarliestUnpaidInvoiceEqualsOrExceeds.toJodaPeriod());
+        }
+
+        return
+                (numberOfUnpaidInvoicesEqualsOrExceeds == null || state.getNumberOfUnpaidInvoices() >= numberOfUnpaidInvoicesEqualsOrExceeds.intValue()) &&
+                        (totalUnpaidInvoiceBalanceEqualsOrExceeds == null || totalUnpaidInvoiceBalanceEqualsOrExceeds.compareTo(state.getBalanceOfUnpaidInvoices()) <= 0) &&
+                        (timeSinceEarliestUnpaidInvoiceEqualsOrExceeds == null ||
+                                (unpaidInvoiceTriggerDate != null && !unpaidInvoiceTriggerDate.isAfter(now))) &&
+                        (responseForLastFailedPayment == null || responseIsIn(state.getResponseForLastFailedPayment(), responseForLastFailedPayment)) &&
+                        (controlTag == null || isTagIn(controlTag, state.getTags()));
+    }
+
+    private boolean responseIsIn(final PaymentResponse actualResponse,
+                                 final PaymentResponse[] responseForLastFailedPayment) {
+        for (final PaymentResponse response : responseForLastFailedPayment) {
+            if (response.equals(actualResponse)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isTagIn(final ControlTagType tag, final Tag[] tags) {
+        for (final Tag t : tags) {
+            if (t.getTagDefinitionName().equals(tag.toString())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public ValidationErrors validate(final OverdueConfig root,
+                                     final ValidationErrors errors) {
+        return errors;
+    }
+
+    @Override
+    public void initialize(final OverdueConfig root, final URI uri) {
+    }
 
     public Duration getTimeOffset() {
         if (timeSinceEarliestUnpaidInvoiceEqualsOrExceeds != null) {
             return timeSinceEarliestUnpaidInvoiceEqualsOrExceeds;
-        } else { 
+        } else {
             return new DefaultDuration().setUnit(TimeUnit.DAYS).setNumber(0); // zero time
         }
-        
+
     }
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultDuration.java b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultDuration.java
index 7301e46..e704ab7 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultDuration.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultDuration.java
@@ -30,17 +30,17 @@ import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultDuration extends ValidatingConfig<OverdueConfig> implements Duration {
-	@XmlElement(required=true)
+    @XmlElement(required = true)
     private TimeUnit unit;
 
-	@XmlElement(required=false)
+    @XmlElement(required = false)
     private Integer number = -1;
-	
+
     /* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IDuration#getUnit()
-	 */
+      * @see com.ning.billing.catalog.IDuration#getUnit()
+      */
     @Override
-	public TimeUnit getUnit() {
+    public TimeUnit getUnit() {
         return unit;
     }
 
@@ -48,13 +48,15 @@ public class DefaultDuration extends ValidatingConfig<OverdueConfig> implements 
 	 * @see com.ning.billing.catalog.IDuration#getLength()
 	 */
     @Override
-	public int getNumber() {
+    public int getNumber() {
         return number;
     }
 
     @Override
-    public DateTime addToDateTime(DateTime dateTime) {
-        if ((number == null) && (unit != TimeUnit.UNLIMITED)) {return dateTime;}
+    public DateTime addToDateTime(final DateTime dateTime) {
+        if ((number == null) && (unit != TimeUnit.UNLIMITED)) {
+            return dateTime;
+        }
 
         switch (unit) {
             case DAYS:
@@ -72,7 +74,9 @@ public class DefaultDuration extends ValidatingConfig<OverdueConfig> implements 
 
     @Override
     public Period toJodaPeriod() {
-        if ((number == null) && (unit != TimeUnit.UNLIMITED)) {return new Period();}
+        if ((number == null) && (unit != TimeUnit.UNLIMITED)) {
+            return new Period();
+        }
 
         switch (unit) {
             case DAYS:
@@ -89,20 +93,20 @@ public class DefaultDuration extends ValidatingConfig<OverdueConfig> implements 
     }
 
     @Override
-	public ValidationErrors validate(OverdueConfig catalog, ValidationErrors errors) {
-		//TODO MDW - Validation TimeUnit UNLIMITED iff number == -1
-		return errors;
-	}
-
-	protected DefaultDuration setUnit(TimeUnit unit) {
-		this.unit = unit;
-		return this;
-	}
-
-	protected DefaultDuration setNumber(Integer number) {
-		this.number = number;
-		return this;
-	}
-	
-	
+    public ValidationErrors validate(final OverdueConfig catalog, final ValidationErrors errors) {
+        //TODO MDW - Validation TimeUnit UNLIMITED iff number == -1
+        return errors;
+    }
+
+    protected DefaultDuration setUnit(final TimeUnit unit) {
+        this.unit = unit;
+        return this;
+    }
+
+    protected DefaultDuration setNumber(final Integer number) {
+        this.number = number;
+        return this;
+    }
+
+
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java
index 2232710..cc4e859 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueState.java
@@ -22,12 +22,10 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlID;
 
-import org.joda.time.DateTime;
 import org.joda.time.Period;
 
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.TimeUnit;
-import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.overdue.OverdueApiException;
 import com.ning.billing.overdue.OverdueState;
@@ -36,114 +34,111 @@ import com.ning.billing.util.config.ValidationError;
 import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class DefaultOverdueState<T extends Blockable> extends ValidatingConfig<OverdueConfig>  implements OverdueState<T> {
+public class DefaultOverdueState<T extends Blockable> extends ValidatingConfig<OverdueConfig> implements OverdueState<T> {
 
     private static final int MAX_NAME_LENGTH = 50;
-    
-    @XmlElement(required=false, name="condition")
-	private DefaultCondition<T> condition;
 
-	@XmlAttribute(required=true, name="name")
+    @XmlElement(required = false, name = "condition")
+    private DefaultCondition<T> condition;
+
+    @XmlAttribute(required = true, name = "name")
     @XmlID
-    private String name; 
+    private String name;
+
+    @XmlElement(required = false, name = "externalMessage")
+    private String externalMessage = "";
 
-	@XmlElement(required=false, name="externalMessage")
-	private String externalMessage = "";
-    
-    @XmlElement(required=false, name="blockChanges")
+    @XmlElement(required = false, name = "blockChanges")
     private Boolean blockChanges = false;
 
-    @XmlElement(required=false, name="disableEntitlementAndChangesBlocked")
+    @XmlElement(required = false, name = "disableEntitlementAndChangesBlocked")
     private Boolean disableEntitlement = false;
-    
-    @XmlElement(required=false, name="daysBetweenPaymentRetries")
-    private Integer daysBetweenPaymentRetries = 8;
-    
-    @XmlElement(required=false, name="isClearState")
+
+    @XmlElement(required = false, name = "isClearState")
     private Boolean isClearState = false;
-    
-    @XmlElement(required=false, name="autoReevaluationInterval")
+
+    @XmlElement(required = false, name = "autoReevaluationInterval")
     private DefaultDuration autoReevaluationInterval;
 
 
-    
-	//Other actions could include
-	// - send email
-	// - trigger payment retry?
-	// - add tagStore to bundle/account
-	// - set payment failure email template
-	// - set payment retry interval
-	// - backup payment mechanism?
+    //Other actions could include
+    // - send email
+    // - trigger payment retry?
+    // - add tagStore to bundle/account
+    // - set payment failure email template
+    // - set payment retry interval
+    // - backup payment mechanism?
 
-	/* (non-Javadoc)
-     * @see com.ning.billing.catalog.overdue.OverdueState#getStageName()
-     */
-	@Override
+    /* (non-Javadoc)
+    * @see com.ning.billing.catalog.overdue.OverdueState#getStageName()
+    */
+    @Override
     public String getName() {
-		return name;
-	}
+        return name;
+    }
 
-	/* (non-Javadoc)
-     * @see com.ning.billing.catalog.overdue.OverdueState#getExternalMessage()
-     */
-	@Override
+    /* (non-Javadoc)
+    * @see com.ning.billing.catalog.overdue.OverdueState#getExternalMessage()
+    */
+    @Override
     public String getExternalMessage() {
-		return externalMessage;
-	}
-	
+        return externalMessage;
+    }
+
     @Override
     public boolean blockChanges() {
         return blockChanges || disableEntitlement;
     }
 
-	/* (non-Javadoc)
-     * @see com.ning.billing.catalog.overdue.OverdueState#applyCancel()
-     */
-	@Override
+    /* (non-Javadoc)
+    * @see com.ning.billing.catalog.overdue.OverdueState#applyCancel()
+    */
+    @Override
     public boolean disableEntitlementAndChangesBlocked() {
-		return disableEntitlement;
-	}
+        return disableEntitlement;
+    }
 
     @Override
     public Period getReevaluationInterval() throws OverdueApiException {
-        if(autoReevaluationInterval == null || autoReevaluationInterval.getUnit() == TimeUnit.UNLIMITED || autoReevaluationInterval.getNumber() == 0) {
+        if (autoReevaluationInterval == null || autoReevaluationInterval.getUnit() == TimeUnit.UNLIMITED || autoReevaluationInterval.getNumber() == 0) {
             throw new OverdueApiException(ErrorCode.OVERDUE_NO_REEVALUATION_INTERVAL, name);
         }
-        return autoReevaluationInterval.toJodaPeriod();       
+        return autoReevaluationInterval.toJodaPeriod();
     }
-	
+
     public DefaultCondition<T> getCondition() {
-		return condition;
-	}
+        return condition;
+    }
 
-	protected DefaultOverdueState<T> setName(String name) {
-		this.name = name;
-		return this;
-	}
+    protected DefaultOverdueState<T> setName(final String name) {
+        this.name = name;
+        return this;
+    }
 
-	protected DefaultOverdueState<T> setClearState(boolean isClearState) {
+    protected DefaultOverdueState<T> setClearState(final boolean isClearState) {
         this.isClearState = isClearState;
         return this;
     }
-	protected DefaultOverdueState<T> setExternalMessage(String externalMessage) {
-		this.externalMessage = externalMessage;
-		return this;
-	}
 
-    protected DefaultOverdueState<T> setDisableEntitlement(boolean cancel) {
+    protected DefaultOverdueState<T> setExternalMessage(final String externalMessage) {
+        this.externalMessage = externalMessage;
+        return this;
+    }
+
+    protected DefaultOverdueState<T> setDisableEntitlement(final boolean cancel) {
         this.disableEntitlement = cancel;
         return this;
     }
 
-    protected DefaultOverdueState<T> setBlockChanges(boolean cancel) {
+    protected DefaultOverdueState<T> setBlockChanges(final boolean cancel) {
         this.blockChanges = cancel;
         return this;
     }
 
-	protected DefaultOverdueState<T> setCondition(DefaultCondition<T> condition) {
-		this.condition = condition;
-		return this;
-	}
+    protected DefaultOverdueState<T> setCondition(final DefaultCondition<T> condition) {
+        this.condition = condition;
+        return this;
+    }
 
     @Override
     public boolean isClearState() {
@@ -151,17 +146,18 @@ public class DefaultOverdueState<T extends Blockable> extends ValidatingConfig<O
     }
 
     @Override
-    public ValidationErrors validate(OverdueConfig root,
-            ValidationErrors errors) {
-        if(name.length() > MAX_NAME_LENGTH) {
-            errors.add(new ValidationError(String.format("Name of state '%s' exceeds the maximum length of %d",name,MAX_NAME_LENGTH),root.getURI(), DefaultOverdueState.class, name));
+    public ValidationErrors validate(final OverdueConfig root,
+                                     final ValidationErrors errors) {
+        if (name.length() > MAX_NAME_LENGTH) {
+            errors.add(new ValidationError(String.format("Name of state '%s' exceeds the maximum length of %d", name, MAX_NAME_LENGTH), root.getURI(), DefaultOverdueState.class, name));
         }
         return errors;
     }
 
     @Override
     public int getDaysBetweenPaymentRetries() {
-         return daysBetweenPaymentRetries;
+        final Integer daysBetweenPaymentRetries = 8;
+        return daysBetweenPaymentRetries;
     }
 
 
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueStateSet.java b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueStateSet.java
index 5493dbc..07d25bc 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueStateSet.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/DefaultOverdueStateSet.java
@@ -20,14 +20,11 @@ import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 
 import org.joda.time.DateTime;
-import org.joda.time.MutablePeriod;
 import org.joda.time.Period;
 
 import com.ning.billing.ErrorCode;
-import com.ning.billing.catalog.api.Duration;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingApi;
-import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.overdue.OverdueApiException;
 import com.ning.billing.overdue.OverdueState;
 import com.ning.billing.overdue.config.api.BillingState;
@@ -38,17 +35,19 @@ import com.ning.billing.util.config.ValidationErrors;
 @XmlAccessorType(XmlAccessType.NONE)
 public abstract class DefaultOverdueStateSet<T extends Blockable> extends ValidatingConfig<OverdueConfig> implements OverdueStateSet<T> {
     private static final Period ZERO_PERIOD = new Period();
-    private DefaultOverdueState<T> clearState = new DefaultOverdueState<T>().setName(BlockingApi.CLEAR_STATE_NAME).setClearState(true);
+    private final DefaultOverdueState<T> clearState = new DefaultOverdueState<T>().setName(BlockingApi.CLEAR_STATE_NAME).setClearState(true);
 
     protected abstract DefaultOverdueState<T>[] getStates();
-    
+
     @Override
-    public OverdueState<T> findState(String stateName) throws OverdueApiException {
-        if(stateName.equals( BlockingApi.CLEAR_STATE_NAME)) {
+    public OverdueState<T> findState(final String stateName) throws OverdueApiException {
+        if (stateName.equals(BlockingApi.CLEAR_STATE_NAME)) {
             return clearState;
         }
-        for(DefaultOverdueState<T> state: getStates()) {
-            if(state.getName().equals(stateName) ) { return state; }
+        for (final DefaultOverdueState<T> state : getStates()) {
+            if (state.getName().equals(stateName)) {
+                return state;
+            }
         }
         throw new OverdueApiException(ErrorCode.CAT_NO_SUCH_OVEDUE_STATE, stateName);
     }
@@ -59,34 +58,34 @@ public abstract class DefaultOverdueStateSet<T extends Blockable> extends Valida
      */
     @Override
     public DefaultOverdueState<T> getClearState() throws OverdueApiException {
-       return clearState;
+        return clearState;
     }
 
     /* (non-Javadoc)
      * @see com.ning.billing.catalog.overdue.OverdueBillingState#calculateOverdueState(com.ning.billing.catalog.api.overdue.BillingState, org.joda.time.DateTime)
      */
     @Override
-    public DefaultOverdueState<T> calculateOverdueState(BillingState<T> billingState, DateTime now) throws OverdueApiException {         
-        for(DefaultOverdueState<T> overdueState : getStates()) {
-            if(overdueState.getCondition().evaluate(billingState, now)) {   
+    public DefaultOverdueState<T> calculateOverdueState(final BillingState<T> billingState, final DateTime now) throws OverdueApiException {
+        for (final DefaultOverdueState<T> overdueState : getStates()) {
+            if (overdueState.getCondition().evaluate(billingState, now)) {
                 return overdueState;
             }
         }
-        return  getClearState();
+        return getClearState();
     }
 
     @Override
-    public ValidationErrors validate(OverdueConfig root,
-            ValidationErrors errors) {
-        for(DefaultOverdueState<T> state: getStates()) {
+    public ValidationErrors validate(final OverdueConfig root,
+                                     final ValidationErrors errors) {
+        for (final DefaultOverdueState<T> state : getStates()) {
             state.validate(root, errors);
         }
         try {
             getClearState();
         } catch (OverdueApiException e) {
-            if(e.getCode() == ErrorCode.CAT_MISSING_CLEAR_STATE.getCode()) {
-                errors.add("Overdue state set is missing a clear state.", 
-                        root.getURI(), this.getClass(), "");
+            if (e.getCode() == ErrorCode.CAT_MISSING_CLEAR_STATE.getCode()) {
+                errors.add("Overdue state set is missing a clear state.",
+                           root.getURI(), this.getClass(), "");
             }
         }
 
@@ -97,5 +96,5 @@ public abstract class DefaultOverdueStateSet<T extends Blockable> extends Valida
     public int size() {
         return getStates().length;
     }
-    
+
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/OverdueConfig.java b/overdue/src/main/java/com/ning/billing/overdue/config/OverdueConfig.java
index 188fdfc..36b97fc 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/config/OverdueConfig.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/OverdueConfig.java
@@ -16,22 +16,21 @@
 
 package com.ning.billing.overdue.config;
 
-import java.net.URI;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import java.net.URI;
 
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationErrors;
 
-@XmlRootElement(name="overdueConfig")
+@XmlRootElement(name = "overdueConfig")
 @XmlAccessorType(XmlAccessType.NONE)
-public class OverdueConfig  extends ValidatingConfig<OverdueConfig> {
+public class OverdueConfig extends ValidatingConfig<OverdueConfig> {
 
-    @XmlElement(required=true, name="bundleOverdueStates")
+    @XmlElement(required = true, name = "bundleOverdueStates")
     private OverdueStatesBundle bundleOverdueStates = new OverdueStatesBundle();
 
     public DefaultOverdueStateSet<SubscriptionBundle> getBundleStateSet() {
@@ -39,12 +38,12 @@ public class OverdueConfig  extends ValidatingConfig<OverdueConfig> {
     }
 
     @Override
-    public ValidationErrors validate(OverdueConfig root,
-            ValidationErrors errors) {
+    public ValidationErrors validate(final OverdueConfig root,
+                                     final ValidationErrors errors) {
         return bundleOverdueStates.validate(root, errors);
     }
-    
-    public OverdueConfig setOverdueStatesBundle(OverdueStatesBundle bundleODS) {
+
+    public OverdueConfig setOverdueStatesBundle(final OverdueStatesBundle bundleODS) {
         this.bundleOverdueStates = bundleODS;
         return this;
     }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/config/OverdueStatesBundle.java b/overdue/src/main/java/com/ning/billing/overdue/config/OverdueStatesBundle.java
index 9f3386b..0eedf8c 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/config/OverdueStatesBundle.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/config/OverdueStatesBundle.java
@@ -20,10 +20,10 @@ import javax.xml.bind.annotation.XmlElement;
 
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 
-public class OverdueStatesBundle extends DefaultOverdueStateSet<SubscriptionBundle>{
+public class OverdueStatesBundle extends DefaultOverdueStateSet<SubscriptionBundle> {
 
     @SuppressWarnings("unchecked")
-    @XmlElement(required=true, name="state")
+    @XmlElement(required = true, name = "state")
     private DefaultOverdueState<SubscriptionBundle>[] bundleOverdueStates = new DefaultOverdueState[0];
 
     @Override
@@ -31,7 +31,7 @@ public class OverdueStatesBundle extends DefaultOverdueStateSet<SubscriptionBund
         return bundleOverdueStates;
     }
 
-    protected OverdueStatesBundle setBundleOverdueStates(DefaultOverdueState<SubscriptionBundle>[] bundleOverdueStates) {
+    protected OverdueStatesBundle setBundleOverdueStates(final DefaultOverdueState<SubscriptionBundle>[] bundleOverdueStates) {
         this.bundleOverdueStates = bundleOverdueStates;
         return this;
     }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/exceptions/OverdueError.java b/overdue/src/main/java/com/ning/billing/overdue/exceptions/OverdueError.java
index 3959408..ff7dc26 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/exceptions/OverdueError.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/exceptions/OverdueError.java
@@ -24,15 +24,15 @@ public class OverdueError extends Error {
         super();
     }
 
-    public OverdueError(String msg, Throwable arg1) {
+    public OverdueError(final String msg, final Throwable arg1) {
         super(msg, arg1);
     }
 
-    public OverdueError(String msg) {
+    public OverdueError(final String msg) {
         super(msg);
     }
 
-    public OverdueError(Throwable msg) {
+    public OverdueError(final Throwable msg) {
         super(msg);
     }
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java b/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java
index cbe5a0a..a81e791 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/glue/DefaultOverdueModule.java
@@ -38,24 +38,24 @@ public class DefaultOverdueModule extends AbstractModule implements OverdueModul
     @Override
     protected void configure() {
         installOverdueUserApi();
-        
+
         // internal bindings
         installOverdueService();
         installOverdueWrapperFactory();
 
         final OverdueProperties config = new ConfigurationObjectFactory(System.getProperties()).build(OverdueProperties.class);
         bind(OverdueProperties.class).toInstance(config);
-        bind(ExtendedOverdueService.class).to(DefaultOverdueService.class).asEagerSingleton();    
+        bind(ExtendedOverdueService.class).to(DefaultOverdueService.class).asEagerSingleton();
         bind(OverdueCheckNotifier.class).to(DefaultOverdueCheckNotifier.class).asEagerSingleton();
         bind(OverdueCheckPoster.class).to(DefaultOverdueCheckPoster.class).asEagerSingleton();
-   }
+    }
 
     protected void installOverdueService() {
-        bind(OverdueService.class).to(DefaultOverdueService.class).asEagerSingleton();    
+        bind(OverdueService.class).to(DefaultOverdueService.class).asEagerSingleton();
     }
 
     protected void installOverdueWrapperFactory() {
-        bind(OverdueWrapperFactory.class).asEagerSingleton();    
+        bind(OverdueWrapperFactory.class).asEagerSingleton();
     }
 
     /* (non-Javadoc)
@@ -63,8 +63,8 @@ public class DefaultOverdueModule extends AbstractModule implements OverdueModul
      */
     @Override
     public void installOverdueUserApi() {
-        bind(OverdueUserApi.class).to(DefaultOverdueUserApi.class).asEagerSingleton();         
+        bind(OverdueUserApi.class).to(DefaultOverdueUserApi.class).asEagerSingleton();
     }
-    
+
 
 }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
index f7b247e..a94448f 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueDispatcher.java
@@ -29,7 +29,6 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.overdue.OverdueApiException;
 import com.ning.billing.overdue.config.api.OverdueError;
-import com.ning.billing.overdue.wrapper.OverdueWrapper;
 import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
 
 public class OverdueDispatcher {
@@ -40,29 +39,29 @@ public class OverdueDispatcher {
 
     @Inject
     public OverdueDispatcher(
-            EntitlementUserApi entitlementUserApi, 
-            OverdueWrapperFactory factory) {
+            final EntitlementUserApi entitlementUserApi,
+            final OverdueWrapperFactory factory) {
         this.entitlementUserApi = entitlementUserApi;
         this.factory = factory;
     }
 
-    public void processOverdueForAccount(UUID accountId) {
-        List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId);
-        for(SubscriptionBundle bundle : bundles) {
+    public void processOverdueForAccount(final UUID accountId) {
+        final List<SubscriptionBundle> bundles = entitlementUserApi.getBundlesForAccount(accountId);
+        for (final SubscriptionBundle bundle : bundles) {
             processOverdue(bundle);
         }
     }
 
-    public void processOverdueForBundle(UUID bundleId) {
+    public void processOverdueForBundle(final UUID bundleId) {
         try {
-            SubscriptionBundle bundle        = entitlementUserApi.getBundleFromId(bundleId);
+            final SubscriptionBundle bundle = entitlementUserApi.getBundleFromId(bundleId);
             processOverdue(bundle);
         } catch (EntitlementUserApiException e) {
             log.error("Error processing Overdue for Bundle with id: " + bundleId.toString(), e);
         }
     }
 
-    public void processOverdue(Blockable blockable) {
+    public void processOverdue(final Blockable blockable) {
         try {
             factory.createOverdueWrapperFor(blockable).refresh();
         } catch (OverdueError e) {
@@ -72,9 +71,9 @@ public class OverdueDispatcher {
         }
     }
 
-    public void processOverdue(UUID blockableId) {
+    public void processOverdue(final UUID blockableId) {
         try {
-        factory.createOverdueWrapperFor(blockableId).refresh();
+            factory.createOverdueWrapperFor(blockableId).refresh();
         } catch (OverdueError e) {
             log.error("Error processing Overdue for Blockable with id: " + blockableId.toString(), e);
         } catch (OverdueApiException e) {
diff --git a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
index 11db1f7..1ab250a 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/listener/OverdueListener.java
@@ -29,10 +29,10 @@ import com.ning.billing.payment.api.PaymentInfoEvent;
 public class OverdueListener {
     OverdueDispatcher dispatcher;
 
-    private final static Logger log = LoggerFactory.getLogger(OverdueListener.class);
+    private static final Logger log = LoggerFactory.getLogger(OverdueListener.class);
 
     @Inject
-    public OverdueListener(OverdueDispatcher dispatcher) {
+    public OverdueListener(final OverdueDispatcher dispatcher) {
         this.dispatcher = dispatcher;
     }
 
@@ -41,15 +41,15 @@ public class OverdueListener {
         log.info(String.format("Received PaymentInfo event %s", event.toString()));
         dispatcher.processOverdueForAccount(event.getAccountId());
     }
- 
+
     @Subscribe
     public void handlePaymentErrorEvent(final PaymentErrorEvent event) {
         log.info(String.format("Received PaymentError event %s", event.toString()));
-        UUID accountId = event.getAccountId();
+        final UUID accountId = event.getAccountId();
         dispatcher.processOverdueForAccount(accountId);
     }
 
-    public void handleNextOverdueCheck(UUID overdueableId) { 
+    public void handleNextOverdueCheck(final UUID overdueableId) {
         log.info(String.format("Received OD checkup notification for %s", overdueableId));
         dispatcher.processOverdue(overdueableId);
     }
diff --git a/overdue/src/main/java/com/ning/billing/overdue/OverdueProperties.java b/overdue/src/main/java/com/ning/billing/overdue/OverdueProperties.java
index 0f6b010..4afe64e 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/OverdueProperties.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/OverdueProperties.java
@@ -23,15 +23,14 @@ import com.ning.billing.config.KillbillConfig;
 import com.ning.billing.config.NotificationConfig;
 
 
-public interface OverdueProperties extends NotificationConfig, KillbillConfig  {
-
+public interface OverdueProperties extends NotificationConfig, KillbillConfig {
     @Override
     @Config("killbill.overdue.engine.notifications.sleep")
     @Default("500")
     public long getSleepTimeMs();
 
     @Override
-    @Config("killbill.notifications.off")
+    @Config("killbill.overdue.engine.notifications.off")
     @Default("false")
     public boolean isNotificationProcessingOff();
 
@@ -39,7 +38,7 @@ public interface OverdueProperties extends NotificationConfig, KillbillConfig  {
     @Default("36")
     public int getNumberOfMonthsInFuture();
 
-    @Config("killbill.overdue.configUri")
+    @Config("killbill.overdue.uri")
     @Default("jar:///com/ning/billing/irs/overdue/Config.xml")
     public String getConfigURI();
-}
\ No newline at end of file
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java b/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java
index e019e01..3df1273 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/service/DefaultOverdueService.java
@@ -46,18 +46,18 @@ public class DefaultOverdueService implements ExtendedOverdueService {
     private final BusService busService;
     private final OverdueListener listener;
     private final OverdueWrapperFactory factory;
-    
+
     private OverdueConfig overdueConfig;
     private boolean isInitialized;
 
     @Inject
     public DefaultOverdueService(
-            OverdueUserApi userApi, 
-            OverdueProperties properties, 
-            OverdueCheckNotifier notifier, 
-            BusService busService,
-            OverdueListener listener,
-            OverdueWrapperFactory factory){
+            final OverdueUserApi userApi,
+            final OverdueProperties properties,
+            final OverdueCheckNotifier notifier,
+            final BusService busService,
+            final OverdueListener listener,
+            final OverdueWrapperFactory factory) {
         this.userApi = userApi;
         this.properties = properties;
         this.notifier = notifier;
@@ -86,7 +86,7 @@ public class DefaultOverdueService implements ExtendedOverdueService {
         if (!isInitialized) {
             try {
                 System.out.println("Overdue config URI" + properties.getConfigURI());
-                URI u = new URI(properties.getConfigURI());
+                final URI u = new URI(properties.getConfigURI());
                 overdueConfig = XMLLoader.getObjectFromUri(u, OverdueConfig.class);
 
                 isInitialized = true;
@@ -97,9 +97,9 @@ public class DefaultOverdueService implements ExtendedOverdueService {
             } catch (Exception e) {
                 throw new ServiceException(e);
             }
-            
+
             factory.setOverdueConfig(overdueConfig);
-            ((DefaultOverdueUserApi)userApi).setOverdueConfig(overdueConfig);
+            ((DefaultOverdueUserApi) userApi).setOverdueConfig(overdueConfig);
         }
     }
 
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
index e3ced50..419e089 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapper.java
@@ -35,11 +35,11 @@ public class OverdueWrapper<T extends Blockable> {
     private final BillingStateCalculator<T> billingStateCalcuator;
     private final OverdueStateApplicator<T> overdueStateApplicator;
 
-    public OverdueWrapper(T overdueable, BlockingApi api,
-            OverdueStateSet<T> overdueStateSet,
-            Clock clock,
-            BillingStateCalculator<T> billingStateCalcuator,
-            OverdueStateApplicator<T> overdueStateApplicator) {
+    public OverdueWrapper(final T overdueable, final BlockingApi api,
+                          final OverdueStateSet<T> overdueStateSet,
+                          final Clock clock,
+                          final BillingStateCalculator<T> billingStateCalcuator,
+                          final OverdueStateApplicator<T> overdueStateApplicator) {
         this.overdueable = overdueable;
         this.overdueStateSet = overdueStateSet;
         this.api = api;
@@ -49,17 +49,17 @@ public class OverdueWrapper<T extends Blockable> {
     }
 
     public OverdueState<T> refresh() throws OverdueError, OverdueApiException {
-        if(overdueStateSet.size() < 1) { // No configuration available
+        if (overdueStateSet.size() < 1) { // No configuration available
             return overdueStateSet.getClearState();
-        } 
-        
-        OverdueState<T> nextOverdueState;
-        BillingState<T> billingState    = billingState();
-        String previousOverdueStateName = api.getBlockingStateFor(overdueable).getStateName();
-        nextOverdueState                = overdueStateSet.calculateOverdueState(billingState, clock.getUTCNow());
+        }
+
+        final OverdueState<T> nextOverdueState;
+        final BillingState<T> billingState = billingState();
+        final String previousOverdueStateName = api.getBlockingStateFor(overdueable).getStateName();
+        nextOverdueState = overdueStateSet.calculateOverdueState(billingState, clock.getUTCNow());
 
-        if(nextOverdueState != null && !previousOverdueStateName.equals(nextOverdueState.getName())) {
-            overdueStateApplicator.apply(overdueable, previousOverdueStateName, nextOverdueState); 
+        if (nextOverdueState != null && !previousOverdueStateName.equals(nextOverdueState.getName())) {
+            overdueStateApplicator.apply(overdueable, previousOverdueStateName, nextOverdueState);
         }
 
         return nextOverdueState;
@@ -69,4 +69,4 @@ public class OverdueWrapper<T extends Blockable> {
     public BillingState<T> billingState() throws OverdueError {
         return billingStateCalcuator.calculateBillingState(overdueable);
     }
-}
\ No newline at end of file
+}
diff --git a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
index 0abc240..aed2aad 100644
--- a/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
+++ b/overdue/src/main/java/com/ning/billing/overdue/wrapper/OverdueWrapperFactory.java
@@ -39,7 +39,7 @@ import com.ning.billing.overdue.config.api.OverdueStateSet;
 import com.ning.billing.util.clock.Clock;
 
 public class OverdueWrapperFactory {
-    private static final Logger log =  LoggerFactory.getLogger(OverdueWrapperFactory.class);
+    private static final Logger log = LoggerFactory.getLogger(OverdueWrapperFactory.class);
 
     private final EntitlementUserApi entitlementApi;
     private final BillingStateCalculatorBundle billingStateCalcuatorBundle;
@@ -49,10 +49,10 @@ public class OverdueWrapperFactory {
     private OverdueConfig config;
 
     @Inject
-    public OverdueWrapperFactory(BlockingApi api, Clock clock, 
-            BillingStateCalculatorBundle billingStateCalcuatorBundle, 
-            OverdueStateApplicator<SubscriptionBundle> overdueStateApplicatorBundle,
-            EntitlementUserApi entitlementApi) {
+    public OverdueWrapperFactory(final BlockingApi api, final Clock clock,
+                                 final BillingStateCalculatorBundle billingStateCalcuatorBundle,
+                                 final OverdueStateApplicator<SubscriptionBundle> overdueStateApplicatorBundle,
+                                 final EntitlementUserApi entitlementApi) {
         this.billingStateCalcuatorBundle = billingStateCalcuatorBundle;
         this.overdueStateApplicatorBundle = overdueStateApplicatorBundle;
         this.entitlementApi = entitlementApi;
@@ -61,39 +61,39 @@ public class OverdueWrapperFactory {
     }
 
     @SuppressWarnings("unchecked")
-    public <T extends Blockable> OverdueWrapper<T> createOverdueWrapperFor(T bloackable) throws OverdueError {
-  
-        if(bloackable instanceof SubscriptionBundle) {
-            return (OverdueWrapper<T>)new OverdueWrapper<SubscriptionBundle>((SubscriptionBundle)bloackable, api, getOverdueStateSetBundle(), 
-                    clock, billingStateCalcuatorBundle, overdueStateApplicatorBundle);
+    public <T extends Blockable> OverdueWrapper<T> createOverdueWrapperFor(final T bloackable) throws OverdueError {
+
+        if (bloackable instanceof SubscriptionBundle) {
+            return (OverdueWrapper<T>) new OverdueWrapper<SubscriptionBundle>((SubscriptionBundle) bloackable, api, getOverdueStateSetBundle(),
+                                                                              clock, billingStateCalcuatorBundle, overdueStateApplicatorBundle);
         } else {
             throw new OverdueError(ErrorCode.OVERDUE_TYPE_NOT_SUPPORTED, bloackable.getId(), bloackable.getClass());
         }
     }
 
     @SuppressWarnings("unchecked")
-    public <T extends Blockable> OverdueWrapper<T> createOverdueWrapperFor(UUID id) throws OverdueError {
-        BlockingState state = api.getBlockingStateFor(id);
+    public <T extends Blockable> OverdueWrapper<T> createOverdueWrapperFor(final UUID id) throws OverdueError {
+        final BlockingState state = api.getBlockingStateFor(id);
 
         try {
             switch (state.getType()) {
-            case SUBSCRIPTION_BUNDLE : {
-                SubscriptionBundle bundle = entitlementApi.getBundleFromId(id);
-                return (OverdueWrapper<T>) new OverdueWrapper<SubscriptionBundle>(bundle, api, getOverdueStateSetBundle(), 
-                        clock, billingStateCalcuatorBundle, overdueStateApplicatorBundle );
-            }
-            default : {
-                throw new OverdueError(ErrorCode.OVERDUE_TYPE_NOT_SUPPORTED, id, state.getType());
+                case SUBSCRIPTION_BUNDLE: {
+                    final SubscriptionBundle bundle = entitlementApi.getBundleFromId(id);
+                    return (OverdueWrapper<T>) new OverdueWrapper<SubscriptionBundle>(bundle, api, getOverdueStateSetBundle(),
+                                                                                      clock, billingStateCalcuatorBundle, overdueStateApplicatorBundle);
+                }
+                default: {
+                    throw new OverdueError(ErrorCode.OVERDUE_TYPE_NOT_SUPPORTED, id, state.getType());
+                }
+
             }
-                
-            }  
         } catch (EntitlementUserApiException e) {
             throw new OverdueError(e);
         }
     }
-    
+
     private OverdueStateSet<SubscriptionBundle> getOverdueStateSetBundle() {
-        if(config == null || config.getBundleStateSet() == null) {
+        if (config == null || config.getBundleStateSet() == null) {
             return new DefaultOverdueStateSet<SubscriptionBundle>() {
 
                 @SuppressWarnings("unchecked")
@@ -103,11 +103,11 @@ public class OverdueWrapperFactory {
                 }
             };
         } else {
-           return config.getBundleStateSet();
+            return config.getBundleStateSet();
         }
     }
-    
-    public void setOverdueConfig(OverdueConfig config) {   
+
+    public void setOverdueConfig(final OverdueConfig config) {
         this.config = config;
     }
 
diff --git a/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java b/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java
index 0dcf12e..a309949 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java
@@ -19,7 +19,6 @@ package com.ning.billing.overdue.applicator;
 import java.util.SortedSet;
 import java.util.UUID;
 
-import org.apache.commons.lang.NotImplementedException;
 import org.joda.time.DateTime;
 
 import com.ning.billing.junction.api.Blockable;
@@ -29,88 +28,85 @@ import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.mock.glue.MockJunctionModule;
 
 public class ApplicatorMockJunctionModule extends MockJunctionModule {
-    
     public static class ApplicatorBlockingApi implements BlockingApi {
-            private BlockingState blockingState;
-
-            public BlockingState getBlockingState() {
-                return blockingState;
-            }
-
-            @Override
-            public BlockingState getBlockingStateFor(Blockable overdueable) {
-                return new BlockingState() {
-
-                    @Override
-                    public String getStateName() {
-                        return BlockingApi.CLEAR_STATE_NAME;
-                    }
-
-                    @Override
-                    public Type getType() {
-
-                        return null;
-                    }
-
-                    @Override
-                    public DateTime getTimestamp() {
-                        return null;
-                    }
-
-                    @Override
-                    public boolean isBlockChange() {
-                        return false;
-                    }
-
-                    @Override
-                    public boolean isBlockEntitlement() {
-                        return false;
-                    }
-
-                    @Override
-                    public boolean isBlockBilling() {
-                        return false;
-                    }
-
-                    @Override
-                    public int compareTo(BlockingState arg0) {
-                        return 0;
-                    }
-
-                    @Override
-                    public String getDescription() {
-                        return null;
-                    }
-                    
-                };
-            }
-
-            @Override
-            public BlockingState getBlockingStateFor(UUID overdueableId) {
-                throw new NotImplementedException();
-            }
-
-            @Override
-            public SortedSet<BlockingState> getBlockingHistory(Blockable overdueable) {
-                throw new NotImplementedException();
-            }
-
-            @Override
-            public SortedSet<BlockingState> getBlockingHistory(UUID overdueableId) {
-                throw new NotImplementedException();
-           }
-
-            @Override
-            public <T extends Blockable> void setBlockingState(BlockingState state) {
-                blockingState = state;
-            }
-            
+        private BlockingState blockingState;
+
+        public BlockingState getBlockingState() {
+            return blockingState;
+        }
+
+        @Override
+        public BlockingState getBlockingStateFor(final Blockable overdueable) {
+            return new BlockingState() {
+
+                @Override
+                public String getStateName() {
+                    return BlockingApi.CLEAR_STATE_NAME;
+                }
+
+                @Override
+                public Type getType() {
+
+                    return null;
+                }
+
+                @Override
+                public DateTime getTimestamp() {
+                    return null;
+                }
+
+                @Override
+                public boolean isBlockChange() {
+                    return false;
+                }
+
+                @Override
+                public boolean isBlockEntitlement() {
+                    return false;
+                }
+
+                @Override
+                public boolean isBlockBilling() {
+                    return false;
+                }
+
+                @Override
+                public int compareTo(final BlockingState arg0) {
+                    return 0;
+                }
+
+                @Override
+                public String getDescription() {
+                    return null;
+                }
+
+            };
+        }
+
+        @Override
+        public BlockingState getBlockingStateFor(final UUID overdueableId) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public SortedSet<BlockingState> getBlockingHistory(final Blockable overdueable) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public SortedSet<BlockingState> getBlockingHistory(final UUID overdueableId) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public <T extends Blockable> void setBlockingState(final BlockingState state) {
+            blockingState = state;
         }
-    
+
+    }
+
     @Override
     public void installBlockingApi() {
-        bind(BlockingApi.class).toInstance(new ApplicatorBlockingApi() );
-        
+        bind(BlockingApi.class).toInstance(new ApplicatorBlockingApi());
     }
-    
-}
\ No newline at end of file
+}
diff --git a/overdue/src/test/java/com/ning/billing/overdue/applicator/TestOverdueStateApplicator.java b/overdue/src/test/java/com/ning/billing/overdue/applicator/TestOverdueStateApplicator.java
index ca6f682..35425d0 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/applicator/TestOverdueStateApplicator.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/applicator/TestOverdueStateApplicator.java
@@ -21,61 +21,47 @@ import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.UUID;
 
-import org.testng.Assert;
-import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
 import com.google.inject.Inject;
-import com.ning.billing.catalog.glue.CatalogModule;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.BlockingApi;
-import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
-import com.ning.billing.mock.glue.MockClockModule;
-import com.ning.billing.mock.glue.MockInvoiceModule;
-import com.ning.billing.mock.glue.MockPaymentModule;
-import com.ning.billing.mock.glue.TestDbiModule;
 import com.ning.billing.overdue.OverdueState;
 import com.ning.billing.overdue.OverdueTestBase;
-import com.ning.billing.overdue.applicator.ApplicatorMockJunctionModule.ApplicatorBlockingApi;
 import com.ning.billing.overdue.config.OverdueConfig;
-import com.ning.billing.overdue.glue.DefaultOverdueModule;
 import com.ning.billing.util.config.XMLLoader;
-import com.ning.billing.util.glue.BusModule;
-import com.ning.billing.util.glue.NotificationQueueModule;
 
 public class TestOverdueStateApplicator extends OverdueTestBase {
     @Inject
     OverdueStateApplicator<SubscriptionBundle> applicator;
-        
-    @Test( groups={"slow"} , enabled = true)
-     public void testApplicator() throws Exception {
-         InputStream is = new ByteArrayInputStream(configXml.getBytes());
-         config = XMLLoader.getObjectFromStreamNoValidation(is,  OverdueConfig.class);
-         overdueWrapperFactory.setOverdueConfig(config);
-         
-         SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
-         ((ZombieControl)bundle).addResult("getId", UUID.randomUUID());
-         
-         OverdueState<SubscriptionBundle> state;
-         
-         state = config.getBundleStateSet().findState("OD1");
-         applicator.apply(bundle, BlockingApi.CLEAR_STATE_NAME, state);
-         checkStateApplied(state);
-         
-        
-         state = config.getBundleStateSet().findState("OD2");
-         applicator.apply(bundle, BlockingApi.CLEAR_STATE_NAME, state);
-         checkStateApplied(state);
-        
-         state = config.getBundleStateSet().findState("OD3");
-         applicator.apply(bundle, BlockingApi.CLEAR_STATE_NAME, state);
-         checkStateApplied(state);
-        
+
+    @Test(groups = {"slow"}, enabled = true)
+    public void testApplicator() throws Exception {
+        final InputStream is = new ByteArrayInputStream(configXml.getBytes());
+        config = XMLLoader.getObjectFromStreamNoValidation(is, OverdueConfig.class);
+        overdueWrapperFactory.setOverdueConfig(config);
+
+        final SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
+        ((ZombieControl) bundle).addResult("getId", UUID.randomUUID());
+
+        OverdueState<SubscriptionBundle> state;
+
+        state = config.getBundleStateSet().findState("OD1");
+        applicator.apply(bundle, BlockingApi.CLEAR_STATE_NAME, state);
+        checkStateApplied(state);
+
+
+        state = config.getBundleStateSet().findState("OD2");
+        applicator.apply(bundle, BlockingApi.CLEAR_STATE_NAME, state);
+        checkStateApplied(state);
+
+        state = config.getBundleStateSet().findState("OD3");
+        applicator.apply(bundle, BlockingApi.CLEAR_STATE_NAME, state);
+        checkStateApplied(state);
+
     }
 
 
-    
-    
 }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
index 9f3c647..8f38f08 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculator.java
@@ -42,62 +42,61 @@ public class TestBillingStateCalculator {
     InvoiceUserApi invoiceApi = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceUserApi.class);
     private int hash = 0;
     DateTime now;
-    
+
     public BillingStateCalculator<SubscriptionBundle> createBSCalc() {
         now = new DateTime();
-        Collection<Invoice> invoices = new ArrayList<Invoice>();
+        final Collection<Invoice> invoices = new ArrayList<Invoice>();
         invoices.add(createInvoice(now, BigDecimal.ZERO, null));
         invoices.add(createInvoice(now.plusDays(1), BigDecimal.TEN, null));
         invoices.add(createInvoice(now.plusDays(2), new BigDecimal("100.0"), null));
-     
-        ((ZombieControl)invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
-            
+
+        ((ZombieControl) invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
+
         return new BillingStateCalculator<SubscriptionBundle>(invoiceApi, clock) {
             @Override
             public BillingState<SubscriptionBundle> calculateBillingState(
-                    SubscriptionBundle overdueable) {
-               return null;
-            }};
+                    final SubscriptionBundle overdueable) {
+                return null;
+            }
+        };
     }
-    
-    public Invoice createInvoice(DateTime date, BigDecimal balance, List<InvoiceItem> invoiceItems) {
-        Invoice invoice = BrainDeadProxyFactory.createBrainDeadProxyFor(Invoice.class);
-        ((ZombieControl)invoice).addResult("getBalance", balance);
-        ((ZombieControl)invoice).addResult("getInvoiceDate", date);
-        ((ZombieControl)invoice).addResult("hashCode", hash++);
-        ((ZombieControl)invoice).addResult("getInvoiceItems", invoiceItems);
-        ((ZombieControl)invoice).addResult("getId", UUID.randomUUID());
-        
+
+    public Invoice createInvoice(final DateTime date, final BigDecimal balance, final List<InvoiceItem> invoiceItems) {
+        final Invoice invoice = BrainDeadProxyFactory.createBrainDeadProxyFor(Invoice.class);
+        ((ZombieControl) invoice).addResult("getBalance", balance);
+        ((ZombieControl) invoice).addResult("getInvoiceDate", date);
+        ((ZombieControl) invoice).addResult("hashCode", hash++);
+        ((ZombieControl) invoice).addResult("getInvoiceItems", invoiceItems);
+        ((ZombieControl) invoice).addResult("getId", UUID.randomUUID());
+
         return invoice;
     }
-    
-    @Test(groups={"fast"}, enabled=true)
+
+    @Test(groups = {"fast"}, enabled = true)
     public void testUnpaidInvoices() {
-        BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
-        SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L,0L));
-        
+        final BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
+        final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L));
+
         Assert.assertEquals(invoices.size(), 3);
         Assert.assertEquals(BigDecimal.ZERO.compareTo(invoices.first().getBalance()), 0);
         Assert.assertEquals(new BigDecimal("100.0").compareTo(invoices.last().getBalance()), 0);
     }
-    
-    @Test(groups={"fast"}, enabled=true)
+
+    @Test(groups = {"fast"}, enabled = true)
     public void testSum() {
-        
-        BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
-        SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L,0L));
+
+        final BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
+        final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L));
         Assert.assertEquals(new BigDecimal("110.0").compareTo(calc.sumBalance(invoices)), 0);
     }
 
-    @Test(groups={"fast"}, enabled=true)
+    @Test(groups = {"fast"}, enabled = true)
     public void testEarliest() {
-        
-        BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
-        SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L,0L));
+
+        final BillingStateCalculator<SubscriptionBundle> calc = createBSCalc();
+        final SortedSet<Invoice> invoices = calc.unpaidInvoicesForAccount(new UUID(0L, 0L));
         Assert.assertEquals(calc.earliest(invoices).getInvoiceDate(), now);
     }
 
-    
-    
-    
+
 }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java
index c2f4baf..dc5b6a4 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/calculator/TestBillingStateCalculatorBundle.java
@@ -44,144 +44,143 @@ import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 
 public class TestBillingStateCalculatorBundle extends TestBillingStateCalculator {
-    
-    
-    private List<InvoiceItem> createInvoiceItems(UUID[] bundleIds) {
-        List<InvoiceItem> result = new ArrayList<InvoiceItem> ();
-        for (UUID id : bundleIds) {
-           InvoiceItem ii = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceItem.class);
-           ((ZombieControl)ii).addResult("getBundleId", id);
-           result.add(ii);
+
+
+    private List<InvoiceItem> createInvoiceItems(final UUID[] bundleIds) {
+        final List<InvoiceItem> result = new ArrayList<InvoiceItem>();
+        for (final UUID id : bundleIds) {
+            final InvoiceItem ii = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceItem.class);
+            ((ZombieControl) ii).addResult("getBundleId", id);
+            result.add(ii);
         }
         return result;
     }
-    
-    @Test(groups = {"fast"}, enabled=true)
+
+    @Test(groups = {"fast"}, enabled = true)
     public void testUnpaidInvoiceForBundle() {
-       UUID thisBundleId = new UUID(0L,0L);
-       UUID thatBundleId = new UUID(0L,1L);
-       
-       now = new DateTime();
-       List<Invoice> invoices = new ArrayList<Invoice>(5);
-       invoices.add(createInvoice(now, BigDecimal.ZERO, createInvoiceItems(new UUID[]{thisBundleId,thatBundleId})));
-       invoices.add(createInvoice(now, BigDecimal.TEN, createInvoiceItems(new UUID[]{thatBundleId})));
-       invoices.add(createInvoice(now, new BigDecimal("100.00"), createInvoiceItems(new UUID[]{thatBundleId,thisBundleId,thatBundleId})));
-       invoices.add(createInvoice(now, new BigDecimal("1000.00"), createInvoiceItems(new UUID[]{thisBundleId})));
-       invoices.add(createInvoice(now, new BigDecimal("10000.00"), createInvoiceItems(new UUID[]{thatBundleId, thisBundleId})));
-       
-       
-       Clock clock = new ClockMock();
-       InvoiceUserApi invoiceApi = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceUserApi.class);
-       EntitlementUserApi entitlementApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
-       ((ZombieControl)invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
-       
-       
-       BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, clock);
-       SortedSet<Invoice> resultinvoices = calc.unpaidInvoicesForBundle(thisBundleId, new UUID(0L,0L));
-       
-       Assert.assertEquals(resultinvoices.size(), 4);
-       Assert.assertEquals(BigDecimal.ZERO.compareTo(resultinvoices.first().getBalance()), 0);
-       Assert.assertEquals(new BigDecimal("10000.0").compareTo(resultinvoices.last().getBalance()), 0);
-       
+        final UUID thisBundleId = new UUID(0L, 0L);
+        final UUID thatBundleId = new UUID(0L, 1L);
+
+        now = new DateTime();
+        final List<Invoice> invoices = new ArrayList<Invoice>(5);
+        invoices.add(createInvoice(now, BigDecimal.ZERO, createInvoiceItems(new UUID[]{thisBundleId, thatBundleId})));
+        invoices.add(createInvoice(now, BigDecimal.TEN, createInvoiceItems(new UUID[]{thatBundleId})));
+        invoices.add(createInvoice(now, new BigDecimal("100.00"), createInvoiceItems(new UUID[]{thatBundleId, thisBundleId, thatBundleId})));
+        invoices.add(createInvoice(now, new BigDecimal("1000.00"), createInvoiceItems(new UUID[]{thisBundleId})));
+        invoices.add(createInvoice(now, new BigDecimal("10000.00"), createInvoiceItems(new UUID[]{thatBundleId, thisBundleId})));
+
+
+        final Clock clock = new ClockMock();
+        final InvoiceUserApi invoiceApi = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceUserApi.class);
+        final EntitlementUserApi entitlementApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
+        ((ZombieControl) invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
+
+
+        final BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, clock);
+        final SortedSet<Invoice> resultinvoices = calc.unpaidInvoicesForBundle(thisBundleId, new UUID(0L, 0L));
+
+        Assert.assertEquals(resultinvoices.size(), 4);
+        Assert.assertEquals(BigDecimal.ZERO.compareTo(resultinvoices.first().getBalance()), 0);
+        Assert.assertEquals(new BigDecimal("10000.0").compareTo(resultinvoices.last().getBalance()), 0);
+
     }
-    
-    @Test(groups = {"fast"}, enabled=true)
+
+    @Test(groups = {"fast"}, enabled = true)
     public void testcalculateBillingStateForBundle() throws Exception {
-        
-       UUID thisBundleId = new UUID(0L,0L);
-       UUID thatBundleId = new UUID(0L,1L);
-       
-       now = new DateTime();
-       List<Invoice> invoices = new ArrayList<Invoice>(5);
-       invoices.add(createInvoice(now.minusDays(5), BigDecimal.ZERO, createInvoiceItems(new UUID[]{thisBundleId,thatBundleId})));
-       invoices.add(createInvoice(now.minusDays(4), BigDecimal.TEN, createInvoiceItems(new UUID[]{thatBundleId})));
-       invoices.add(createInvoice(now.minusDays(3), new BigDecimal("100.00"), createInvoiceItems(new UUID[]{thatBundleId,thisBundleId,thatBundleId})));
-       invoices.add(createInvoice(now.minusDays(2), new BigDecimal("1000.00"), createInvoiceItems(new UUID[]{thisBundleId})));
-       invoices.add(createInvoice(now.minusDays(1), new BigDecimal("10000.00"), createInvoiceItems(new UUID[]{thatBundleId, thisBundleId})));
-       
-       
-       Clock clock = new ClockMock();
-       InvoiceUserApi invoiceApi = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceUserApi.class);
-       ((ZombieControl)invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
-       
-       SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
-       ((ZombieControl)bundle).addResult("getId", thisBundleId);
-       ((ZombieControl)bundle).addResult("getAccountId", UUID.randomUUID());
-       
-       EntitlementUserApi entitlementApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
-       Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
-       ((ZombieControl)entitlementApi).addResult("getBaseSubscription",subscription);
-       
-       Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
-       PriceList pricelist = new MockPriceList();
-       ((ZombieControl)subscription).addResult("getCurrentPlan", plan);
-       ((ZombieControl)subscription).addResult("getCurrentPriceList", pricelist);
-       ((ZombieControl)subscription).addResult("getCurrentPhase", plan.getFinalPhase());
-      
-       BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, clock);
-            
-       BillingStateBundle state = calc.calculateBillingState(bundle); 
-       
-       Assert.assertEquals(state.getNumberOfUnpaidInvoices(),4);
-       Assert.assertEquals(state.getBalanceOfUnpaidInvoices().intValue(), 11100);
-       Assert.assertEquals(state.getDateOfEarliestUnpaidInvoice().compareTo(now.minusDays(5)), 0);
-       Assert.assertEquals(state.getResponseForLastFailedPayment(),PaymentResponse.INSUFFICIENT_FUNDS); //TODO needs more when implemented
-       Assert.assertEquals(state.getTags().length,0);//TODO needs more when implemented
-       Assert.assertEquals(state.getBasePlanBillingPeriod(), plan.getBillingPeriod());
-       Assert.assertEquals(state.getBasePlanPhaseType(), plan.getFinalPhase().getPhaseType());
-       Assert.assertEquals(state.getBasePlanPriceList(), pricelist);
-       Assert.assertEquals(state.getBasePlanProduct(), plan.getProduct());
-       
+
+        final UUID thisBundleId = new UUID(0L, 0L);
+        final UUID thatBundleId = new UUID(0L, 1L);
+
+        now = new DateTime();
+        final List<Invoice> invoices = new ArrayList<Invoice>(5);
+        invoices.add(createInvoice(now.minusDays(5), BigDecimal.ZERO, createInvoiceItems(new UUID[]{thisBundleId, thatBundleId})));
+        invoices.add(createInvoice(now.minusDays(4), BigDecimal.TEN, createInvoiceItems(new UUID[]{thatBundleId})));
+        invoices.add(createInvoice(now.minusDays(3), new BigDecimal("100.00"), createInvoiceItems(new UUID[]{thatBundleId, thisBundleId, thatBundleId})));
+        invoices.add(createInvoice(now.minusDays(2), new BigDecimal("1000.00"), createInvoiceItems(new UUID[]{thisBundleId})));
+        invoices.add(createInvoice(now.minusDays(1), new BigDecimal("10000.00"), createInvoiceItems(new UUID[]{thatBundleId, thisBundleId})));
+
+
+        final Clock clock = new ClockMock();
+        final InvoiceUserApi invoiceApi = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceUserApi.class);
+        ((ZombieControl) invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
+
+        final SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
+        ((ZombieControl) bundle).addResult("getId", thisBundleId);
+        ((ZombieControl) bundle).addResult("getAccountId", UUID.randomUUID());
+
+        final EntitlementUserApi entitlementApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
+        final Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+        ((ZombieControl) entitlementApi).addResult("getBaseSubscription", subscription);
+
+        final Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
+        final PriceList pricelist = new MockPriceList();
+        ((ZombieControl) subscription).addResult("getCurrentPlan", plan);
+        ((ZombieControl) subscription).addResult("getCurrentPriceList", pricelist);
+        ((ZombieControl) subscription).addResult("getCurrentPhase", plan.getFinalPhase());
+
+        final BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, clock);
+
+        final BillingStateBundle state = calc.calculateBillingState(bundle);
+
+        Assert.assertEquals(state.getNumberOfUnpaidInvoices(), 4);
+        Assert.assertEquals(state.getBalanceOfUnpaidInvoices().intValue(), 11100);
+        Assert.assertEquals(state.getDateOfEarliestUnpaidInvoice().compareTo(now.minusDays(5)), 0);
+        Assert.assertEquals(state.getResponseForLastFailedPayment(), PaymentResponse.INSUFFICIENT_FUNDS); //TODO needs more when implemented
+        Assert.assertEquals(state.getTags().length, 0);//TODO needs more when implemented
+        Assert.assertEquals(state.getBasePlanBillingPeriod(), plan.getBillingPeriod());
+        Assert.assertEquals(state.getBasePlanPhaseType(), plan.getFinalPhase().getPhaseType());
+        Assert.assertEquals(state.getBasePlanPriceList(), pricelist);
+        Assert.assertEquals(state.getBasePlanProduct(), plan.getProduct());
+
     }
-    
-    
-    @Test(groups = {"fast"}, enabled=true)
+
+
+    @Test(groups = {"fast"}, enabled = true)
     public void testcalculateBillingStateForBundleNoOverdueInvoices() throws Exception {
-        
-       UUID thisBundleId = new UUID(0L,0L);
-       UUID thatBundleId = new UUID(0L,1L);
-       
-       now = new DateTime();
-       List<Invoice> invoices = new ArrayList<Invoice>(5);
-      
-       Clock clock = new ClockMock();
-       InvoiceUserApi invoiceApi = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceUserApi.class);
-       ((ZombieControl)invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
-       
-       SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
-       ((ZombieControl)bundle).addResult("getId", thisBundleId);
-       ((ZombieControl)bundle).addResult("getAccountId", UUID.randomUUID());
-       
-       EntitlementUserApi entitlementApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
-       Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
-       ((ZombieControl)entitlementApi).addResult("getBaseSubscription",subscription);
-       
-       Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
-       PriceList pricelist = new MockPriceList();
-       ((ZombieControl)subscription).addResult("getCurrentPlan", plan);
-       ((ZombieControl)subscription).addResult("getCurrentPriceList", pricelist);
-       ((ZombieControl)subscription).addResult("getCurrentPhase", plan.getFinalPhase());
-      
-       BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, clock);
-            
-       BillingStateBundle state = calc.calculateBillingState(bundle); 
-       
-       Assert.assertEquals(state.getNumberOfUnpaidInvoices(),0);
-       Assert.assertEquals(state.getBalanceOfUnpaidInvoices().intValue(), 0);
-       Assert.assertEquals(state.getDateOfEarliestUnpaidInvoice(), null);
-       Assert.assertEquals(state.getResponseForLastFailedPayment(),PaymentResponse.INSUFFICIENT_FUNDS); //TODO needs more when implemented
-       Assert.assertEquals(state.getTags().length,0);//TODO needs more when implemented
-       Assert.assertEquals(state.getBasePlanBillingPeriod(), plan.getBillingPeriod());
-       Assert.assertEquals(state.getBasePlanPhaseType(), plan.getFinalPhase().getPhaseType());
-       Assert.assertEquals(state.getBasePlanPriceList(), pricelist);
-       Assert.assertEquals(state.getBasePlanProduct(), plan.getProduct());
-       
+
+        final UUID thisBundleId = new UUID(0L, 0L);
+        final UUID thatBundleId = new UUID(0L, 1L);
+
+        now = new DateTime();
+        final List<Invoice> invoices = new ArrayList<Invoice>(5);
+
+        final Clock clock = new ClockMock();
+        final InvoiceUserApi invoiceApi = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceUserApi.class);
+        ((ZombieControl) invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
+
+        final SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
+        ((ZombieControl) bundle).addResult("getId", thisBundleId);
+        ((ZombieControl) bundle).addResult("getAccountId", UUID.randomUUID());
+
+        final EntitlementUserApi entitlementApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
+        final Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+        ((ZombieControl) entitlementApi).addResult("getBaseSubscription", subscription);
+
+        final Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
+        final PriceList pricelist = new MockPriceList();
+        ((ZombieControl) subscription).addResult("getCurrentPlan", plan);
+        ((ZombieControl) subscription).addResult("getCurrentPriceList", pricelist);
+        ((ZombieControl) subscription).addResult("getCurrentPhase", plan.getFinalPhase());
+
+        final BillingStateCalculatorBundle calc = new BillingStateCalculatorBundle(entitlementApi, invoiceApi, clock);
+
+        final BillingStateBundle state = calc.calculateBillingState(bundle);
+
+        Assert.assertEquals(state.getNumberOfUnpaidInvoices(), 0);
+        Assert.assertEquals(state.getBalanceOfUnpaidInvoices().intValue(), 0);
+        Assert.assertEquals(state.getDateOfEarliestUnpaidInvoice(), null);
+        Assert.assertEquals(state.getResponseForLastFailedPayment(), PaymentResponse.INSUFFICIENT_FUNDS); //TODO needs more when implemented
+        Assert.assertEquals(state.getTags().length, 0);//TODO needs more when implemented
+        Assert.assertEquals(state.getBasePlanBillingPeriod(), plan.getBillingPeriod());
+        Assert.assertEquals(state.getBasePlanPhaseType(), plan.getFinalPhase().getPhaseType());
+        Assert.assertEquals(state.getBasePlanPriceList(), pricelist);
+        Assert.assertEquals(state.getBasePlanProduct(), plan.getProduct());
+
     }
-    
+
     public void testCorrectBehaviorForNoOverdueConfig() {
         //TODO with no overdue config the system should be fine - take no action but see no NPEs
     }
-    
-    
-    
+
+
 }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/config/CreateOverdueConfigSchema.java b/overdue/src/test/java/com/ning/billing/overdue/config/CreateOverdueConfigSchema.java
index bbd4b18..b801a2d 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/config/CreateOverdueConfigSchema.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/config/CreateOverdueConfigSchema.java
@@ -24,20 +24,20 @@ import com.ning.billing.util.config.XMLSchemaGenerator;
 
 public class CreateOverdueConfigSchema {
 
-	/**
-	 * @param args
-	 */
-	public static void main(String[] args) throws Exception {
-		if(args.length != 1) {
-			System.err.println("Usage: <filepath>");
-			System.exit(0);
-		}
-		
-		File f = new File(args[0]);
-		Writer w = new FileWriter(f);
-		w.write(XMLSchemaGenerator.xmlSchemaAsString(OverdueConfig.class));
-		w.close();
-
-	}
+    /**
+     * @param args
+     */
+    public static void main(final String[] args) throws Exception {
+        if (args.length != 1) {
+            System.err.println("Usage: <filepath>");
+            System.exit(0);
+        }
+
+        final File f = new File(args[0]);
+        final Writer w = new FileWriter(f);
+        w.write(XMLSchemaGenerator.xmlSchemaAsString(OverdueConfig.class));
+        w.close();
+
+    }
 
 }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/config/io/TestReadConfig.java b/overdue/src/test/java/com/ning/billing/overdue/config/io/TestReadConfig.java
index 8208a73..75b3239 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/config/io/TestReadConfig.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/config/io/TestReadConfig.java
@@ -23,7 +23,7 @@ import com.ning.billing.overdue.config.OverdueConfig;
 import com.ning.billing.util.config.XMLLoader;
 
 public class TestReadConfig {
-    @Test(enabled=true) 
+    @Test(enabled = true)
     public void testConfigLoad() throws Exception {
         XMLLoader.getObjectFromString(Resources.getResource("OverdueConfig.xml").toExternalForm(), OverdueConfig.class);
     }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueRules.java b/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueRules.java
index 514c85f..1452d9e 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueRules.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueRules.java
@@ -21,12 +21,12 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 
 
 public class MockOverdueRules extends OverdueConfig {
-    public static final String CLEAR_STATE="Clear";
+    public static final String CLEAR_STATE = "Clear";
 
     @SuppressWarnings("unchecked")
     public MockOverdueRules() {
-        OverdueStatesBundle bundleODS =  new OverdueStatesBundle();
-        bundleODS.setBundleOverdueStates(new DefaultOverdueState[] { new DefaultOverdueState<SubscriptionBundle>().setName(CLEAR_STATE) });
+        final OverdueStatesBundle bundleODS = new OverdueStatesBundle();
+        bundleODS.setBundleOverdueStates(new DefaultOverdueState[]{new DefaultOverdueState<SubscriptionBundle>().setName(CLEAR_STATE)});
         setOverdueStatesBundle(bundleODS);
 
     }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueState.java b/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueState.java
index d1b9ab1..6ea4ab3 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueState.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueState.java
@@ -19,12 +19,12 @@ package com.ning.billing.overdue.config;
 import com.ning.billing.junction.api.Blockable;
 
 public class MockOverdueState<T extends Blockable> extends DefaultOverdueState<T> {
-    
+
     public MockOverdueState() {
         setName(MockOverdueRules.CLEAR_STATE);
     }
 
-    public MockOverdueState(String name, boolean blockChanges, boolean disableEntitlementAndBlockChanges) {
+    public MockOverdueState(final String name, final boolean blockChanges, final boolean disableEntitlementAndBlockChanges) {
         setName(name);
         setBlockChanges(blockChanges);
         setDisableEntitlement(disableEntitlementAndBlockChanges);
diff --git a/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueStatesBundle.java b/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueStatesBundle.java
index f1020b2..3519b7d 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueStatesBundle.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/config/MockOverdueStatesBundle.java
@@ -21,11 +21,11 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 public class MockOverdueStatesBundle extends OverdueStatesBundle {
 
     public MockOverdueStatesBundle() {
-        
+
     }
-    
-   public MockOverdueStatesBundle(DefaultOverdueState<SubscriptionBundle>[] states) {
-       setBundleOverdueStates(states);
+
+    public MockOverdueStatesBundle(final DefaultOverdueState<SubscriptionBundle>[] states) {
+        setBundleOverdueStates(states);
     }
 
 }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/config/TestCondition.java b/overdue/src/test/java/com/ning/billing/overdue/config/TestCondition.java
index 08325f2..508dcb4 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/config/TestCondition.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/config/TestCondition.java
@@ -16,13 +16,12 @@
 
 package com.ning.billing.overdue.config;
 
+import javax.xml.bind.annotation.XmlRootElement;
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.math.BigDecimal;
 import java.util.UUID;
 
-import javax.xml.bind.annotation.XmlRootElement;
-
 import org.joda.time.DateTime;
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -37,116 +36,115 @@ import com.ning.billing.util.tag.DescriptiveTag;
 import com.ning.billing.util.tag.Tag;
 
 public class TestCondition {
-	
-	@XmlRootElement(name="condition")
-	private static class MockCondition extends DefaultCondition<Blockable> {}
-
-	@Test(groups={"fast"}, enabled=true)
-	public void testNumberOfUnpaidInvoicesEqualsOrExceeds() throws Exception {
-		String xml = 
-				"<condition>" +
-				"	<numberOfUnpaidInvoicesEqualsOrExceeds>1</numberOfUnpaidInvoicesEqualsOrExceeds>" +
-				"</condition>";
-		InputStream is = new ByteArrayInputStream(xml.getBytes());
-		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
-		UUID unpaidInvoiceId = UUID.randomUUID();		        
-		
-		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 2, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		
-		Assert.assertTrue(!c.evaluate(state0, new DateTime()));
-		Assert.assertTrue(c.evaluate(state1, new DateTime()));
-		Assert.assertTrue(c.evaluate(state2, new DateTime()));
-	}
-	
-	@Test(groups={"fast"}, enabled=true)
-	public void testTotalUnpaidInvoiceBalanceEqualsOrExceeds() throws Exception {
-		String xml = 
-				"<condition>" +
-				"	<totalUnpaidInvoiceBalanceEqualsOrExceeds>100.00</totalUnpaidInvoiceBalanceEqualsOrExceeds>" +
-				"</condition>";
-		InputStream is = new ByteArrayInputStream(xml.getBytes());
-		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
-        UUID unpaidInvoiceId = UUID.randomUUID();               
-		
-		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		
-		Assert.assertTrue(!c.evaluate(state0, new DateTime()));
-		Assert.assertTrue(c.evaluate(state1, new DateTime()));
-		Assert.assertTrue(c.evaluate(state2, new DateTime()));
-	}
-
-	
-	@Test(groups={"fast"}, enabled=true)
-	public void testTimeSinceEarliestUnpaidInvoiceEqualsOrExceeds() throws Exception {
-		String xml = 
-				"<condition>" +
-				"	<timeSinceEarliestUnpaidInvoiceEqualsOrExceeds><unit>DAYS</unit><number>10</number></timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-				"</condition>";
-		InputStream is = new ByteArrayInputStream(xml.getBytes());
-		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
-        UUID unpaidInvoiceId = UUID.randomUUID();               
-		
-		DateTime now = new DateTime();
-		
-		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, null, unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		
-		Assert.assertTrue(!c.evaluate(state0, now));
-		Assert.assertTrue(c.evaluate(state1, now));
-		Assert.assertTrue(c.evaluate(state2, now));
-	}
-
-	@Test(groups={"fast"}, enabled=true)
-	public void testResponseForLastFailedPaymentIn() throws Exception {
-		String xml = 
-				"<condition>" +
-				"	<responseForLastFailedPaymentIn><response>INSUFFICIENT_FUNDS</response><response>DO_NOT_HONOR</response></responseForLastFailedPaymentIn>" +
-				"</condition>";
-		InputStream is = new ByteArrayInputStream(xml.getBytes());
-		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
-        UUID unpaidInvoiceId = UUID.randomUUID();               
-		
-		DateTime now = new DateTime();
-		
-		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, null, unpaidInvoiceId, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{});
-		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
-		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), unpaidInvoiceId, PaymentResponse.DO_NOT_HONOR , new Tag[]{});
-		
-		Assert.assertTrue(!c.evaluate(state0, now));
-		Assert.assertTrue(c.evaluate(state1, now));
-		Assert.assertTrue(c.evaluate(state2, now));
-	}
-
-	@Test(groups={"fast"}, enabled=true)
-	public void testHasControlTag() throws Exception {
-		String xml = 
-				"<condition>" +
-				"	<controlTag>OVERDUE_ENFORCEMENT_OFF</controlTag>" +
-				"</condition>";
-		InputStream is = new ByteArrayInputStream(xml.getBytes());
-		MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is,  MockCondition.class);
-        UUID unpaidInvoiceId = UUID.randomUUID();               
-		
-		DateTime now = new DateTime();
-		
-		BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L,1L), 0, BigDecimal.ZERO, null, unpaidInvoiceId, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF),new DescriptiveTag("Tag")});
-		BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("100.00"), now.minusDays(10), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag(ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
-		BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L,1L), 1, new BigDecimal("200.00"), now.minusDays(20), unpaidInvoiceId, 
-				PaymentResponse.DO_NOT_HONOR, 
-				new Tag[]{new DefaultControlTag(ControlTagType.OVERDUE_ENFORCEMENT_OFF), 
-						  new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF),
-						  new DescriptiveTag("Tag")});
-		
-		Assert.assertTrue(!c.evaluate(state0, now));
-		Assert.assertTrue(c.evaluate(state1, now));
-		Assert.assertTrue(c.evaluate(state2, now));
-	}
 
+    @XmlRootElement(name = "condition")
+    private static class MockCondition extends DefaultCondition<Blockable> {}
+
+    @Test(groups = {"fast"}, enabled = true)
+    public void testNumberOfUnpaidInvoicesEqualsOrExceeds() throws Exception {
+        final String xml =
+                "<condition>" +
+                        "	<numberOfUnpaidInvoicesEqualsOrExceeds>1</numberOfUnpaidInvoicesEqualsOrExceeds>" +
+                        "</condition>";
+        final InputStream is = new ByteArrayInputStream(xml.getBytes());
+        final MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is, MockCondition.class);
+        final UUID unpaidInvoiceId = UUID.randomUUID();
+
+        final BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L, 1L), 0, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+        final BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L, 1L), 1, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+        final BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L, 1L), 2, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+
+        Assert.assertTrue(!c.evaluate(state0, new DateTime()));
+        Assert.assertTrue(c.evaluate(state1, new DateTime()));
+        Assert.assertTrue(c.evaluate(state2, new DateTime()));
+    }
+
+    @Test(groups = {"fast"}, enabled = true)
+    public void testTotalUnpaidInvoiceBalanceEqualsOrExceeds() throws Exception {
+        final String xml =
+                "<condition>" +
+                        "	<totalUnpaidInvoiceBalanceEqualsOrExceeds>100.00</totalUnpaidInvoiceBalanceEqualsOrExceeds>" +
+                        "</condition>";
+        final InputStream is = new ByteArrayInputStream(xml.getBytes());
+        final MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is, MockCondition.class);
+        final UUID unpaidInvoiceId = UUID.randomUUID();
+
+        final BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L, 1L), 0, BigDecimal.ZERO, new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+        final BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L, 1L), 1, new BigDecimal("100.00"), new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+        final BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L, 1L), 1, new BigDecimal("200.00"), new DateTime(), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+
+        Assert.assertTrue(!c.evaluate(state0, new DateTime()));
+        Assert.assertTrue(c.evaluate(state1, new DateTime()));
+        Assert.assertTrue(c.evaluate(state2, new DateTime()));
+    }
+
+
+    @Test(groups = {"fast"}, enabled = true)
+    public void testTimeSinceEarliestUnpaidInvoiceEqualsOrExceeds() throws Exception {
+        final String xml =
+                "<condition>" +
+                        "	<timeSinceEarliestUnpaidInvoiceEqualsOrExceeds><unit>DAYS</unit><number>10</number></timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                        "</condition>";
+        final InputStream is = new ByteArrayInputStream(xml.getBytes());
+        final MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is, MockCondition.class);
+        final UUID unpaidInvoiceId = UUID.randomUUID();
+
+        final DateTime now = new DateTime();
+
+        final BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L, 1L), 0, BigDecimal.ZERO, null, unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+        final BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L, 1L), 1, new BigDecimal("100.00"), now.minusDays(10), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+        final BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L, 1L), 1, new BigDecimal("200.00"), now.minusDays(20), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+
+        Assert.assertTrue(!c.evaluate(state0, now));
+        Assert.assertTrue(c.evaluate(state1, now));
+        Assert.assertTrue(c.evaluate(state2, now));
+    }
+
+    @Test(groups = {"fast"}, enabled = true)
+    public void testResponseForLastFailedPaymentIn() throws Exception {
+        final String xml =
+                "<condition>" +
+                        "	<responseForLastFailedPaymentIn><response>INSUFFICIENT_FUNDS</response><response>DO_NOT_HONOR</response></responseForLastFailedPaymentIn>" +
+                        "</condition>";
+        final InputStream is = new ByteArrayInputStream(xml.getBytes());
+        final MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is, MockCondition.class);
+        final UUID unpaidInvoiceId = UUID.randomUUID();
+
+        final DateTime now = new DateTime();
+
+        final BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L, 1L), 0, BigDecimal.ZERO, null, unpaidInvoiceId, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{});
+        final BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L, 1L), 1, new BigDecimal("100.00"), now.minusDays(10), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{});
+        final BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L, 1L), 1, new BigDecimal("200.00"), now.minusDays(20), unpaidInvoiceId, PaymentResponse.DO_NOT_HONOR, new Tag[]{});
+
+        Assert.assertTrue(!c.evaluate(state0, now));
+        Assert.assertTrue(c.evaluate(state1, now));
+        Assert.assertTrue(c.evaluate(state2, now));
+    }
+
+    @Test(groups = {"fast"}, enabled = true)
+    public void testHasControlTag() throws Exception {
+        final String xml =
+                "<condition>" +
+                        "	<controlTag>OVERDUE_ENFORCEMENT_OFF</controlTag>" +
+                        "</condition>";
+        final InputStream is = new ByteArrayInputStream(xml.getBytes());
+        final MockCondition c = XMLLoader.getObjectFromStreamNoValidation(is, MockCondition.class);
+        final UUID unpaidInvoiceId = UUID.randomUUID();
+
+        final DateTime now = new DateTime();
+
+        final BillingState<Blockable> state0 = new BillingState<Blockable>(new UUID(0L, 1L), 0, BigDecimal.ZERO, null, unpaidInvoiceId, PaymentResponse.LOST_OR_STOLEN_CARD, new Tag[]{new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF), new DescriptiveTag("Tag")});
+        final BillingState<Blockable> state1 = new BillingState<Blockable>(new UUID(0L, 1L), 1, new BigDecimal("100.00"), now.minusDays(10), unpaidInvoiceId, PaymentResponse.INSUFFICIENT_FUNDS, new Tag[]{new DefaultControlTag(ControlTagType.OVERDUE_ENFORCEMENT_OFF)});
+        final BillingState<Blockable> state2 = new BillingState<Blockable>(new UUID(0L, 1L), 1, new BigDecimal("200.00"), now.minusDays(20), unpaidInvoiceId,
+                                                                     PaymentResponse.DO_NOT_HONOR,
+                                                                     new Tag[]{new DefaultControlTag(ControlTagType.OVERDUE_ENFORCEMENT_OFF),
+                                                                             new DefaultControlTag(ControlTagType.AUTO_INVOICING_OFF),
+                                                                             new DescriptiveTag("Tag")});
+
+        Assert.assertTrue(!c.evaluate(state0, now));
+        Assert.assertTrue(c.evaluate(state1, now));
+        Assert.assertTrue(c.evaluate(state2, now));
+    }
 
 
 }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.java b/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.java
index 4cffcdc..58aabcf 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/config/TestOverdueConfig.java
@@ -24,42 +24,41 @@ import org.testng.annotations.Test;
 import com.ning.billing.util.config.XMLLoader;
 
 public class TestOverdueConfig {
-    private String xml = 
-            "<overdueConfig>" +
-                    "   <bundleOverdueStates>" +
-                    "       <state name=\"OD1\">" +
-                    "           <condition>" +
-                    "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                    "                   <unit>MONTHS</unit><number>1</number>" +
-                    "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                    "           </condition>" +
-                    "           <externalMessage>Reached OD1</externalMessage>" +
-                    "           <blockChanges>true</blockChanges>" +
-                    "           <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
-                    "           <autoReevaluationInterval>" +
-                    "               <unit>DAYS</unit><number>15</number>" +
-                    "           </autoReevaluationInterval>" +
-                    "       </state>" +
-                    "       <state name=\"OD2\">" +
-                    "           <condition>" +
-                    "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                    "                   <unit>MONTHS</unit><number>2</number>" +
-                    "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
-                    "           </condition>" +
-                    "           <externalMessage>Reached OD1</externalMessage>" +
-                    "           <blockChanges>true</blockChanges>" +
-                    "           <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
-                    "           <autoReevaluationInterval>" +
-                    "               <unit>DAYS</unit><number>15</number>" +
-                    "           </autoReevaluationInterval>" +
-                    "       </state>" +
-                    "   </bundleOverdueStates>" +
-                    "</overdueConfig>";
 
     @Test
     public void testParseConfig() throws Exception {
-        InputStream is = new ByteArrayInputStream(xml.getBytes());
-        OverdueConfig c = XMLLoader.getObjectFromStreamNoValidation(is,  OverdueConfig.class);
+        final String xml = "<overdueConfig>" +
+                "   <bundleOverdueStates>" +
+                "       <state name=\"OD1\">" +
+                "           <condition>" +
+                "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                "                   <unit>MONTHS</unit><number>1</number>" +
+                "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                "           </condition>" +
+                "           <externalMessage>Reached OD1</externalMessage>" +
+                "           <blockChanges>true</blockChanges>" +
+                "           <disableEntitlementAndChangesBlocked>false</disableEntitlementAndChangesBlocked>" +
+                "           <autoReevaluationInterval>" +
+                "               <unit>DAYS</unit><number>15</number>" +
+                "           </autoReevaluationInterval>" +
+                "       </state>" +
+                "       <state name=\"OD2\">" +
+                "           <condition>" +
+                "               <timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                "                   <unit>MONTHS</unit><number>2</number>" +
+                "               </timeSinceEarliestUnpaidInvoiceEqualsOrExceeds>" +
+                "           </condition>" +
+                "           <externalMessage>Reached OD1</externalMessage>" +
+                "           <blockChanges>true</blockChanges>" +
+                "           <disableEntitlementAndChangesBlocked>true</disableEntitlementAndChangesBlocked>" +
+                "           <autoReevaluationInterval>" +
+                "               <unit>DAYS</unit><number>15</number>" +
+                "           </autoReevaluationInterval>" +
+                "       </state>" +
+                "   </bundleOverdueStates>" +
+                "</overdueConfig>";
+        final InputStream is = new ByteArrayInputStream(xml.getBytes());
+        final OverdueConfig c = XMLLoader.getObjectFromStreamNoValidation(is, OverdueConfig.class);
 
     }
 
diff --git a/overdue/src/test/java/com/ning/billing/overdue/notification/MockOverdueCheckPoster.java b/overdue/src/test/java/com/ning/billing/overdue/notification/MockOverdueCheckPoster.java
index c1cfb65..8fd0aa1 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/notification/MockOverdueCheckPoster.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/notification/MockOverdueCheckPoster.java
@@ -22,17 +22,17 @@ import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.ovedue.notification.OverdueCheckPoster;
 
 public class MockOverdueCheckPoster implements OverdueCheckPoster {
-    
+
     @Override
-    public void insertOverdueCheckNotification(Blockable overdueable,
-            DateTime futureNotificationTime) {
+    public void insertOverdueCheckNotification(final Blockable overdueable,
+                                               final DateTime futureNotificationTime) {
         // TODO Auto-generated method stub
-        
+
     }
 
     @Override
-    public void clearNotificationsFor(Blockable blockable) {
+    public void clearNotificationsFor(final Blockable blockable) {
         // TODO Auto-generated method stub
-        
+
     }
 }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
index 1048cb0..a098a25 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/notification/TestOverdueCheckNotifier.java
@@ -16,15 +16,11 @@
 
 package com.ning.billing.overdue.notification;
 
-import static com.jayway.awaitility.Awaitility.await;
-import static java.util.concurrent.TimeUnit.MINUTES;
-
 import java.io.IOException;
 import java.sql.SQLException;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
@@ -58,7 +54,6 @@ import com.ning.billing.overdue.OverdueProperties;
 import com.ning.billing.overdue.glue.DefaultOverdueModule;
 import com.ning.billing.overdue.listener.OverdueListener;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.bus.InMemoryBus;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
 import com.ning.billing.util.clock.Clock;
@@ -68,51 +63,55 @@ import com.ning.billing.util.customfield.dao.CustomFieldDao;
 import com.ning.billing.util.globallocker.GlobalLocker;
 import com.ning.billing.util.globallocker.MySqlGlobalLocker;
 import com.ning.billing.util.glue.BusModule;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.notificationq.DefaultNotificationQueueService;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
 import com.ning.billing.util.tag.dao.AuditedTagDao;
 import com.ning.billing.util.tag.dao.TagDao;
 
+import static com.jayway.awaitility.Awaitility.await;
+import static java.util.concurrent.TimeUnit.MINUTES;
+
 public class TestOverdueCheckNotifier {
-	private Clock clock;
-	private DefaultOverdueCheckNotifier notifier;
+    private Clock clock;
+    private DefaultOverdueCheckNotifier notifier;
 
-	private Bus eventBus;
-	private MysqlTestingHelper helper;
-	private OverdueListenerMock listener;
-	private NotificationQueueService notificationQueueService;
+    private Bus eventBus;
+    private MysqlTestingHelper helper;
+    private OverdueListenerMock listener;
+    private NotificationQueueService notificationQueueService;
 
-	private static final class OverdueListenerMock extends OverdueListener {
-		int eventCount = 0;
-		UUID latestSubscriptionId = null;
+    private static final class OverdueListenerMock extends OverdueListener {
+        int eventCount = 0;
+        UUID latestSubscriptionId = null;
 
-		public OverdueListenerMock() {
-			super(null);
-		}
+        public OverdueListenerMock() {
+            super(null);
+        }
 
-		@Override
-		public void handleNextOverdueCheck(UUID subscriptionId) {
-			eventCount++;
-			latestSubscriptionId=subscriptionId;
-		}
+        @Override
+        public void handleNextOverdueCheck(final UUID subscriptionId) {
+            eventCount++;
+            latestSubscriptionId = subscriptionId;
+        }
 
-		public int getEventCount() {
-			return eventCount;
-		}
+        public int getEventCount() {
+            return eventCount;
+        }
 
-		public UUID getLatestSubscriptionId(){
-			return latestSubscriptionId;
-		}
+        public UUID getLatestSubscriptionId() {
+            return latestSubscriptionId;
+        }
+
+    }
 
-	}
 
+    @BeforeClass(groups = {"slow"})
+    public void setup() throws ServiceException, IOException, ClassNotFoundException, SQLException {
+        //TestApiBase.loadSystemPropertiesFromClasspath("/entitlement.properties");
+        final Injector g = Guice.createInjector(Stage.PRODUCTION, new MockInvoiceModule(), new MockPaymentModule(), new BusModule(), new DefaultOverdueModule() {
 
-	@BeforeClass(groups={"slow"})
-	public void setup() throws ServiceException, IOException, ClassNotFoundException, SQLException {
-		//TestApiBase.loadSystemPropertiesFromClasspath("/entitlement.properties");
-        final Injector g = Guice.createInjector(Stage.PRODUCTION,  new MockInvoiceModule(), new MockPaymentModule(), new BusModule(), new DefaultOverdueModule() {
-			
             protected void configure() {
                 super.configure();
                 bind(Clock.class).to(ClockMock.class).asEagerSingleton();
@@ -125,7 +124,7 @@ public class TestOverdueCheckNotifier {
                 bind(CatalogService.class).to(DefaultCatalogService.class).asEagerSingleton();
                 final MysqlTestingHelper helper = new MysqlTestingHelper();
                 bind(MysqlTestingHelper.class).toInstance(helper);
-                IDBI dbi = helper.getDBI();
+                final IDBI dbi = helper.getDBI();
                 bind(IDBI.class).toInstance(dbi);
                 bind(TagDao.class).to(AuditedTagDao.class).asEagerSingleton();
                 bind(CustomFieldDao.class).to(AuditedCustomFieldDao.class).asEagerSingleton();
@@ -136,70 +135,70 @@ public class TestOverdueCheckNotifier {
         });
 
         clock = g.getInstance(Clock.class);
-        IDBI dbi = g.getInstance(IDBI.class);
+        final IDBI dbi = g.getInstance(IDBI.class);
 
         eventBus = g.getInstance(Bus.class);
         helper = g.getInstance(MysqlTestingHelper.class);
         notificationQueueService = g.getInstance(NotificationQueueService.class);
-        
-        OverdueProperties properties = g.getInstance(OverdueProperties.class);
 
-        Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
-        EntitlementUserApi entitlementUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
+        final OverdueProperties properties = g.getInstance(OverdueProperties.class);
+
+        final Subscription subscription = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+        final EntitlementUserApi entitlementUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
         ((ZombieControl) entitlementUserApi).addResult("getSubscriptionFromId", subscription);
 
 //        CallContextFactory factory = new DefaultCallContextFactory(clock);
         listener = new OverdueListenerMock();
         notifier = new DefaultOverdueCheckNotifier(notificationQueueService,
-                 properties, listener);
-        
+                                                   properties, listener);
+
         startMysql();
         eventBus.start();
         notifier.initialize();
         notifier.start();
-	}
+    }
+
+    private void startMysql() throws IOException, ClassNotFoundException, SQLException {
+        final String ddl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+        final String testDdl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
 
-	private void startMysql() throws IOException, ClassNotFoundException, SQLException {
-		final String ddl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
-		final String testDdl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
+        helper.startMysql();
+        helper.initDb(ddl);
+        helper.initDb(testDdl);
+    }
 
-		helper.startMysql();
-		helper.initDb(ddl);
-		helper.initDb(testDdl);
-	}
+    @Test(enabled = true, groups = "slow")
+    public void test() throws Exception {
+        final UUID subscriptionId = new UUID(0L, 1L);
+        final Blockable blockable = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+        ((ZombieControl) blockable).addResult("getId", subscriptionId);
+        final DateTime now = new DateTime();
+        final DateTime readyTime = now.plusMillis(2000);
+        final OverdueCheckPoster poster = new DefaultOverdueCheckPoster(notificationQueueService);
 
-	@Test(enabled=true, groups="slow")
-	public void test() throws Exception {
-		final UUID subscriptionId = new UUID(0L,1L);
-		final Blockable blockable = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
-		((ZombieControl)blockable).addResult("getId", subscriptionId);
-		final DateTime now = new DateTime();
-		final DateTime readyTime = now.plusMillis(2000);
-		final OverdueCheckPoster poster = new DefaultOverdueCheckPoster(notificationQueueService);
 
+        poster.insertOverdueCheckNotification(blockable, readyTime);
 
-		poster.insertOverdueCheckNotification(blockable, readyTime);
 
+        // Move time in the future after the notification effectiveDate
+        ((ClockMock) clock).setDeltaFromReality(3000);
 
-		// Move time in the future after the notification effectiveDate
-		((ClockMock) clock).setDeltaFromReality(3000);
 
+        await().atMost(1, MINUTES).until(new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                return listener.getEventCount() == 1;
+            }
+        });
 
-	    await().atMost(1, MINUTES).until(new Callable<Boolean>() {
-	            @Override
-	            public Boolean call() throws Exception {
-	                return listener.getEventCount() == 1;
-	            }
-	        });
+        Assert.assertEquals(listener.getEventCount(), 1);
+        Assert.assertEquals(listener.getLatestSubscriptionId(), subscriptionId);
 
-		Assert.assertEquals(listener.getEventCount(), 1);
-		Assert.assertEquals(listener.getLatestSubscriptionId(), subscriptionId);
-        
-	}
+    }
 
-	@AfterClass(groups="slow")
+    @AfterClass(groups = "slow")
     public void tearDown() {
-	    eventBus.stop();
+        eventBus.stop();
         notifier.stop();
         helper.stopMysql();
     }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java b/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
index 55163ca..f68ce0a 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/OverdueTestBase.java
@@ -22,9 +22,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-import javax.management.RuntimeErrorException;
-
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
@@ -64,12 +61,12 @@ import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.NotificationQueueModule;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
 
-//@Guice(modules = {MockJunctionModule.class, MockInvoiceModule.class, DefaultOverdueModule.class})
-@Guice( modules = {DefaultOverdueModule.class, MockClockModule.class, ApplicatorMockJunctionModule.class, CatalogModule.class, MockInvoiceModule.class, MockPaymentModule.class, BusModule.class, NotificationQueueModule.class, TestDbiModule.class})
+@Guice(modules = {DefaultOverdueModule.class, MockClockModule.class, ApplicatorMockJunctionModule.class, CatalogModule.class, MockInvoiceModule.class, MockPaymentModule.class, BusModule.class, NotificationQueueModule.class, TestDbiModule.class})
 public class OverdueTestBase {
-    protected final String configXml =  
+    protected final String configXml =
             "<overdueConfig>" +
                     "   <bundleOverdueStates>" +
                     "       <state name=\"OD3\">" +
@@ -113,7 +110,7 @@ public class OverdueTestBase {
                     "       </state>" +
                     "   </bundleOverdueStates>" +
                     "</overdueConfig>";
-    protected OverdueConfig config; 
+    protected OverdueConfig config;
 
     @Inject
     protected ClockMock clock;
@@ -147,25 +144,23 @@ public class OverdueTestBase {
     @Inject
     protected MysqlTestingHelper helper;
 
-    protected void setupMySQL() throws IOException
-    {
+    protected void setupMySQL() throws IOException {
         final String utilDdl = IOUtils.toString(TestOverdueStateApplicator.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
         helper.startMysql();
         helper.initDb(utilDdl);
     }
 
-
     @BeforeClass(groups = "slow")
-    public void setup() throws Exception{
+    public void setup() throws Exception {
 
         setupMySQL();
         service.registerForBus();
         try {
             service.initialize();
-        }catch (RuntimeException e) {
-            if(!(e.getCause() instanceof NotificationQueueAlreadyExists)) {
+        } catch (RuntimeException e) {
+            if (!(e.getCause() instanceof NotificationQueueAlreadyExists)) {
                 throw e;
-            } 
+            }
         }
         service.start();
     }
@@ -187,48 +182,48 @@ public class OverdueTestBase {
     }
 
 
-    protected void checkStateApplied( OverdueState<SubscriptionBundle> state) {
-        BlockingState result = ((ApplicatorBlockingApi)blockingApi).getBlockingState();
-        checkStateApplied( result, state);
+    protected void checkStateApplied(final OverdueState<SubscriptionBundle> state) {
+        final BlockingState result = ((ApplicatorBlockingApi) blockingApi).getBlockingState();
+        checkStateApplied(result, state);
     }
 
-    protected void checkStateApplied(BlockingState result, OverdueState<SubscriptionBundle> state) {
-        Assert.assertEquals(result.getStateName(),state.getName());
+    protected void checkStateApplied(final BlockingState result, final OverdueState<SubscriptionBundle> state) {
+        Assert.assertEquals(result.getStateName(), state.getName());
         Assert.assertEquals(result.isBlockChange(), state.blockChanges());
         Assert.assertEquals(result.isBlockEntitlement(), state.disableEntitlementAndChangesBlocked());
         Assert.assertEquals(result.isBlockBilling(), state.disableEntitlementAndChangesBlocked());
     }
 
 
-    protected SubscriptionBundle createBundle(DateTime dateOfLastUnPaidInvoice) {
-        SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
-        UUID bundleId = UUID.randomUUID();
-        ((ZombieControl)bundle).addResult("getId", bundleId);
-        ((ZombieControl)bundle).addResult("getAccountId", UUID.randomUUID());
+    protected SubscriptionBundle createBundle(final DateTime dateOfLastUnPaidInvoice) {
+        final SubscriptionBundle bundle = BrainDeadProxyFactory.createBrainDeadProxyFor(SubscriptionBundle.class);
+        final UUID bundleId = UUID.randomUUID();
+        ((ZombieControl) bundle).addResult("getId", bundleId);
+        ((ZombieControl) bundle).addResult("getAccountId", UUID.randomUUID());
 
-        Invoice invoice = BrainDeadProxyFactory.createBrainDeadProxyFor(Invoice.class);
-        ((ZombieControl)invoice).addResult("getInvoiceDate",dateOfLastUnPaidInvoice);
-        ((ZombieControl)invoice).addResult("getBalance",BigDecimal.TEN);
-        ((ZombieControl)invoice).addResult("getId",UUID.randomUUID());
-        ((ZombieControl)invoice).addResult("hashCode", UUID.randomUUID().hashCode());
+        final Invoice invoice = BrainDeadProxyFactory.createBrainDeadProxyFor(Invoice.class);
+        ((ZombieControl) invoice).addResult("getInvoiceDate", dateOfLastUnPaidInvoice);
+        ((ZombieControl) invoice).addResult("getBalance", BigDecimal.TEN);
+        ((ZombieControl) invoice).addResult("getId", UUID.randomUUID());
+        ((ZombieControl) invoice).addResult("hashCode", UUID.randomUUID().hashCode());
 
-        InvoiceItem item = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceItem.class);
-        ((ZombieControl)item).addResult("getBundleId",bundleId);
-        List<InvoiceItem> items = new ArrayList<InvoiceItem>();
+        final InvoiceItem item = BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceItem.class);
+        ((ZombieControl) item).addResult("getBundleId", bundleId);
+        final List<InvoiceItem> items = new ArrayList<InvoiceItem>();
         items.add(item);
 
-        ((ZombieControl)invoice).addResult("getInvoiceItems",items);
+        ((ZombieControl) invoice).addResult("getInvoiceItems", items);
 
-        List<Invoice> invoices = new ArrayList<Invoice>();
+        final List<Invoice> invoices = new ArrayList<Invoice>();
         invoices.add(invoice);
-        ((ZombieControl)invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
+        ((ZombieControl) invoiceApi).addResult("getUnpaidInvoicesByAccountId", invoices);
 
 
-        Subscription base = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
-        ((ZombieControl)base).addResult("getCurrentPlan", MockPlan.createBicycleNoTrialEvergreen1USD());
-        ((ZombieControl)base).addResult("getCurrentPriceList", new MockPriceList());
-        ((ZombieControl)base).addResult("getCurrentPhase", MockPlan.createBicycleNoTrialEvergreen1USD().getFinalPhase());
-        ((ZombieControl)entitlementApi).addResult("getBaseSubscription", base);
+        final Subscription base = BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+        ((ZombieControl) base).addResult("getCurrentPlan", MockPlan.createBicycleNoTrialEvergreen1USD());
+        ((ZombieControl) base).addResult("getCurrentPriceList", new MockPriceList());
+        ((ZombieControl) base).addResult("getCurrentPhase", MockPlan.createBicycleNoTrialEvergreen1USD().getFinalPhase());
+        ((ZombieControl) entitlementApi).addResult("getBaseSubscription", base);
 
         return bundle;
     }
diff --git a/overdue/src/test/java/com/ning/billing/overdue/wrapper/TestOverdueWrapper.java b/overdue/src/test/java/com/ning/billing/overdue/wrapper/TestOverdueWrapper.java
index 8fbc310..84e7467 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/wrapper/TestOverdueWrapper.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/wrapper/TestOverdueWrapper.java
@@ -30,17 +30,17 @@ import com.ning.billing.overdue.config.OverdueConfig;
 import com.ning.billing.util.config.XMLLoader;
 
 public class TestOverdueWrapper extends OverdueTestBase {
-    @Test( groups={"fast"} , enabled = true)
+    @Test(groups = {"fast"}, enabled = true)
     public void testWrapperBasic() throws Exception {
-        InputStream is = new ByteArrayInputStream(configXml.getBytes());
-        config = XMLLoader.getObjectFromStreamNoValidation(is,  OverdueConfig.class);
+        final InputStream is = new ByteArrayInputStream(configXml.getBytes());
+        config = XMLLoader.getObjectFromStreamNoValidation(is, OverdueConfig.class);
         overdueWrapperFactory.setOverdueConfig(config);
-        
+
         SubscriptionBundle bundle;
-        OverdueWrapper<SubscriptionBundle> wrapper ;
+        OverdueWrapper<SubscriptionBundle> wrapper;
         OverdueState<SubscriptionBundle> state;
 
-        state = config.getBundleStateSet().findState("OD1"); 
+        state = config.getBundleStateSet().findState("OD1");
         bundle = createBundle(clock.getUTCNow().minusDays(31));
         wrapper = overdueWrapperFactory.createOverdueWrapperFor(bundle);
         wrapper.refresh();
@@ -60,25 +60,26 @@ public class TestOverdueWrapper extends OverdueTestBase {
         checkStateApplied(state);
 
     }
-    @Test( groups={"fast"} , enabled = true)
+
+    @Test(groups = {"fast"}, enabled = true)
     public void testWrapperNoConfig() throws Exception {
 
         overdueWrapperFactory.setOverdueConfig(null);
-        
 
-        SubscriptionBundle bundle;
-        OverdueWrapper<SubscriptionBundle> wrapper ;
-        OverdueState<SubscriptionBundle> state;
 
-        InputStream is = new ByteArrayInputStream(configXml.getBytes());
-        config = XMLLoader.getObjectFromStreamNoValidation(is,  OverdueConfig.class);
-        state = config.getBundleStateSet().findState(BlockingApi.CLEAR_STATE_NAME); 
+        final SubscriptionBundle bundle;
+        final OverdueWrapper<SubscriptionBundle> wrapper;
+        final OverdueState<SubscriptionBundle> state;
+
+        final InputStream is = new ByteArrayInputStream(configXml.getBytes());
+        config = XMLLoader.getObjectFromStreamNoValidation(is, OverdueConfig.class);
+        state = config.getBundleStateSet().findState(BlockingApi.CLEAR_STATE_NAME);
         bundle = createBundle(clock.getUTCNow().minusDays(31));
         wrapper = overdueWrapperFactory.createOverdueWrapperFor(bundle);
-        OverdueState<SubscriptionBundle> result = wrapper.refresh();
+        final OverdueState<SubscriptionBundle> result = wrapper.refresh();
 
 
-        Assert.assertEquals(result.getName(),state.getName());
+        Assert.assertEquals(result.getName(), state.getName());
         Assert.assertEquals(result.blockChanges(), state.blockChanges());
         Assert.assertEquals(result.disableEntitlementAndChangesBlocked(), state.disableEntitlementAndChangesBlocked());
 

payment/pom.xml 22(+7 -15)

diff --git a/payment/pom.xml b/payment/pom.xml
index e22d42a..c3a5544 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-payment</artifactId>
@@ -66,30 +66,22 @@
             <artifactId>joda-time</artifactId>
         </dependency>
         <dependency>
-            <groupId>commons-lang</groupId>
-            <artifactId>commons-lang</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
 
         <!--  TEST SCOPE -->
         <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.testng</groupId>
             <artifactId>testng</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency> 
+        <dependency>
             <groupId>com.jayway.awaitility</groupId>
             <artifactId>awaitility</artifactId>
             <scope>test</scope>
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPayment.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPayment.java
index 5e9be0a..c206d8e 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPayment.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPayment.java
@@ -32,7 +32,7 @@ import com.ning.billing.util.entity.EntityBase;
 
 public class DefaultPayment extends EntityBase implements Payment {
 
-    
+
     private final UUID accountId;
     private final UUID invoiceId;
     private final UUID paymentMethodId;
@@ -40,14 +40,14 @@ public class DefaultPayment extends EntityBase implements Payment {
     private final Currency currency;
     private final DateTime effectiveDate;
     private final Integer paymentNumber;
-    private final PaymentStatus paymentStatus;    
+    private final PaymentStatus paymentStatus;
     private final List<PaymentAttempt> attempts;
 
-    
-    private DefaultPayment(UUID id, UUID accountId, UUID invoiceId,
-            UUID paymentMethodId, BigDecimal amount, Currency currency,
-            DateTime effectiveDate, Integer paymentNumber,
-            PaymentStatus paymentStatus, String paymentError, List<PaymentAttempt> attempts) {
+
+    private DefaultPayment(final UUID id, final UUID accountId, final UUID invoiceId,
+                           final UUID paymentMethodId, final BigDecimal amount, final Currency currency,
+                           final DateTime effectiveDate, final Integer paymentNumber,
+                           final PaymentStatus paymentStatus, final String paymentError, final List<PaymentAttempt> attempts) {
         super(id);
         this.accountId = accountId;
         this.invoiceId = invoiceId;
@@ -59,8 +59,8 @@ public class DefaultPayment extends EntityBase implements Payment {
         this.paymentStatus = paymentStatus;
         this.attempts = attempts;
     }
-    
-    public DefaultPayment(PaymentModelDao src, List<PaymentAttemptModelDao> attempts) {
+
+    public DefaultPayment(final PaymentModelDao src, final List<PaymentAttemptModelDao> attempts) {
         this(src.getId(),
              src.getAccountId(),
              src.getInvoiceId(),
@@ -73,13 +73,13 @@ public class DefaultPayment extends EntityBase implements Payment {
              null,
              toPaymentAttempts(attempts));
     }
-    
+
 
     @Override
     public Integer getPaymentNumber() {
         return paymentNumber;
     }
-    
+
     @Override
     public UUID getAccountId() {
         return accountId;
@@ -120,8 +120,8 @@ public class DefaultPayment extends EntityBase implements Payment {
     public List<PaymentAttempt> getAttempts() {
         return attempts;
     }
-    
-    private static List<PaymentAttempt> toPaymentAttempts(List<PaymentAttemptModelDao> attempts) {
+
+    private static List<PaymentAttempt> toPaymentAttempts(final List<PaymentAttemptModelDao> attempts) {
         if (attempts == null || attempts.size() == 0) {
             return Collections.emptyList();
         }
@@ -133,14 +133,17 @@ public class DefaultPayment extends EntityBase implements Payment {
                     public PaymentStatus getPaymentStatus() {
                         return input.getPaymentStatus();
                     }
+
                     @Override
                     public String getErrorMsg() {
                         return input.getPaymentError();
                     }
+
                     @Override
                     public DateTime getEffectiveDate() {
                         return input.getEffectiveDate();
                     }
+
                     @Override
                     public UUID getId() {
                         return input.getId();
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
index 8c0ecf5..ad55ff9 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
@@ -30,57 +30,57 @@ import com.ning.billing.payment.core.RefundProcessor;
 import com.ning.billing.util.callcontext.CallContext;
 
 public class DefaultPaymentApi implements PaymentApi {
-    
+
 
     private final PaymentMethodProcessor methodProcessor;
     private final PaymentProcessor paymentProcessor;
     private final RefundProcessor refundProcessor;
-      
+
     @Inject
     public DefaultPaymentApi(final PaymentMethodProcessor methodProcessor,
-            final PaymentProcessor paymentProcessor,
-            final RefundProcessor refundProcessor) {
+                             final PaymentProcessor paymentProcessor,
+                             final RefundProcessor refundProcessor) {
         this.methodProcessor = methodProcessor;
         this.paymentProcessor = paymentProcessor;
         this.refundProcessor = refundProcessor;
     }
-     
+
     @Override
-    public Payment createPayment(final String accountKey, final UUID invoiceId, final BigDecimal amount, final CallContext context) 
-    throws PaymentApiException {
+    public Payment createPayment(final String accountKey, final UUID invoiceId, final BigDecimal amount, final CallContext context)
+            throws PaymentApiException {
         return paymentProcessor.createPayment(accountKey, invoiceId, amount, context, true);
-     }
-    
+    }
+
     @Override
-    public Payment createPayment(Account account, UUID invoiceId,
-            final BigDecimal amount, CallContext context) throws PaymentApiException {
-        return paymentProcessor.createPayment(account, invoiceId, amount, context, true);        
+    public Payment createPayment(final Account account, final UUID invoiceId,
+                                 final BigDecimal amount, final CallContext context) throws PaymentApiException {
+        return paymentProcessor.createPayment(account, invoiceId, amount, context, true);
     }
 
     @Override
-    public Payment getPayment(UUID paymentId) throws PaymentApiException {
-        Payment payment = paymentProcessor.getPayment(paymentId);
+    public Payment getPayment(final UUID paymentId) throws PaymentApiException {
+        final Payment payment = paymentProcessor.getPayment(paymentId);
         if (payment == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT, paymentId);
         }
         return payment;
     }
-    
+
     @Override
-    public List<Payment> getInvoicePayments(UUID invoiceId) {
+    public List<Payment> getInvoicePayments(final UUID invoiceId) {
         return paymentProcessor.getInvoicePayments(invoiceId);
     }
 
     @Override
-    public List<Payment> getAccountPayments(UUID accountId)
+    public List<Payment> getAccountPayments(final UUID accountId)
             throws PaymentApiException {
         return paymentProcessor.getAccountPayments(accountId);
     }
-    
+
 
     @Override
-    public Refund createRefund(Account account, UUID paymentId, CallContext context)
-        throws PaymentApiException {
+    public Refund createRefund(final Account account, final UUID paymentId, final CallContext context)
+            throws PaymentApiException {
         return refundProcessor.createRefund(account, paymentId, context);
     }
 
@@ -91,59 +91,59 @@ public class DefaultPaymentApi implements PaymentApi {
 
 
     @Override
-    public String initializeAccountPlugin(String pluginName, Account account)
-        throws PaymentApiException {
+    public String initializeAccountPlugin(final String pluginName, final Account account)
+            throws PaymentApiException {
         return methodProcessor.initializeAccountPlugin(pluginName, account);
     }
 
 
     @Override
-    public UUID addPaymentMethod(String pluginName, Account account,
-            boolean setDefault, final PaymentMethodPlugin paymentMethodInfo, final CallContext context) 
-        throws PaymentApiException {
+    public UUID addPaymentMethod(final String pluginName, final Account account,
+                                 final boolean setDefault, final PaymentMethodPlugin paymentMethodInfo, final CallContext context)
+            throws PaymentApiException {
         return methodProcessor.addPaymentMethod(pluginName, account, setDefault, paymentMethodInfo, context);
     }
 
- 
+
     @Override
-    public List<PaymentMethod> refreshPaymentMethods(String pluginName,
-            Account account, final CallContext context) 
+    public List<PaymentMethod> refreshPaymentMethods(final String pluginName,
+                                                     final Account account, final CallContext context)
             throws PaymentApiException {
         return methodProcessor.refreshPaymentMethods(pluginName, account, context);
     }
 
     @Override
-    public List<PaymentMethod> getPaymentMethods(Account account, boolean withPluginDetail) 
-    throws PaymentApiException {
+    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginDetail)
+            throws PaymentApiException {
         return methodProcessor.getPaymentMethods(account, withPluginDetail);
     }
 
     public PaymentMethod getPaymentMethodById(final UUID paymentMethodId)
-    throws PaymentApiException {
-        return methodProcessor.getPaymentMethodById(paymentMethodId);        
+            throws PaymentApiException {
+        return methodProcessor.getPaymentMethodById(paymentMethodId);
     }
 
     @Override
-    public PaymentMethod getPaymentMethod(final Account account, UUID paymentMethod, boolean withPluginDetail)
-        throws PaymentApiException {
+    public PaymentMethod getPaymentMethod(final Account account, final UUID paymentMethod, final boolean withPluginDetail)
+            throws PaymentApiException {
         return methodProcessor.getPaymentMethod(account, paymentMethod, withPluginDetail);
     }
 
     @Override
-    public void updatePaymentMethod(final Account account, UUID paymentMethodId, PaymentMethodPlugin paymentMethodInfo)
-        throws PaymentApiException {
+    public void updatePaymentMethod(final Account account, final UUID paymentMethodId, final PaymentMethodPlugin paymentMethodInfo)
+            throws PaymentApiException {
         methodProcessor.updatePaymentMethod(account, paymentMethodId, paymentMethodInfo);
     }
 
     @Override
-    public void deletedPaymentMethod(final Account account, UUID paymentMethodId, final CallContext context) 
-        throws PaymentApiException {
+    public void deletedPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
+            throws PaymentApiException {
         methodProcessor.deletedPaymentMethod(account, paymentMethodId);
     }
 
     @Override
-    public void setDefaultPaymentMethod(Account account, UUID paymentMethodId, final CallContext context)
-        throws PaymentApiException {
+    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
+            throws PaymentApiException {
         methodProcessor.setDefaultPaymentMethod(account, paymentMethodId, context);
     }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentErrorEvent.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentErrorEvent.java
index d87e844..1fe7ff4 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentErrorEvent.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentErrorEvent.java
@@ -15,6 +15,7 @@
  */
 
 package com.ning.billing.payment.api;
+
 import java.util.UUID;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
@@ -25,7 +26,7 @@ import com.ning.billing.util.entity.EntityBase;
 
 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "error")
 public class DefaultPaymentErrorEvent extends EntityBase implements PaymentErrorEvent {
-	
+
     private final String message;
     private final UUID accountId;
     private final UUID invoiceId;
@@ -34,38 +35,36 @@ public class DefaultPaymentErrorEvent extends EntityBase implements PaymentError
 
 
     @JsonCreator
-    public DefaultPaymentErrorEvent(@JsonProperty("id") UUID id,
-            @JsonProperty("accountId") UUID accountId,
-            @JsonProperty("invoiceId") UUID invoiceId,
-            @JsonProperty("paymentId") UUID paymentId,            
-            @JsonProperty("message") String message,
-            @JsonProperty("userToken") UUID userToken) {
+    public DefaultPaymentErrorEvent(@JsonProperty("id") final UUID id,
+                                    @JsonProperty("accountId") final UUID accountId,
+                                    @JsonProperty("invoiceId") final UUID invoiceId,
+                                    @JsonProperty("paymentId") final UUID paymentId,
+                                    @JsonProperty("message") final String message,
+                                    @JsonProperty("userToken") final UUID userToken) {
         super(id);
         this.message = message;
         this.accountId = accountId;
         this.invoiceId = invoiceId;
         this.paymentId = paymentId;
-        this.userToken = userToken;        
+        this.userToken = userToken;
     }
-    
 
 
-    public DefaultPaymentErrorEvent(UUID accountId,
-            UUID invoiceId, UUID paymentId, String message, UUID userToken) {
+    public DefaultPaymentErrorEvent(final UUID accountId,
+                                    final UUID invoiceId, final UUID paymentId, final String message, final UUID userToken) {
         this(UUID.randomUUID(), accountId, invoiceId, paymentId, message, userToken);
     }
 
 
-
     @JsonIgnore
-	@Override
-	public BusEventType getBusEventType() {
-		return BusEventType.PAYMENT_ERROR;
-	}
+    @Override
+    public BusEventType getBusEventType() {
+        return BusEventType.PAYMENT_ERROR;
+    }
 
     @Override
     public UUID getUserToken() {
-    	return userToken;
+        return userToken;
     }
 
     @Override
@@ -107,39 +106,52 @@ public class DefaultPaymentErrorEvent extends EntityBase implements PaymentError
 
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        DefaultPaymentErrorEvent other = (DefaultPaymentErrorEvent) obj;
+        }
+        final DefaultPaymentErrorEvent other = (DefaultPaymentErrorEvent) obj;
         if (accountId == null) {
-            if (other.accountId != null)
+            if (other.accountId != null) {
                 return false;
-        } else if (!accountId.equals(other.accountId))
+            }
+        } else if (!accountId.equals(other.accountId)) {
             return false;
+        }
         if (invoiceId == null) {
-            if (other.invoiceId != null)
+            if (other.invoiceId != null) {
                 return false;
-        } else if (!invoiceId.equals(other.invoiceId))
+            }
+        } else if (!invoiceId.equals(other.invoiceId)) {
             return false;
+        }
         if (message == null) {
-            if (other.message != null)
+            if (other.message != null) {
                 return false;
-        } else if (!message.equals(other.message))
+            }
+        } else if (!message.equals(other.message)) {
             return false;
+        }
         if (paymentId == null) {
-            if (other.paymentId != null)
+            if (other.paymentId != null) {
                 return false;
-        } else if (!paymentId.equals(other.paymentId))
+            }
+        } else if (!paymentId.equals(other.paymentId)) {
             return false;
+        }
         if (userToken == null) {
-            if (other.userToken != null)
+            if (other.userToken != null) {
                 return false;
-        } else if (!userToken.equals(other.userToken))
+            }
+        } else if (!userToken.equals(other.userToken)) {
             return false;
+        }
         return true;
     }
 
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentInfoEvent.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentInfoEvent.java
index 348555c..a34f71e 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentInfoEvent.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentInfoEvent.java
@@ -19,21 +19,17 @@ package com.ning.billing.payment.api;
 import java.math.BigDecimal;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.ning.billing.util.entity.EntityBase;
-import org.joda.time.DateTime;
-
-import com.google.common.base.Objects;
-
-import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
-import com.ning.billing.payment.plugin.api.PaymentInfoPlugin.PaymentPluginStatus;
 
 public class DefaultPaymentInfoEvent extends EntityBase implements PaymentInfoEvent {
-    
+
     private final UUID accountId;
-    private final UUID invoiceId;  
+    private final UUID invoiceId;
     private final UUID paymentId;
     private final BigDecimal amount;
     private final Integer paymentNumber;
@@ -42,15 +38,15 @@ public class DefaultPaymentInfoEvent extends EntityBase implements PaymentInfoEv
     private final DateTime effectiveDate;
 
     @JsonCreator
-    public DefaultPaymentInfoEvent(@JsonProperty("id") UUID id,
-            @JsonProperty("accountId") UUID accountId,
-            @JsonProperty("invoiceId") UUID invoiceId,            
-            @JsonProperty("paymentId") UUID paymentId,
-            @JsonProperty("amount") BigDecimal amount,
-            @JsonProperty("paymentNumber") Integer paymentNumber,
-            @JsonProperty("status") PaymentStatus status,
-            @JsonProperty("userToken") UUID userToken,
-            @JsonProperty("effectiveDate") DateTime effectiveDate) {
+    public DefaultPaymentInfoEvent(@JsonProperty("id") final UUID id,
+                                   @JsonProperty("accountId") final UUID accountId,
+                                   @JsonProperty("invoiceId") final UUID invoiceId,
+                                   @JsonProperty("paymentId") final UUID paymentId,
+                                   @JsonProperty("amount") final BigDecimal amount,
+                                   @JsonProperty("paymentNumber") final Integer paymentNumber,
+                                   @JsonProperty("status") final PaymentStatus status,
+                                   @JsonProperty("userToken") final UUID userToken,
+                                   @JsonProperty("effectiveDate") final DateTime effectiveDate) {
         super(id);
         this.accountId = accountId;
         this.invoiceId = invoiceId;
@@ -62,25 +58,25 @@ public class DefaultPaymentInfoEvent extends EntityBase implements PaymentInfoEv
         this.effectiveDate = effectiveDate;
     }
 
-    
-    public DefaultPaymentInfoEvent(UUID accountId, UUID invoiceId,
-            UUID paymentId, BigDecimal amount, Integer paymentNumber,
-            PaymentStatus status, UUID userToken, DateTime effectiveDate) {
+
+    public DefaultPaymentInfoEvent(final UUID accountId, final UUID invoiceId,
+                                   final UUID paymentId, final BigDecimal amount, final Integer paymentNumber,
+                                   final PaymentStatus status, final UUID userToken, final DateTime effectiveDate) {
         this(UUID.randomUUID(), accountId, invoiceId, paymentId, amount, paymentNumber, status, userToken, effectiveDate);
     }
 
-    public DefaultPaymentInfoEvent(DefaultPaymentInfoEvent src) {
+    public DefaultPaymentInfoEvent(final DefaultPaymentInfoEvent src) {
         this(src.id,
-                src.accountId,
-                src.invoiceId,
-                src.paymentId,
-                src.amount,
-                src.paymentNumber,
-                src.status,
-                src.userToken,
-                src.effectiveDate);
+             src.accountId,
+             src.invoiceId,
+             src.paymentId,
+             src.amount,
+             src.paymentNumber,
+             src.status,
+             src.userToken,
+             src.effectiveDate);
     }
-      
+
 
     @JsonIgnore
     @Override
@@ -160,51 +156,69 @@ public class DefaultPaymentInfoEvent extends EntityBase implements PaymentInfoEv
 
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        DefaultPaymentInfoEvent other = (DefaultPaymentInfoEvent) obj;
+        }
+        final DefaultPaymentInfoEvent other = (DefaultPaymentInfoEvent) obj;
         if (accountId == null) {
-            if (other.accountId != null)
+            if (other.accountId != null) {
                 return false;
-        } else if (!accountId.equals(other.accountId))
+            }
+        } else if (!accountId.equals(other.accountId)) {
             return false;
+        }
         if (amount == null) {
-            if (other.amount != null)
+            if (other.amount != null) {
                 return false;
-        } else if (amount.compareTo(other.amount) != 0)
+            }
+        } else if (amount.compareTo(other.amount) != 0) {
             return false;
+        }
         if (effectiveDate == null) {
-            if (other.effectiveDate != null)
+            if (other.effectiveDate != null) {
                 return false;
-        } else if (effectiveDate.compareTo(other.effectiveDate) != 0)
+            }
+        } else if (effectiveDate.compareTo(other.effectiveDate) != 0) {
             return false;
+        }
         if (invoiceId == null) {
-            if (other.invoiceId != null)
+            if (other.invoiceId != null) {
                 return false;
-        } else if (!invoiceId.equals(other.invoiceId))
+            }
+        } else if (!invoiceId.equals(other.invoiceId)) {
             return false;
+        }
         if (paymentId == null) {
-            if (other.paymentId != null)
+            if (other.paymentId != null) {
                 return false;
-        } else if (!paymentId.equals(other.paymentId))
+            }
+        } else if (!paymentId.equals(other.paymentId)) {
             return false;
+        }
         if (paymentNumber == null) {
-            if (other.paymentNumber != null)
+            if (other.paymentNumber != null) {
                 return false;
-        } else if (!paymentNumber.equals(other.paymentNumber))
+            }
+        } else if (!paymentNumber.equals(other.paymentNumber)) {
             return false;
-        if (status != other.status)
+        }
+        if (status != other.status) {
             return false;
+        }
         if (userToken == null) {
-            if (other.userToken != null)
+            if (other.userToken != null) {
                 return false;
-        } else if (!userToken.equals(other.userToken))
+            }
+        } else if (!userToken.equals(other.userToken)) {
             return false;
+        }
         return true;
     }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentMethod.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentMethod.java
index 1ae4204..e3f57b7 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentMethod.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentMethod.java
@@ -20,23 +20,23 @@ import java.util.UUID;
 import com.ning.billing.payment.dao.PaymentMethodModelDao;
 import com.ning.billing.util.entity.EntityBase;
 
-public class DefaultPaymentMethod extends EntityBase  implements PaymentMethod {
+public class DefaultPaymentMethod extends EntityBase implements PaymentMethod {
 
 
-    private final UUID accountId;    
+    private final UUID accountId;
     private final Boolean isActive;
     private final String pluginName;
     private final PaymentMethodPlugin pluginDetail;
-    
-    public DefaultPaymentMethod(UUID paymentMethodId, UUID accountId, Boolean isActive, String pluginName) {
+
+    public DefaultPaymentMethod(final UUID paymentMethodId, final UUID accountId, final Boolean isActive, final String pluginName) {
         super(paymentMethodId);
         this.accountId = accountId;
         this.isActive = isActive;
         this.pluginName = pluginName;
         this.pluginDetail = null;
     }
-    
-    public DefaultPaymentMethod(UUID paymentMethodId, UUID accountId, Boolean isActive, String pluginName, PaymentMethodPlugin pluginDetail) {
+
+    public DefaultPaymentMethod(final UUID paymentMethodId, final UUID accountId, final Boolean isActive, final String pluginName, final PaymentMethodPlugin pluginDetail) {
         super(paymentMethodId);
         this.accountId = accountId;
         this.isActive = isActive;
@@ -44,15 +44,15 @@ public class DefaultPaymentMethod extends EntityBase  implements PaymentMethod {
         this.pluginDetail = pluginDetail;
     }
 
-    public DefaultPaymentMethod(UUID accountId, String pluginName, PaymentMethodPlugin pluginDetail) {
+    public DefaultPaymentMethod(final UUID accountId, final String pluginName, final PaymentMethodPlugin pluginDetail) {
         this(UUID.randomUUID(), accountId, true, pluginName, pluginDetail);
     }
 
-    public DefaultPaymentMethod(PaymentMethodModelDao input) {
+    public DefaultPaymentMethod(final PaymentMethodModelDao input) {
         this(input.getId(), input.getAccountId(), input.isActive(), input.getPluginName());
     }
 
-    public DefaultPaymentMethod(PaymentMethodModelDao input, PaymentMethodPlugin pluginDetail) {
+    public DefaultPaymentMethod(final PaymentMethodModelDao input, final PaymentMethodPlugin pluginDetail) {
         this(input.getId(), input.getAccountId(), input.isActive(), input.getPluginName(), pluginDetail);
     }
 
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentMethodPlugin.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentMethodPlugin.java
index a27a095..c0aefd3 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentMethodPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentMethodPlugin.java
@@ -22,13 +22,13 @@ public class DefaultPaymentMethodPlugin implements PaymentMethodPlugin {
     private final String externalPaymentMethodId;
     private final boolean isDefaultPaymentMethod;
     private final List<PaymentMethodKVInfo> properties;
-    
-    public DefaultPaymentMethodPlugin(PaymentMethodPlugin src, String externalPaymentId) {
+
+    public DefaultPaymentMethodPlugin(final PaymentMethodPlugin src, final String externalPaymentId) {
         this.externalPaymentMethodId = externalPaymentId;
         this.isDefaultPaymentMethod = src.isDefaultPaymentMethod();
         this.properties = src.getProperties();
     }
-    
+
     @Override
     public String getExternalPaymentMethodId() {
         return externalPaymentMethodId;
@@ -45,7 +45,7 @@ public class DefaultPaymentMethodPlugin implements PaymentMethodPlugin {
     }
 
     @Override
-    public String getValueString(String key) {
+    public String getValueString(final String key) {
         throw new RuntimeException("Not implemented");
     }
 
diff --git a/payment/src/main/java/com/ning/billing/payment/bus/InvoiceHandler.java b/payment/src/main/java/com/ning/billing/payment/bus/InvoiceHandler.java
index 12a2379..e94b175 100644
--- a/payment/src/main/java/com/ning/billing/payment/bus/InvoiceHandler.java
+++ b/payment/src/main/java/com/ning/billing/payment/bus/InvoiceHandler.java
@@ -29,9 +29,6 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.invoice.api.InvoiceCreationEvent;
-
-
-import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.core.PaymentProcessor;
 import com.ning.billing.util.api.TagUserApi;
@@ -58,15 +55,15 @@ public class InvoiceHandler {
     private final AccountUserApi accountUserApi;
     private final Clock clock;
     private final TagUserApi tagUserApi;
-    
+
 
     private static final Logger log = LoggerFactory.getLogger(InvoiceHandler.class);
 
     @Inject
     public InvoiceHandler(final Clock clock,
-            final AccountUserApi accountUserApi,
-            final PaymentProcessor paymentProcessor,
-            final TagUserApi tagUserApi) {        
+                          final AccountUserApi accountUserApi,
+                          final PaymentProcessor paymentProcessor,
+                          final TagUserApi tagUserApi) {
         this.clock = clock;
         this.accountUserApi = accountUserApi;
         this.tagUserApi = tagUserApi;
@@ -75,20 +72,20 @@ public class InvoiceHandler {
 
 
     @Subscribe
-    public void processInvoiceEvent(InvoiceCreationEvent event) {
-        
+    public void processInvoiceEvent(final InvoiceCreationEvent event) {
+
         log.info("Received invoice creation notification for account {} and invoice {}",
-                    event.getAccountId(), event.getInvoiceId());
+                 event.getAccountId(), event.getInvoiceId());
 
-        Account account = null;        
+        Account account = null;
         try {
             account = accountUserApi.getAccountById(event.getAccountId());
             if (isAccountAutoPayOff(account.getId())) {
                 return;
             }
-            CallContext context = new DefaultCallContext("PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken(), clock);
+            final CallContext context = new DefaultCallContext("PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken(), clock);
             paymentProcessor.createPayment(account, event.getInvoiceId(), null, context, false);
-        } catch(AccountApiException e) {
+        } catch (AccountApiException e) {
             log.error("Failed to process invoice payment", e);
         } catch (PaymentApiException e) {
             if (e.getCode() != ErrorCode.PAYMENT_NULL_INVOICE.getCode()) {
@@ -96,10 +93,10 @@ public class InvoiceHandler {
             }
         }
     }
-    
-    private boolean isAccountAutoPayOff(UUID accountId) {
-        Map<String, Tag> accountTags =  tagUserApi.getTags(accountId, ObjectType.ACCOUNT);
-        for (Tag cur : accountTags.values()) {
+
+    private boolean isAccountAutoPayOff(final UUID accountId) {
+        final Map<String, Tag> accountTags = tagUserApi.getTags(accountId, ObjectType.ACCOUNT);
+        for (final Tag cur : accountTags.values()) {
             if (cur.getTagDefinitionName().equals(ControlTagType.AUTO_PAY_OFF.toString())) {
                 return true;
             }
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
index 41b79a4..eb972c6 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentMethodProcessor.java
@@ -15,8 +15,6 @@
  */
 package com.ning.billing.payment.core;
 
-import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedList;
@@ -35,41 +33,39 @@ import com.ning.billing.account.api.DefaultMutableAccountData;
 import com.ning.billing.account.api.MutableAccountData;
 import com.ning.billing.payment.api.DefaultPaymentMethod;
 import com.ning.billing.payment.api.DefaultPaymentMethodPlugin;
-import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentMethod;
 import com.ning.billing.payment.api.PaymentMethodPlugin;
-import com.ning.billing.payment.core.ProcessorBase.CallableWithAccountLock;
-import com.ning.billing.payment.core.ProcessorBase.WithAccountLockCallback;
 import com.ning.billing.payment.dao.PaymentDao;
 import com.ning.billing.payment.dao.PaymentMethodModelDao;
-import com.ning.billing.payment.dispatcher.PluginDispatcher;
-import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
 import com.ning.billing.payment.plugin.api.PaymentPluginApi;
+import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
 import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.globallocker.GlobalLocker;
 
+import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
+
 public class PaymentMethodProcessor extends ProcessorBase {
-    
+
     @Inject
     public PaymentMethodProcessor(final PaymentProviderPluginRegistry pluginRegistry,
-            final AccountUserApi accountUserApi,
-            final Bus eventBus,
-            final PaymentDao paymentDao,
-            final GlobalLocker locker,
-            @Named(PLUGIN_EXECUTOR_NAMED)  final ExecutorService executor) {
+                                  final AccountUserApi accountUserApi,
+                                  final Bus eventBus,
+                                  final PaymentDao paymentDao,
+                                  final GlobalLocker locker,
+                                  @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
         super(pluginRegistry, accountUserApi, eventBus, paymentDao, locker, executor);
     }
-    
+
     public Set<String> getAvailablePlugins() {
         return pluginRegistry.getRegisteredPluginNames();
     }
 
 
     public String initializeAccountPlugin(final String pluginName, final Account account) throws PaymentApiException {
-    
+
         return new WithAccountLock<String>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<String>() {
 
             @Override
@@ -81,7 +77,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                     return pluginApi.createPaymentProviderAccount(account);
                 } catch (PaymentPluginApiException e) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_ACCOUNT_INIT,
-                            account.getId(), pluginApi != null ? pluginApi.getName() : null, e.getErrorMessage());
+                                                  account.getId(), pluginApi != null ? pluginApi.getName() : null, e.getErrorMessage());
                 }
             }
         });
@@ -89,9 +85,9 @@ public class PaymentMethodProcessor extends ProcessorBase {
 
 
     public UUID addPaymentMethod(final String pluginName, final Account account,
-            final boolean setDefault, final PaymentMethodPlugin paymentMethodProps, final CallContext context) 
-    throws PaymentApiException {
-        
+                                 final boolean setDefault, final PaymentMethodPlugin paymentMethodProps, final CallContext context)
+            throws PaymentApiException {
+
         return new WithAccountLock<UUID>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<UUID>() {
 
             @Override
@@ -101,12 +97,12 @@ public class PaymentMethodProcessor extends ProcessorBase {
                 try {
                     pluginApi = pluginRegistry.getPlugin(pluginName);
                     pm = new DefaultPaymentMethod(account.getId(), pluginName, paymentMethodProps);
-                    String externalId = pluginApi.addPaymentMethod(account.getExternalKey(), paymentMethodProps, setDefault);
-                    PaymentMethodModelDao pmModel = new PaymentMethodModelDao(pm.getId(), pm.getAccountId(), pm.getPluginName(), pm.isActive(), externalId);
+                    final String externalId = pluginApi.addPaymentMethod(account.getExternalKey(), paymentMethodProps, setDefault);
+                    final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(pm.getId(), pm.getAccountId(), pm.getPluginName(), pm.isActive(), externalId);
                     paymentDao.insertPaymentMethod(pmModel, context);
-                    
+
                     if (setDefault) {
-                        MutableAccountData updateAccountData = new DefaultMutableAccountData(account);
+                        final MutableAccountData updateAccountData = new DefaultMutableAccountData(account);
                         updateAccountData.setPaymentMethodId(pm.getId());
                         accountUserApi.updateAccount(account.getId(), updateAccountData, context);
                     }
@@ -114,29 +110,29 @@ public class PaymentMethodProcessor extends ProcessorBase {
                     // STEPH all errors should also take a pluginName
                     throw new PaymentApiException(ErrorCode.PAYMENT_ADD_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
                 } catch (AccountApiException e) {
-                    throw new PaymentApiException(e);            
+                    throw new PaymentApiException(e);
                 }
                 return pm.getId();
             }
         });
     }
-  
+
 
     public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final CallContext context)
-    throws PaymentApiException {
+            throws PaymentApiException {
 
         return new WithAccountLock<List<PaymentMethod>>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<List<PaymentMethod>>() {
 
             @Override
             public List<PaymentMethod> doOperation() throws PaymentApiException {
-                List<PaymentMethod> result = new LinkedList<PaymentMethod>();
+                final List<PaymentMethod> result = new LinkedList<PaymentMethod>();
                 PaymentPluginApi pluginApi = null;
                 try {
-                    pluginApi = pluginRegistry.getPlugin(pluginName);            
-                    List<PaymentMethodPlugin> pluginPms = pluginApi.getPaymentMethodDetails(account.getExternalKey());
-                    for (PaymentMethodPlugin cur : pluginPms) {
-                        PaymentMethod input = new DefaultPaymentMethod(account.getId(), pluginName, cur);
-                        PaymentMethodModelDao pmModel = new PaymentMethodModelDao(input.getId(), input.getAccountId(), input.getPluginName(), input.isActive(), input.getPluginDetail().getExternalPaymentMethodId());
+                    pluginApi = pluginRegistry.getPlugin(pluginName);
+                    final List<PaymentMethodPlugin> pluginPms = pluginApi.getPaymentMethodDetails(account.getExternalKey());
+                    for (final PaymentMethodPlugin cur : pluginPms) {
+                        final PaymentMethod input = new DefaultPaymentMethod(account.getId(), pluginName, cur);
+                        final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(input.getId(), input.getAccountId(), input.getPluginName(), input.isActive(), input.getPluginDetail().getExternalPaymentMethodId());
                         // STEPH we should insert within one batch
                         paymentDao.insertPaymentMethod(pmModel, context);
                         result.add(input);
@@ -150,50 +146,50 @@ public class PaymentMethodProcessor extends ProcessorBase {
         });
     }
 
-    public List<PaymentMethod> getPaymentMethods(Account account, boolean withPluginDetail) throws PaymentApiException {
+    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginDetail) throws PaymentApiException {
 
-        List<PaymentMethodModelDao> paymentMethodModels = paymentDao.getPaymentMethods(account.getId());
+        final List<PaymentMethodModelDao> paymentMethodModels = paymentDao.getPaymentMethods(account.getId());
         if (paymentMethodModels.size() == 0) {
             return Collections.emptyList();
         }
         return getPaymentMethodInternal(paymentMethodModels, account.getId(), account.getExternalKey(), withPluginDetail);
     }
 
-    public PaymentMethod getPaymentMethodById(UUID paymentMethodId)
-    throws PaymentApiException {
-        PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
+    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId)
+            throws PaymentApiException {
+        final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
         if (paymentMethodModel == null) {
-            throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId); 
+            throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
         }
         return new DefaultPaymentMethod(paymentMethodModel, null);
     }
-    
-    public PaymentMethod getPaymentMethod(Account account, UUID paymentMethodId, boolean withPluginDetail) 
-    throws PaymentApiException {
-        PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
+
+    public PaymentMethod getPaymentMethod(final Account account, final UUID paymentMethodId, final boolean withPluginDetail)
+            throws PaymentApiException {
+        final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
         if (paymentMethodModel == null) {
-            throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);             
+            throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
         }
-        List<PaymentMethod> result =  getPaymentMethodInternal(Collections.singletonList(paymentMethodModel), account.getId(), account.getExternalKey(), withPluginDetail);
-        return (result.size() == 0) ? null : result.get(0); 
+        final List<PaymentMethod> result = getPaymentMethodInternal(Collections.singletonList(paymentMethodModel), account.getId(), account.getExternalKey(), withPluginDetail);
+        return (result.size() == 0) ? null : result.get(0);
     }
 
 
-    private List<PaymentMethod> getPaymentMethodInternal(List<PaymentMethodModelDao> paymentMethodModels, UUID accountId, String accountKey, boolean withPluginDetail)
-    throws PaymentApiException {
+    private List<PaymentMethod> getPaymentMethodInternal(final List<PaymentMethodModelDao> paymentMethodModels, final UUID accountId, final String accountKey, final boolean withPluginDetail)
+            throws PaymentApiException {
 
-        List<PaymentMethod> result = new ArrayList<PaymentMethod>(paymentMethodModels.size());
+        final List<PaymentMethod> result = new ArrayList<PaymentMethod>(paymentMethodModels.size());
         PaymentPluginApi pluginApi = null;
         try {
-            List<PaymentMethodPlugin> pluginDetails = null;            
-            for (PaymentMethodModelDao cur : paymentMethodModels) {
-                
+            List<PaymentMethodPlugin> pluginDetails = null;
+            for (final PaymentMethodModelDao cur : paymentMethodModels) {
+
                 if (withPluginDetail) {
                     pluginApi = pluginRegistry.getPlugin(cur.getPluginName());
-                    pluginDetails = pluginApi.getPaymentMethodDetails(accountKey); 
+                    pluginDetails = pluginApi.getPaymentMethodDetails(accountKey);
                 }
-                
-                PaymentMethod pm = new DefaultPaymentMethod(cur, getPaymentMethodDetail(pluginDetails, cur.getExternalId()));
+
+                final PaymentMethod pm = new DefaultPaymentMethod(cur, getPaymentMethodDetail(pluginDetails, cur.getExternalId()));
                 result.add(pm);
             }
         } catch (PaymentPluginApiException e) {
@@ -201,13 +197,13 @@ public class PaymentMethodProcessor extends ProcessorBase {
         }
         return result;
     }
-    
-    
-    private PaymentMethodPlugin getPaymentMethodDetail(List<PaymentMethodPlugin> pluginDetails, String externalId) {
+
+
+    private PaymentMethodPlugin getPaymentMethodDetail(final List<PaymentMethodPlugin> pluginDetails, final String externalId) {
         if (pluginDetails == null) {
             return null;
         }
-        for (PaymentMethodPlugin cur : pluginDetails) {
+        for (final PaymentMethodPlugin cur : pluginDetails) {
             if (cur.getExternalPaymentMethodId().equals(externalId)) {
                 return cur;
             }
@@ -216,89 +212,91 @@ public class PaymentMethodProcessor extends ProcessorBase {
     }
 
     public void updatePaymentMethod(final Account account, final UUID paymentMethodId,
-            final PaymentMethodPlugin paymentMethodProps) 
-    throws PaymentApiException {
+                                    final PaymentMethodPlugin paymentMethodProps)
+            throws PaymentApiException {
 
         new WithAccountLock<Void>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<Void>() {
 
             @Override
             public Void doOperation() throws PaymentApiException {
-                PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
+                final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
                 if (paymentMethodModel == null) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, account.getId(), paymentMethodId);
                 }
 
                 try {
-                    PaymentMethodPlugin inputWithId = new DefaultPaymentMethodPlugin(paymentMethodProps, paymentMethodModel.getExternalId());
-                    PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId());    
+                    final PaymentMethodPlugin inputWithId = new DefaultPaymentMethodPlugin(paymentMethodProps, paymentMethodModel.getExternalId());
+                    final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId());
                     pluginApi.updatePaymentMethod(account.getExternalKey(), inputWithId);
                     return null;
                 } catch (PaymentPluginApiException e) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_UPD_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
                 }
             }
-        }); 
+        });
     }
 
 
-    public void deletedPaymentMethod(final Account account, final UUID paymentMethodId) 
-    throws PaymentApiException {
+    public void deletedPaymentMethod(final Account account, final UUID paymentMethodId)
+            throws PaymentApiException {
 
         new WithAccountLock<Void>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<Void>() {
 
             @Override
             public Void doOperation() throws PaymentApiException {
-                PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
+                final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
                 if (paymentMethodModel == null) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, account.getId(), paymentMethodId);
                 }
 
                 try {
                     if (account.getPaymentMethodId().equals(paymentMethodId)) {
-                        throw new PaymentApiException(ErrorCode.PAYMENT_DEL_DEFAULT_PAYMENT_METHOD, account.getId());                
+                        throw new PaymentApiException(ErrorCode.PAYMENT_DEL_DEFAULT_PAYMENT_METHOD, account.getId());
                     }
-                    PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId());                
+                    final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId());
                     pluginApi.deletePaymentMethod(account.getExternalKey(), paymentMethodModel.getExternalId());
                     paymentDao.deletedPaymentMethod(paymentMethodId);
                     return null;
                 } catch (PaymentPluginApiException e) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_DEL_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
                 }
-            }});       
-        }
+            }
+        });
+    }
 
-    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context) 
-    throws PaymentApiException {
+    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
+            throws PaymentApiException {
 
         new WithAccountLock<Void>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<Void>() {
 
             @Override
             public Void doOperation() throws PaymentApiException {
-                PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
+                final PaymentMethodModelDao paymentMethodModel = paymentDao.getPaymentMethod(paymentMethodId);
                 if (paymentMethodModel == null) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, account.getId(), paymentMethodId);
                 }
 
                 try {
-                    PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId());                            
+                    final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, account.getId());
                     pluginApi.setDefaultPaymentMethod(account.getExternalKey(), paymentMethodModel.getExternalId());
-                    MutableAccountData updateAccountData = new DefaultMutableAccountData(account);
+                    final MutableAccountData updateAccountData = new DefaultMutableAccountData(account);
                     updateAccountData.setPaymentMethodId(paymentMethodId);
                     accountUserApi.updateAccount(account.getId(), updateAccountData, context);
                     return null;
                 } catch (PaymentPluginApiException e) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_UPD_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
                 } catch (AccountApiException e) {
-                    throw new PaymentApiException(e);            
+                    throw new PaymentApiException(e);
                 }
-            }});               
+            }
+        });
     }
 
-    private PaymentPluginApi getPluginApi(UUID paymentMethodId, UUID accountId)
-        throws PaymentApiException {
-        PaymentMethodModelDao paymentMethod = paymentDao.getPaymentMethod(paymentMethodId);
+    private PaymentPluginApi getPluginApi(final UUID paymentMethodId, final UUID accountId)
+            throws PaymentApiException {
+        final PaymentMethodModelDao paymentMethod = paymentDao.getPaymentMethod(paymentMethodId);
         if (paymentMethod == null) {
-            throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, accountId, "");                
+            throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, accountId, "");
         }
         return pluginRegistry.getPlugin(paymentMethod.getPluginName());
     }
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
index 3b44130..20e30b5 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
@@ -15,8 +15,7 @@
  */
 package com.ning.billing.payment.core;
 
-import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
-
+import javax.inject.Inject;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.Collections;
@@ -26,8 +25,6 @@ import java.util.UUID;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeoutException;
 
-import javax.inject.Inject;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -51,8 +48,8 @@ import com.ning.billing.payment.dao.PaymentDao;
 import com.ning.billing.payment.dao.PaymentModelDao;
 import com.ning.billing.payment.dispatcher.PluginDispatcher;
 import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
-import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
 import com.ning.billing.payment.plugin.api.PaymentPluginApi;
+import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
 import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
 import com.ning.billing.payment.retry.FailedPaymentRetryService.FailedPaymentRetryServiceScheduler;
 import com.ning.billing.payment.retry.PluginFailureRetryService.PluginFailureRetryServiceScheduler;
@@ -65,17 +62,19 @@ import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.globallocker.GlobalLocker;
 
+import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
+
 public class PaymentProcessor extends ProcessorBase {
-    
+
     private final InvoicePaymentApi invoicePaymentApi;
     private final FailedPaymentRetryServiceScheduler failedPaymentRetryService;
     private final PluginFailureRetryServiceScheduler pluginFailureRetryService;
     private final CallContextFactory factory;
     private final Clock clock;
-    
+
     private final PluginDispatcher<Payment> paymentPluginDispatcher;
-    private final PluginDispatcher<Void> voidPluginDispatcher;    
-    
+    private final PluginDispatcher<Void> voidPluginDispatcher;
+
     private static final Logger log = LoggerFactory.getLogger(PaymentProcessor.class);
 
     @Inject
@@ -88,7 +87,7 @@ public class PaymentProcessor extends ProcessorBase {
             final Bus eventBus,
             final Clock clock,
             final GlobalLocker locker,
-            @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor,            
+            @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor,
             final CallContextFactory factory) {
         super(pluginRegistry, accountUserApi, eventBus, paymentDao, locker, executor);
         this.invoicePaymentApi = invoicePaymentApi;
@@ -99,39 +98,39 @@ public class PaymentProcessor extends ProcessorBase {
         this.paymentPluginDispatcher = new PluginDispatcher<Payment>(executor);
         this.voidPluginDispatcher = new PluginDispatcher<Void>(executor);
     }
-  
-    public Payment getPayment(UUID paymentId) {
-        PaymentModelDao model = paymentDao.getPayment(paymentId);
+
+    public Payment getPayment(final UUID paymentId) {
+        final PaymentModelDao model = paymentDao.getPayment(paymentId);
         if (model == null) {
             return null;
         }
-        return getPayments(Collections.singletonList(model)).get(0);        
+        return getPayments(Collections.singletonList(model)).get(0);
     }
 
-    
-    public List<Payment> getInvoicePayments(UUID invoiceId) {
-        return getPayments(paymentDao.getPaymentsForInvoice(invoiceId));        
+
+    public List<Payment> getInvoicePayments(final UUID invoiceId) {
+        return getPayments(paymentDao.getPaymentsForInvoice(invoiceId));
     }
 
-    
-    public List<Payment> getAccountPayments(UUID accountId) {
+
+    public List<Payment> getAccountPayments(final UUID accountId) {
         return getPayments(paymentDao.getPaymentsForAccount(accountId));
     }
-    
-    private List<Payment> getPayments(List<PaymentModelDao> payments) {
+
+    private List<Payment> getPayments(final List<PaymentModelDao> payments) {
         if (payments == null) {
             return Collections.emptyList();
         }
-        List<Payment> result = new LinkedList<Payment>();
-        for (PaymentModelDao cur : payments) {
-            List<PaymentAttemptModelDao> attempts =  paymentDao.getAttemptsForPayment(cur.getId());
-            Payment entry = new DefaultPayment(cur, attempts);
+        final List<Payment> result = new LinkedList<Payment>();
+        for (final PaymentModelDao cur : payments) {
+            final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(cur.getId());
+            final Payment entry = new DefaultPayment(cur, attempts);
             result.add(entry);
         }
         return result;
     }
 
-    public Payment createPayment(final String accountKey, final UUID invoiceId, final BigDecimal inputAmount, final CallContext context, final boolean isInstantPayment) 
+    public Payment createPayment(final String accountKey, final UUID invoiceId, final BigDecimal inputAmount, final CallContext context, final boolean isInstantPayment)
     throws PaymentApiException {
         try {
             final Account account = accountUserApi.getAccountByKey(accountKey);
@@ -141,7 +140,7 @@ public class PaymentProcessor extends ProcessorBase {
         }
     }
 
-    public Payment createPayment(final Account account, final UUID invoiceId, final BigDecimal inputAmount , final CallContext context,  final boolean isInstantPayment)
+    public Payment createPayment(final Account account, final UUID invoiceId, final BigDecimal inputAmount, final CallContext context, final boolean isInstantPayment)
     throws PaymentApiException {
 
         final PaymentPluginApi plugin = getPaymentProviderPlugin(account);
@@ -160,7 +159,7 @@ public class PaymentProcessor extends ProcessorBase {
                         return null;
                     }
 
-                    BigDecimal requestedAmount = getAndValidatePaymentAmount(invoice, inputAmount, isInstantPayment);
+                    final BigDecimal requestedAmount = getAndValidatePaymentAmount(invoice, inputAmount, isInstantPayment);
                     return processNewPaymentWithAccountLocked(plugin, account, invoice, requestedAmount, isInstantPayment, context);
                 }
             }));
@@ -177,20 +176,19 @@ public class PaymentProcessor extends ProcessorBase {
             }
         }
     }
-    
 
 
-    private BigDecimal getAndValidatePaymentAmount(final Invoice invoice,  final BigDecimal inputAmount, final boolean isInstantPayment)
+    private BigDecimal getAndValidatePaymentAmount(final Invoice invoice, final BigDecimal inputAmount, final boolean isInstantPayment)
     throws PaymentApiException {
 
-        if (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0 ) {
+        if (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NULL_INVOICE, invoice.getId());
         }
         if (isInstantPayment &&
                 inputAmount != null &&
                 invoice.getBalance().compareTo(inputAmount) < 0) {
-                    throw new PaymentApiException(ErrorCode.PAYMENT_AMOUNT_DENIED,
-                            invoice.getId(), inputAmount.floatValue(), invoice.getBalance().floatValue());   
+            throw new PaymentApiException(ErrorCode.PAYMENT_AMOUNT_DENIED,
+                    invoice.getId(), inputAmount.floatValue(), invoice.getBalance().floatValue());
         }
         return inputAmount != null ? inputAmount : invoice.getBalance();
     }
@@ -199,16 +197,16 @@ public class PaymentProcessor extends ProcessorBase {
     public void retryPluginFailure(final UUID paymentId) {
         retryFailedPaymentInternal(paymentId, PaymentStatus.PLUGIN_FAILURE, PaymentStatus.TIMEDOUT);
     }
-    
+
     public void retryFailedPayment(final UUID paymentId) {
-        retryFailedPaymentInternal(paymentId, PaymentStatus.PAYMENT_FAILURE);    
+        retryFailedPaymentInternal(paymentId, PaymentStatus.PAYMENT_FAILURE);
     }
-    
-    private void retryFailedPaymentInternal(final UUID paymentId, final PaymentStatus...expectedPaymentStates) {
+
+    private void retryFailedPaymentInternal(final UUID paymentId, final PaymentStatus... expectedPaymentStates) {
 
         try {
-            
-            PaymentModelDao payment = paymentDao.getPayment(paymentId);
+
+            final PaymentModelDao payment = paymentDao.getPayment(paymentId);
             if (payment == null) {
                 log.error("Invalid retry for non existnt paymentId {}", paymentId);
                 return;
@@ -217,7 +215,7 @@ public class PaymentProcessor extends ProcessorBase {
             final Account account = accountUserApi.getAccountById(payment.getAccountId());
             final PaymentPluginApi plugin = getPaymentProviderPlugin(account);
             final CallContext context = factory.createCallContext("PaymentRetry", CallOrigin.INTERNAL, UserType.SYSTEM);
-            
+
             voidPluginDispatcher.dispatchWithAccountLock(new CallableWithAccountLock<Void>(locker,
                     account.getExternalKey(),
                     new WithAccountLockCallback<Void>() {
@@ -226,9 +224,9 @@ public class PaymentProcessor extends ProcessorBase {
                 public Void doOperation() throws PaymentApiException {
 
                     // Fetch gain with account lock this time
-                    PaymentModelDao payment = paymentDao.getPayment(paymentId);
+                    final PaymentModelDao payment = paymentDao.getPayment(paymentId);
                     boolean foundExpectedState = false;
-                    for (PaymentStatus cur : expectedPaymentStates) {
+                    for (final PaymentStatus cur : expectedPaymentStates) {
                         if (payment.getPaymentStatus() == cur) {
                             foundExpectedState = true;
                             break;
@@ -243,7 +241,7 @@ public class PaymentProcessor extends ProcessorBase {
                     if (invoice.isMigrationInvoice()) {
                         return null;
                     }
-                    if (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0 ) {
+                    if (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
                         log.info("Aborted retry for payment {} because invoice has been paid", paymentId);
                         return null;
                     }
@@ -262,29 +260,29 @@ public class PaymentProcessor extends ProcessorBase {
         }
     }
 
-    private Payment processNewPaymentWithAccountLocked(PaymentPluginApi plugin, Account account, Invoice invoice,
-            BigDecimal requestedAmount, boolean isInstantPayment, CallContext context) throws PaymentApiException {
-        
+    private Payment processNewPaymentWithAccountLocked(final PaymentPluginApi plugin, final Account account, final Invoice invoice,
+            final BigDecimal requestedAmount, final boolean isInstantPayment, final CallContext context) throws PaymentApiException {
+
         final boolean scheduleRetryForPayment = !isInstantPayment;
-        PaymentModelDao payment = new PaymentModelDao(account.getId(), invoice.getId(), requestedAmount.setScale(2, RoundingMode.HALF_EVEN), invoice.getCurrency(), invoice.getTargetDate());
-        PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow(), requestedAmount);
-        
-        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, scheduleRetryForPayment, context);
+        final PaymentModelDao payment = new PaymentModelDao(account.getId(), invoice.getId(), requestedAmount.setScale(2, RoundingMode.HALF_EVEN), invoice.getCurrency(), invoice.getTargetDate());
+        final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow(), requestedAmount);
+
+        final PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, scheduleRetryForPayment, context);
         return processPaymentWithAccountLocked(plugin, account, invoice, savedPayment, attempt, isInstantPayment, context);
     }
-    
-    private Payment processRetryPaymentWithAccountLocked(PaymentPluginApi plugin, Account account, Invoice invoice, PaymentModelDao payment,
-            BigDecimal requestedAmount, CallContext context) throws PaymentApiException {
+
+    private Payment processRetryPaymentWithAccountLocked(final PaymentPluginApi plugin, final Account account, final Invoice invoice, final PaymentModelDao payment,
+            final BigDecimal requestedAmount, final CallContext context) throws PaymentApiException {
         final boolean scheduleRetryForPayment = true;
-        PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow(), requestedAmount);
+        final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow(), requestedAmount);
         paymentDao.insertNewAttemptForPayment(payment.getId(), attempt, scheduleRetryForPayment, context);
         return processPaymentWithAccountLocked(plugin, account, invoice, payment, attempt, false, context);
     }
 
-    
-    private Payment processPaymentWithAccountLocked(PaymentPluginApi plugin, Account account, Invoice invoice,
-            PaymentModelDao paymentInput, PaymentAttemptModelDao attemptInput, boolean isInstantPayment, CallContext context) throws PaymentApiException {
-        
+
+    private Payment processPaymentWithAccountLocked(final PaymentPluginApi plugin, final Account account, final Invoice invoice,
+            final PaymentModelDao paymentInput, final PaymentAttemptModelDao attemptInput, final boolean isInstantPayment, final CallContext context) throws PaymentApiException {
+
         BusEvent event = null;
         List<PaymentAttemptModelDao> allAttempts = null;
         PaymentAttemptModelDao lastAttempt = null;
@@ -292,7 +290,7 @@ public class PaymentProcessor extends ProcessorBase {
         PaymentStatus paymentStatus = PaymentStatus.UNKNOWN;
         try {
 
-            PaymentInfoPlugin paymentPluginInfo = plugin.processPayment(account.getExternalKey(), paymentInput.getId(), attemptInput.getRequestedAmount());
+            final PaymentInfoPlugin paymentPluginInfo = plugin.processPayment(account.getExternalKey(), paymentInput.getId(), attemptInput.getRequestedAmount());
             switch (paymentPluginInfo.getStatus()) {
             case PROCESSED:
                 // Update Payment/PaymentAttempt status
@@ -303,19 +301,19 @@ public class PaymentProcessor extends ProcessorBase {
                 allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId());
                 lastAttempt = allAttempts.get(allAttempts.size() - 1);
                 payment = paymentDao.getPayment(paymentInput.getId());
-                
+
                 invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
                         paymentStatus == PaymentStatus.SUCCESS ? payment.getAmount() : null,
-                        paymentStatus == PaymentStatus.SUCCESS ? payment.getCurrency() : null,
-                        lastAttempt.getId(),
-                        lastAttempt.getEffectiveDate(),
-                        context);
-                
+                                paymentStatus == PaymentStatus.SUCCESS ? payment.getCurrency() : null,
+                                        lastAttempt.getId(),
+                                        lastAttempt.getEffectiveDate(),
+                                        context);
+
                 // Create Bus event
                 event = new DefaultPaymentInfoEvent(account.getId(),
                         invoice.getId(), payment.getId(), payment.getAmount(), payment.getPaymentNumber(), paymentStatus, context.getUserToken(), payment.getEffectiveDate());
                 break;
-                
+
             case ERROR:
                 // Schedule if non instant payment and max attempt for retry not reached yet
                 if (!isInstantPayment) {
@@ -323,7 +321,7 @@ public class PaymentProcessor extends ProcessorBase {
                     final int retryAttempt = getNumberAttemptsInState(paymentInput.getId(), allAttempts,
                             PaymentStatus.UNKNOWN, PaymentStatus.PAYMENT_FAILURE);
                     final boolean isScheduledForRetry = failedPaymentRetryService.scheduleRetry(paymentInput.getId(), retryAttempt);
-                    paymentStatus = isScheduledForRetry ? PaymentStatus.PAYMENT_FAILURE : PaymentStatus.PAYMENT_FAILURE_ABORTED; 
+                    paymentStatus = isScheduledForRetry ? PaymentStatus.PAYMENT_FAILURE : PaymentStatus.PAYMENT_FAILURE_ABORTED;
                 } else {
                     paymentStatus = PaymentStatus.PAYMENT_FAILURE_ABORTED;
                 }
@@ -332,27 +330,27 @@ public class PaymentProcessor extends ProcessorBase {
 
                 log.info(String.format("Could not process payment for account %s, invoice %s, error = %s",
                         account.getId(), invoice.getId(), paymentPluginInfo.getGatewayError()));
-                
-                event = new DefaultPaymentErrorEvent(account.getId(), invoice.getId(), paymentInput.getId(), paymentPluginInfo.getGatewayError(), context.getUserToken());                        
+
+                event = new DefaultPaymentErrorEvent(account.getId(), invoice.getId(), paymentInput.getId(), paymentPluginInfo.getGatewayError(), context.getUserToken());
                 throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT, account.getId(), paymentPluginInfo.getGatewayError());
-                
+
             default:
-                String formatError = String.format("Plugin return status %s for payment %s", paymentPluginInfo.getStatus(), paymentInput.getId());
+                final String formatError = String.format("Plugin return status %s for payment %s", paymentPluginInfo.getStatus(), paymentInput.getId());
                 // This caught right below as a retryable Plugin failure
                 throw new PaymentPluginApiException("", formatError);
             }
-            
+
         } catch (PaymentPluginApiException e) {
             //
             // An exception occurred, we are left in an unknown state, we need to schedule a retry
             //
-            paymentStatus = isInstantPayment ? PaymentStatus.PAYMENT_FAILURE_ABORTED : scheduleRetryOnPluginFailure(paymentInput.getId());  
+            paymentStatus = isInstantPayment ? PaymentStatus.PAYMENT_FAILURE_ABORTED : scheduleRetryOnPluginFailure(paymentInput.getId());
             // STEPH message might need truncation to fit??
-            
+
             paymentDao.updateStatusForPaymentWithAttempt(paymentInput.getId(), paymentStatus, e.getMessage(), attemptInput.getId(), context);
 
             throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT, account.getId(), e.getMessage());
-            
+
         } finally {
             if (event != null) {
                 postPaymentEvent(event, account.getId());
@@ -360,22 +358,22 @@ public class PaymentProcessor extends ProcessorBase {
         }
         return new DefaultPayment(payment, allAttempts);
     }
-    
-    private PaymentStatus scheduleRetryOnPluginFailure(UUID paymentId) {
-        List<PaymentAttemptModelDao> allAttempts = paymentDao.getAttemptsForPayment(paymentId);
+
+    private PaymentStatus scheduleRetryOnPluginFailure(final UUID paymentId) {
+        final List<PaymentAttemptModelDao> allAttempts = paymentDao.getAttemptsForPayment(paymentId);
         final int retryAttempt = getNumberAttemptsInState(paymentId, allAttempts, PaymentStatus.UNKNOWN, PaymentStatus.PLUGIN_FAILURE);
         final boolean isScheduledForRetry = pluginFailureRetryService.scheduleRetry(paymentId, retryAttempt);
-        return isScheduledForRetry ? PaymentStatus.PLUGIN_FAILURE : PaymentStatus.PLUGIN_FAILURE_ABORTED; 
+        return isScheduledForRetry ? PaymentStatus.PLUGIN_FAILURE : PaymentStatus.PLUGIN_FAILURE_ABORTED;
     }
-    
-    private int getNumberAttemptsInState(final UUID paymentId, final List<PaymentAttemptModelDao> allAttempts, final PaymentStatus...statuses) {
+
+    private int getNumberAttemptsInState(final UUID paymentId, final List<PaymentAttemptModelDao> allAttempts, final PaymentStatus... statuses) {
         if (allAttempts == null || allAttempts.size() == 0) {
             return 0;
         }
         return Collections2.filter(allAttempts, new Predicate<PaymentAttemptModelDao>() {
             @Override
-            public boolean apply(PaymentAttemptModelDao input) {
-                for (PaymentStatus cur : statuses) {
+            public boolean apply(final PaymentAttemptModelDao input) {
+                for (final PaymentStatus cur : statuses) {
                     if (input.getPaymentStatus() == cur) {
                         return true;
                     }
diff --git a/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java b/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
index 1901ee7..4e5c71f 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/ProcessorBase.java
@@ -18,7 +18,6 @@ package com.ning.billing.payment.core;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,17 +32,17 @@ import com.ning.billing.payment.dao.PaymentMethodModelDao;
 import com.ning.billing.payment.plugin.api.PaymentPluginApi;
 import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
 import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.bus.BusEvent;
 import com.ning.billing.util.bus.Bus.EventBusException;
+import com.ning.billing.util.bus.BusEvent;
 import com.ning.billing.util.globallocker.GlobalLock;
 import com.ning.billing.util.globallocker.GlobalLocker;
-import com.ning.billing.util.globallocker.LockFailedException;
 import com.ning.billing.util.globallocker.GlobalLocker.LockerService;
+import com.ning.billing.util.globallocker.LockFailedException;
 
 public abstract class ProcessorBase {
 
-    private final static int NB_LOCK_TRY = 5;
-    
+    private static final int NB_LOCK_TRY = 5;
+
     protected final PaymentProviderPluginRegistry pluginRegistry;
     protected final AccountUserApi accountUserApi;
     protected final Bus eventBus;
@@ -52,51 +51,51 @@ public abstract class ProcessorBase {
     protected final PaymentDao paymentDao;
 
     private static final Logger log = LoggerFactory.getLogger(ProcessorBase.class);
-    
+
     public ProcessorBase(final PaymentProviderPluginRegistry pluginRegistry,
-            final AccountUserApi accountUserApi,
-            final Bus eventBus,
-            final PaymentDao paymentDao,
-            final GlobalLocker locker,
-            final ExecutorService executor) {
+                         final AccountUserApi accountUserApi,
+                         final Bus eventBus,
+                         final PaymentDao paymentDao,
+                         final GlobalLocker locker,
+                         final ExecutorService executor) {
         this.pluginRegistry = pluginRegistry;
         this.accountUserApi = accountUserApi;
-        this.eventBus= eventBus;
+        this.eventBus = eventBus;
         this.paymentDao = paymentDao;
         this.locker = locker;
         this.executor = executor;
     }
-    
-    
-    protected PaymentPluginApi getPaymentProviderPlugin(String accountKey)
-        throws AccountApiException, PaymentApiException {
 
-        String paymentProviderName = null;
+
+    protected PaymentPluginApi getPaymentProviderPlugin(final String accountKey)
+            throws AccountApiException, PaymentApiException {
+
+        final String paymentProviderName = null;
         if (accountKey != null) {
-            Account account = accountUserApi.getAccountByKey(accountKey);
+            final Account account = accountUserApi.getAccountByKey(accountKey);
             return getPaymentProviderPlugin(account);
         }
         return pluginRegistry.getPlugin(paymentProviderName);
     }
-    
-    protected PaymentPluginApi getPaymentProviderPlugin(Account account) throws PaymentApiException {
+
+    protected PaymentPluginApi getPaymentProviderPlugin(final Account account) throws PaymentApiException {
         String paymentProviderName = null;
         if (account != null) {
-            UUID paymentMethodId = account.getPaymentMethodId();
+            final UUID paymentMethodId = account.getPaymentMethodId();
             if (paymentMethodId == null) {
                 throw new PaymentApiException(ErrorCode.PAYMENT_NO_DEFAULT_PAYMENT_METHOD, account.getId());
             }
-            PaymentMethodModelDao methodDao = paymentDao.getPaymentMethod(paymentMethodId);
+            final PaymentMethodModelDao methodDao = paymentDao.getPaymentMethod(paymentMethodId);
             if (methodDao == null) {
                 log.error("Account {} has a non existent default payment method {}!!!", account.getId(), paymentMethodId);
-                throw new PaymentApiException(ErrorCode.PAYMENT_NO_DEFAULT_PAYMENT_METHOD, account.getId());                
+                throw new PaymentApiException(ErrorCode.PAYMENT_NO_DEFAULT_PAYMENT_METHOD, account.getId());
             }
             paymentProviderName = methodDao.getPluginName();
         }
         return pluginRegistry.getPlugin(paymentProviderName);
     }
 
-    protected void postPaymentEvent(BusEvent ev, UUID accountId) {
+    protected void postPaymentEvent(final BusEvent ev, final UUID accountId) {
         if (ev == null) {
             return;
         }
@@ -108,22 +107,20 @@ public abstract class ProcessorBase {
     }
 
 
-
     public interface WithAccountLockCallback<T> {
         public T doOperation() throws PaymentApiException;
     }
-    
-    
+
 
     public static class CallableWithAccountLock<T> implements Callable<T> {
-        
+
         private final GlobalLocker locker;
         private final String accountExternalKey;
         private final WithAccountLockCallback<T> callback;
-        
+
         public CallableWithAccountLock(final GlobalLocker locker,
-                final String accountExternalKey,
-                final WithAccountLockCallback<T> callback) {
+                                       final String accountExternalKey,
+                                       final WithAccountLockCallback<T> callback) {
             this.locker = locker;
             this.accountExternalKey = accountExternalKey;
             this.callback = callback;
@@ -134,23 +131,23 @@ public abstract class ProcessorBase {
             return new WithAccountLock<T>().processAccountWithLock(locker, accountExternalKey, callback);
         }
     }
-    
+
     public static class WithAccountLock<T> {
-        
+
         public T processAccountWithLock(final GlobalLocker locker, final String accountExternalKey, final WithAccountLockCallback<T> callback)
-         throws PaymentApiException {
+                throws PaymentApiException {
             GlobalLock lock = null;
             try {
                 lock = locker.lockWithNumberOfTries(LockerService.PAYMENT, accountExternalKey, NB_LOCK_TRY);
                 return callback.doOperation();
             } catch (LockFailedException e) {
-                String format = String.format("Failed to lock account %s", accountExternalKey);
+                final String format = String.format("Failed to lock account %s", accountExternalKey);
                 log.error(String.format(format), e);
                 throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, format);
             } finally {
                 if (lock != null) {
                     lock.release();
-                }        
+                }
             }
         }
     }
diff --git a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
index f478e07..4f21a9b 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
@@ -15,13 +15,10 @@
  */
 package com.ning.billing.payment.core;
 
-import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
-
+import javax.inject.Inject;
 import java.util.UUID;
 import java.util.concurrent.ExecutorService;
 
-import javax.inject.Inject;
-
 import com.google.inject.name.Named;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountUserApi;
@@ -33,20 +30,22 @@ import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.globallocker.GlobalLocker;
 
+import static com.ning.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
+
 public class RefundProcessor extends ProcessorBase {
 
     @Inject
     public RefundProcessor(final PaymentProviderPluginRegistry pluginRegistry,
-            final AccountUserApi accountUserApi,
-            final Bus eventBus,
-            final PaymentDao paymentDao,
-            final GlobalLocker locker,
-            @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
-        super(pluginRegistry, accountUserApi, eventBus, paymentDao, locker, executor);        
+                           final AccountUserApi accountUserApi,
+                           final Bus eventBus,
+                           final PaymentDao paymentDao,
+                           final GlobalLocker locker,
+                           @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
+        super(pluginRegistry, accountUserApi, eventBus, paymentDao, locker, executor);
     }
-    
-    public Refund createRefund(Account account, UUID paymentId, CallContext context)
-    throws PaymentApiException {
+
+    public Refund createRefund(final Account account, final UUID paymentId, final CallContext context)
+            throws PaymentApiException {
         /*
         try {
             
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
index e8a49d4..5dad606 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
@@ -19,19 +19,13 @@ import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 
-
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.Transaction;
 import org.skife.jdbi.v2.TransactionStatus;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
 import com.google.inject.Inject;
-import com.ning.billing.payment.api.PaymentApiException;
-import com.ning.billing.payment.api.PaymentInfoEvent;
 import com.ning.billing.payment.api.PaymentStatus;
 import com.ning.billing.payment.retry.PluginFailureRetryService.PluginFailureRetryServiceScheduler;
-
 import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.dao.EntityAudit;
@@ -42,45 +36,44 @@ public class AuditedPaymentDao implements PaymentDao {
 
     private final PaymentSqlDao paymentSqlDao;
     private final PaymentAttemptSqlDao paymentAttemptSqlDao;
-    private final PaymentMethodSqlDao paymentMethodSqlDao;    
+    private final PaymentMethodSqlDao paymentMethodSqlDao;
     //private final TimedoutPaymentRetryServiceScheduler timedoutSchduler;
-    
+
     @Inject
-    public AuditedPaymentDao(IDBI dbi, PluginFailureRetryServiceScheduler timedoutSchduler) {
-       this.paymentSqlDao = dbi.onDemand(PaymentSqlDao.class);
-       this.paymentAttemptSqlDao = dbi.onDemand(PaymentAttemptSqlDao.class);
-       this.paymentMethodSqlDao = dbi.onDemand(PaymentMethodSqlDao.class);
-      // this.timedoutSchduler = timedoutSchduler;
+    public AuditedPaymentDao(final IDBI dbi, final PluginFailureRetryServiceScheduler timedoutSchduler) {
+        this.paymentSqlDao = dbi.onDemand(PaymentSqlDao.class);
+        this.paymentAttemptSqlDao = dbi.onDemand(PaymentAttemptSqlDao.class);
+        this.paymentMethodSqlDao = dbi.onDemand(PaymentMethodSqlDao.class);
+        // this.timedoutSchduler = timedoutSchduler;
     }
-    
 
 
     @Override
     public PaymentAttemptModelDao insertNewAttemptForPayment(final UUID paymentId,
-            final PaymentAttemptModelDao attempt, final boolean scheduleTimeoutRetry, final CallContext context) {
+                                                             final PaymentAttemptModelDao attempt, final boolean scheduleTimeoutRetry, final CallContext context) {
 
         return paymentAttemptSqlDao.inTransaction(new Transaction<PaymentAttemptModelDao, PaymentAttemptSqlDao>() {
             @Override
-            public PaymentAttemptModelDao inTransaction(PaymentAttemptSqlDao transactional, TransactionStatus status)
-            throws Exception {
-                PaymentAttemptModelDao savedAttempt = insertPaymentAttemptFromTransaction(attempt, context, transactional);
-                PaymentSqlDao transPaymentSqlDao = transactional.become(PaymentSqlDao.class);
+            public PaymentAttemptModelDao inTransaction(final PaymentAttemptSqlDao transactional, final TransactionStatus status)
+                    throws Exception {
+                final PaymentAttemptModelDao savedAttempt = insertPaymentAttemptFromTransaction(attempt, context, transactional);
+                final PaymentSqlDao transPaymentSqlDao = transactional.become(PaymentSqlDao.class);
                 updatePaymentAmountFromTransaction(paymentId, savedAttempt.getRequestedAmount(), context, transPaymentSqlDao);
                 return savedAttempt;
             }
         });
     }
-    
-    
+
+
     @Override
     public PaymentModelDao insertPaymentWithAttempt(final PaymentModelDao payment, final PaymentAttemptModelDao attempt, final boolean scheduleTimeoutRetry, final CallContext context) {
-        
+
         return paymentSqlDao.inTransaction(new Transaction<PaymentModelDao, PaymentSqlDao>() {
 
             @Override
-            public PaymentModelDao inTransaction(PaymentSqlDao transactional,
-                    TransactionStatus status) throws Exception {
-                PaymentModelDao result =  insertPaymentFromTransaction(payment, context, transactional);
+            public PaymentModelDao inTransaction(final PaymentSqlDao transactional,
+                                                 final TransactionStatus status) throws Exception {
+                final PaymentModelDao result = insertPaymentFromTransaction(payment, context, transactional);
                 final PaymentAttemptSqlDao transactionalAttempt = transactional.become(PaymentAttemptSqlDao.class);
                 insertPaymentAttemptFromTransaction(attempt, context, transactionalAttempt);
                 return result;
@@ -108,54 +101,53 @@ public class AuditedPaymentDao implements PaymentDao {
         }
     }
 */
-    
-    
+
+
     private PaymentModelDao insertPaymentFromTransaction(final PaymentModelDao payment, final CallContext context, final PaymentSqlDao transactional) {
         transactional.insertPayment(payment, context);
-        PaymentModelDao savedPayment = transactional.getPayment(payment.getId().toString());
-        Long recordId = transactional.getRecordId(savedPayment.getId().toString());
-        EntityHistory<PaymentModelDao> history = new EntityHistory<PaymentModelDao>(savedPayment.getId(), recordId, savedPayment, ChangeType.INSERT);
+        final PaymentModelDao savedPayment = transactional.getPayment(payment.getId().toString());
+        final Long recordId = transactional.getRecordId(savedPayment.getId().toString());
+        final EntityHistory<PaymentModelDao> history = new EntityHistory<PaymentModelDao>(savedPayment.getId(), recordId, savedPayment, ChangeType.INSERT);
         transactional.insertHistoryFromTransaction(history, context);
-        
-        Long historyRecordId = transactional.getHistoryRecordId(recordId);
-        EntityAudit audit = new EntityAudit(TableName.PAYMENTS, historyRecordId, ChangeType.INSERT);
+
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final EntityAudit audit = new EntityAudit(TableName.PAYMENTS, historyRecordId, ChangeType.INSERT);
         transactional.insertAuditFromTransaction(audit, context);
         return savedPayment;
     }
-    
+
     private PaymentAttemptModelDao insertPaymentAttemptFromTransaction(final PaymentAttemptModelDao attempt, final CallContext context, final PaymentAttemptSqlDao transactional) {
         transactional.insertPaymentAttempt(attempt, context);
-        PaymentAttemptModelDao savedAttempt = transactional.getPaymentAttempt(attempt.getId().toString());
-        Long recordId = transactional.getRecordId(savedAttempt.getId().toString());
-        EntityHistory<PaymentAttemptModelDao> history = new EntityHistory<PaymentAttemptModelDao>(savedAttempt.getId(), recordId, savedAttempt, ChangeType.INSERT);
+        final PaymentAttemptModelDao savedAttempt = transactional.getPaymentAttempt(attempt.getId().toString());
+        final Long recordId = transactional.getRecordId(savedAttempt.getId().toString());
+        final EntityHistory<PaymentAttemptModelDao> history = new EntityHistory<PaymentAttemptModelDao>(savedAttempt.getId(), recordId, savedAttempt, ChangeType.INSERT);
         transactional.insertHistoryFromTransaction(history, context);
-        Long historyRecordId = transactional.getHistoryRecordId(recordId);
-        EntityAudit audit = new EntityAudit(TableName.PAYMENT_ATTEMPTS, historyRecordId, ChangeType.INSERT);
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final EntityAudit audit = new EntityAudit(TableName.PAYMENT_ATTEMPTS, historyRecordId, ChangeType.INSERT);
         transactional.insertAuditFromTransaction(audit, context);
         return savedAttempt;
     }
-    
+
     @Override
     public PaymentAttemptModelDao getPaymentAttempt(final UUID attemptId) {
         return paymentAttemptSqlDao.inTransaction(new Transaction<PaymentAttemptModelDao, PaymentAttemptSqlDao>() {
             @Override
-            public PaymentAttemptModelDao inTransaction(PaymentAttemptSqlDao transactional, TransactionStatus status)
+            public PaymentAttemptModelDao inTransaction(final PaymentAttemptSqlDao transactional, final TransactionStatus status)
                     throws Exception {
                 return transactional.getPaymentAttempt(attemptId.toString());
             }
         });
     }
-    
-    
+
 
     @Override
     public void updateStatusForPayment(final UUID paymentId,
-            final PaymentStatus paymentStatus, final CallContext context) {
+                                       final PaymentStatus paymentStatus, final CallContext context) {
         paymentSqlDao.inTransaction(new Transaction<Void, PaymentSqlDao>() {
 
             @Override
-            public Void inTransaction(PaymentSqlDao transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final PaymentSqlDao transactional,
+                                      final TransactionStatus status) throws Exception {
                 updatePaymentStatusFromTransaction(paymentId, paymentStatus, context, transactional);
                 return null;
             }
@@ -164,15 +156,15 @@ public class AuditedPaymentDao implements PaymentDao {
 
     @Override
     public void updateStatusForPaymentWithAttempt(final UUID paymentId,
-            final PaymentStatus paymentStatus, final String paymentError, final UUID attemptId,
-            final CallContext context) {
+                                                  final PaymentStatus paymentStatus, final String paymentError, final UUID attemptId,
+                                                  final CallContext context) {
         paymentSqlDao.inTransaction(new Transaction<Void, PaymentSqlDao>() {
 
             @Override
-            public Void inTransaction(PaymentSqlDao transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final PaymentSqlDao transactional,
+                                      final TransactionStatus status) throws Exception {
                 updatePaymentStatusFromTransaction(paymentId, paymentStatus, context, transactional);
-                PaymentAttemptSqlDao transPaymentAttemptSqlDao = transactional.become(PaymentAttemptSqlDao.class);
+                final PaymentAttemptSqlDao transPaymentAttemptSqlDao = transactional.become(PaymentAttemptSqlDao.class);
                 updatePaymentAttemptStatusFromTransaction(attemptId, paymentStatus, paymentError, context, transPaymentAttemptSqlDao);
                 return null;
             }
@@ -181,104 +173,103 @@ public class AuditedPaymentDao implements PaymentDao {
 
     private void updatePaymentAmountFromTransaction(final UUID paymentId, final BigDecimal amount, final CallContext context, final PaymentSqlDao transactional) {
         transactional.updatePaymentAmount(paymentId.toString(), amount, context);
-        PaymentModelDao savedPayment = transactional.getPayment(paymentId.toString());
-        Long recordId = transactional.getRecordId(savedPayment.getId().toString());
-        EntityHistory<PaymentModelDao> history = new EntityHistory<PaymentModelDao>(savedPayment.getId(), recordId, savedPayment, ChangeType.UPDATE);
+        final PaymentModelDao savedPayment = transactional.getPayment(paymentId.toString());
+        final Long recordId = transactional.getRecordId(savedPayment.getId().toString());
+        final EntityHistory<PaymentModelDao> history = new EntityHistory<PaymentModelDao>(savedPayment.getId(), recordId, savedPayment, ChangeType.UPDATE);
         transactional.insertHistoryFromTransaction(history, context);
-        Long historyRecordId = transactional.getHistoryRecordId(recordId);
-        EntityAudit audit = new EntityAudit(TableName.PAYMENTS, historyRecordId, ChangeType.UPDATE);
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final EntityAudit audit = new EntityAudit(TableName.PAYMENTS, historyRecordId, ChangeType.UPDATE);
         transactional.insertAuditFromTransaction(audit, context);
     }
 
     private void updatePaymentStatusFromTransaction(final UUID paymentId, final PaymentStatus paymentStatus, final CallContext context, final PaymentSqlDao transactional) {
         transactional.updatePaymentStatus(paymentId.toString(), paymentStatus.toString(), context);
-        PaymentModelDao savedPayment = transactional.getPayment(paymentId.toString());
-        Long recordId = transactional.getRecordId(savedPayment.getId().toString());
-        EntityHistory<PaymentModelDao> history = new EntityHistory<PaymentModelDao>(savedPayment.getId(), recordId, savedPayment, ChangeType.UPDATE);
+        final PaymentModelDao savedPayment = transactional.getPayment(paymentId.toString());
+        final Long recordId = transactional.getRecordId(savedPayment.getId().toString());
+        final EntityHistory<PaymentModelDao> history = new EntityHistory<PaymentModelDao>(savedPayment.getId(), recordId, savedPayment, ChangeType.UPDATE);
         transactional.insertHistoryFromTransaction(history, context);
-        Long historyRecordId = transactional.getHistoryRecordId(recordId);
-        EntityAudit audit = new EntityAudit(TableName.PAYMENTS, historyRecordId, ChangeType.UPDATE);
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final EntityAudit audit = new EntityAudit(TableName.PAYMENTS, historyRecordId, ChangeType.UPDATE);
         transactional.insertAuditFromTransaction(audit, context);
     }
-    
+
     private void updatePaymentAttemptStatusFromTransaction(final UUID attemptId, final PaymentStatus processingStatus, final String paymentError, final CallContext context, final PaymentAttemptSqlDao transactional) {
         transactional.updatePaymentAttemptStatus(attemptId.toString(), processingStatus.toString(), paymentError);
-        PaymentAttemptModelDao savedAttempt = transactional.getPaymentAttempt(attemptId.toString());
-        Long recordId = transactional.getRecordId(savedAttempt.getId().toString());
-        EntityHistory<PaymentAttemptModelDao> history = new EntityHistory<PaymentAttemptModelDao>(savedAttempt.getId(), recordId, savedAttempt, ChangeType.UPDATE);
+        final PaymentAttemptModelDao savedAttempt = transactional.getPaymentAttempt(attemptId.toString());
+        final Long recordId = transactional.getRecordId(savedAttempt.getId().toString());
+        final EntityHistory<PaymentAttemptModelDao> history = new EntityHistory<PaymentAttemptModelDao>(savedAttempt.getId(), recordId, savedAttempt, ChangeType.UPDATE);
         transactional.insertHistoryFromTransaction(history, context);
-        Long historyRecordId = transactional.getHistoryRecordId(recordId);
-        EntityAudit audit = new EntityAudit(TableName.PAYMENT_ATTEMPTS, historyRecordId, ChangeType.UPDATE);
+        final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+        final EntityAudit audit = new EntityAudit(TableName.PAYMENT_ATTEMPTS, historyRecordId, ChangeType.UPDATE);
         transactional.insertAuditFromTransaction(audit, context);
     }
-    
+
     @Override
     public PaymentMethodModelDao insertPaymentMethod(final PaymentMethodModelDao paymentMethod, final CallContext context) {
         return paymentMethodSqlDao.inTransaction(new Transaction<PaymentMethodModelDao, PaymentMethodSqlDao>() {
 
             @Override
-            public PaymentMethodModelDao inTransaction(PaymentMethodSqlDao transactional, TransactionStatus status)
+            public PaymentMethodModelDao inTransaction(final PaymentMethodSqlDao transactional, final TransactionStatus status)
                     throws Exception {
                 transactional.insertPaymentMethod(paymentMethod, context);
-                PaymentMethodModelDao savedPaymentMethod = transactional.getPaymentMethod(paymentMethod.getId().toString());
-                Long recordId = transactional.getRecordId(savedPaymentMethod.getId().toString());
-                EntityHistory<PaymentMethodModelDao> history = new EntityHistory<PaymentMethodModelDao>(savedPaymentMethod.getId(), recordId, savedPaymentMethod, ChangeType.INSERT);
+                final PaymentMethodModelDao savedPaymentMethod = transactional.getPaymentMethod(paymentMethod.getId().toString());
+                final Long recordId = transactional.getRecordId(savedPaymentMethod.getId().toString());
+                final EntityHistory<PaymentMethodModelDao> history = new EntityHistory<PaymentMethodModelDao>(savedPaymentMethod.getId(), recordId, savedPaymentMethod, ChangeType.INSERT);
                 transactional.insertHistoryFromTransaction(history, context);
-                Long historyRecordId = transactional.getHistoryRecordId(recordId);
-                EntityAudit audit = new EntityAudit(TableName.PAYMENT_METHODS, historyRecordId, ChangeType.INSERT);
+                final Long historyRecordId = transactional.getHistoryRecordId(recordId);
+                final EntityAudit audit = new EntityAudit(TableName.PAYMENT_METHODS, historyRecordId, ChangeType.INSERT);
                 transactional.insertAuditFromTransaction(audit, context);
                 return savedPaymentMethod;
             }
         });
     }
-    
+
     @Override
     public PaymentMethodModelDao getPaymentMethod(final UUID paymentMethodId) {
         return paymentMethodSqlDao.inTransaction(new Transaction<PaymentMethodModelDao, PaymentMethodSqlDao>() {
             @Override
-            public PaymentMethodModelDao inTransaction(PaymentMethodSqlDao transactional, TransactionStatus status)
+            public PaymentMethodModelDao inTransaction(final PaymentMethodSqlDao transactional, final TransactionStatus status)
                     throws Exception {
                 return transactional.getPaymentMethod(paymentMethodId.toString());
             }
         });
     }
-    
-    @Override    
+
+    @Override
     public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId) {
         return paymentMethodSqlDao.inTransaction(new Transaction<List<PaymentMethodModelDao>, PaymentMethodSqlDao>() {
             @Override
-            public List<PaymentMethodModelDao> inTransaction(PaymentMethodSqlDao transactional, TransactionStatus status)
+            public List<PaymentMethodModelDao> inTransaction(final PaymentMethodSqlDao transactional, final TransactionStatus status)
                     throws Exception {
                 return transactional.getPaymentMethods(accountId.toString());
             }
         });
-                 
+
     }
 
     @Override
-    public void deletedPaymentMethod(UUID paymentMethodId) {
+    public void deletedPaymentMethod(final UUID paymentMethodId) {
         paymentMethodSqlDao.markPaymentMethodAsDeleted(paymentMethodId.toString());
     }
 
 
-
     @Override
-    public List<PaymentModelDao> getPaymentsForInvoice(UUID invoiceId) {
+    public List<PaymentModelDao> getPaymentsForInvoice(final UUID invoiceId) {
         return paymentSqlDao.getPaymentsForInvoice(invoiceId.toString());
     }
 
     @Override
-    public PaymentModelDao getPayment(UUID paymentId) {
+    public PaymentModelDao getPayment(final UUID paymentId) {
         return paymentSqlDao.getPayment(paymentId.toString());
     }
 
     @Override
-    public List<PaymentModelDao> getPaymentsForAccount(UUID accountId) {
+    public List<PaymentModelDao> getPaymentsForAccount(final UUID accountId) {
         return paymentSqlDao.getPaymentsForAccount(accountId.toString());
     }
 
     @Override
-    public List<PaymentAttemptModelDao> getAttemptsForPayment(UUID paymentId) {
+    public List<PaymentAttemptModelDao> getAttemptsForPayment(final UUID paymentId) {
         return paymentAttemptSqlDao.getPaymentAttempts(paymentId.toString());
     }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptHistoryBinder.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptHistoryBinder.java
index b08658d..7f66ace 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptHistoryBinder.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptHistoryBinder.java
@@ -34,21 +34,21 @@ import com.ning.billing.util.dao.EntityHistory;
 @Target({ElementType.PARAMETER})
 public @interface PaymentAttemptHistoryBinder {
 
-    
+
     public static class PaymentAttemptHistoryBinderFactory extends BinderBase implements BinderFactory {
         @Override
-        public Binder<PaymentAttemptHistoryBinder, EntityHistory<PaymentAttemptModelDao>> build(Annotation annotation) {
+        public Binder<PaymentAttemptHistoryBinder, EntityHistory<PaymentAttemptModelDao>> build(final Annotation annotation) {
             return new Binder<PaymentAttemptHistoryBinder, EntityHistory<PaymentAttemptModelDao>>() {
                 @Override
-                public void bind(@SuppressWarnings("rawtypes") SQLStatement q, PaymentAttemptHistoryBinder bind, EntityHistory<PaymentAttemptModelDao> history) {
+                public void bind(final SQLStatement<?> q, final PaymentAttemptHistoryBinder bind, final EntityHistory<PaymentAttemptModelDao> history) {
                     q.bind("recordId", history.getValue());
                     q.bind("changeType", history.getChangeType().toString());
-                    PaymentAttemptModelDao attempt = history.getEntity();
+                    final PaymentAttemptModelDao attempt = history.getEntity();
                     q.bind("id", attempt.getId().toString());
-                    q.bind("paymentId", attempt.getPaymentId().toString());            
+                    q.bind("paymentId", attempt.getPaymentId().toString());
                     q.bind("processingStatus", attempt.getPaymentStatus().toString());
-                    q.bind("paymentError", attempt.getPaymentError());   
-                    q.bind("requestedAmount", attempt.getRequestedAmount());                           
+                    q.bind("paymentError", attempt.getPaymentError());
+                    q.bind("requestedAmount", attempt.getRequestedAmount());
                 }
             };
         }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
index b8f66b7..9c65c80 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
@@ -31,11 +31,11 @@ public class PaymentAttemptModelDao extends EntityBase {
     private final PaymentStatus processingStatus;
     private final DateTime effectiveDate;
     private final String paymentError;
-    private final BigDecimal requestedAmount; 
-    
-    public PaymentAttemptModelDao(UUID id, UUID accountId, UUID invoiceId,
-            UUID paymentId, PaymentStatus processingStatus, DateTime effectiveDate,
-            BigDecimal requestedAmount, String paymentError) {
+    private final BigDecimal requestedAmount;
+
+    public PaymentAttemptModelDao(final UUID id, final UUID accountId, final UUID invoiceId,
+                                  final UUID paymentId, final PaymentStatus processingStatus, final DateTime effectiveDate,
+                                  final BigDecimal requestedAmount, final String paymentError) {
         super(id);
         this.accountId = accountId;
         this.invoiceId = invoiceId;
@@ -45,16 +45,16 @@ public class PaymentAttemptModelDao extends EntityBase {
         this.requestedAmount = requestedAmount;
         this.paymentError = paymentError;
     }
-    
-    public PaymentAttemptModelDao(UUID accountId, UUID invoiceId, UUID paymentId, DateTime effectiveDate, BigDecimal requestedAmount) {
-        this(UUID.randomUUID(), accountId, invoiceId, paymentId, PaymentStatus.UNKNOWN, effectiveDate, requestedAmount,  null);
+
+    public PaymentAttemptModelDao(final UUID accountId, final UUID invoiceId, final UUID paymentId, final DateTime effectiveDate, final BigDecimal requestedAmount) {
+        this(UUID.randomUUID(), accountId, invoiceId, paymentId, PaymentStatus.UNKNOWN, effectiveDate, requestedAmount, null);
     }
 
-    public PaymentAttemptModelDao(PaymentAttemptModelDao src, PaymentStatus newProcessingStatus, String paymentError) {
+    public PaymentAttemptModelDao(final PaymentAttemptModelDao src, final PaymentStatus newProcessingStatus, final String paymentError) {
         this(src.getId(), src.getAccountId(), src.getInvoiceId(), src.getPaymentId(), newProcessingStatus,
-                src.getEffectiveDate(), src.getRequestedAmount(), paymentError);
+             src.getEffectiveDate(), src.getRequestedAmount(), paymentError);
     }
-    
+
     public UUID getAccountId() {
         return accountId;
     }
@@ -70,15 +70,15 @@ public class PaymentAttemptModelDao extends EntityBase {
     public PaymentStatus getPaymentStatus() {
         return processingStatus;
     }
-    
+
     public DateTime getEffectiveDate() {
         return effectiveDate;
     }
-    
+
     public String getPaymentError() {
         return paymentError;
     }
-    
+
     public BigDecimal getRequestedAmount() {
         return requestedAmount;
     }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptSqlDao.java
index b1b53d6..66276c4 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptSqlDao.java
@@ -22,7 +22,6 @@ import java.sql.SQLException;
 import java.util.List;
 import java.util.UUID;
 
-
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
@@ -47,55 +46,54 @@ import com.ning.billing.util.entity.dao.UpdatableEntitySqlDao;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(PaymentAttemptSqlDao.PaymentAttemptModelDaoMapper.class)
-public interface PaymentAttemptSqlDao extends Transactional<PaymentAttemptSqlDao>, UpdatableEntitySqlDao<PaymentAttemptModelDao>, Transmogrifier,  CloseMe {
-
+public interface PaymentAttemptSqlDao extends Transactional<PaymentAttemptSqlDao>, UpdatableEntitySqlDao<PaymentAttemptModelDao>, Transmogrifier, CloseMe {
 
-    
 
     @SqlUpdate
     void insertPaymentAttempt(@Bind(binder = PaymentAttemptModelDaoBinder.class) final PaymentAttemptModelDao attempt,
-                           @CallContextBinder final CallContext context);
-    
+                              @CallContextBinder final CallContext context);
+
     @SqlUpdate
     void updatePaymentAttemptStatus(@Bind("id") final String attemptId,
-            @Bind("processingStatus") final String processingStatus,
-            @Bind("paymentError") final String paymentError);
-    
+                                    @Bind("processingStatus") final String processingStatus,
+                                    @Bind("paymentError") final String paymentError);
+
     @SqlQuery
     PaymentAttemptModelDao getPaymentAttempt(@Bind("id") final String attemptId);
 
     @SqlQuery
     List<PaymentAttemptModelDao> getPaymentAttempts(@Bind("paymentId") final String paymentId);
 
-   
+
     @Override
     @SqlUpdate
     void insertHistoryFromTransaction(@PaymentAttemptHistoryBinder final EntityHistory<PaymentAttemptModelDao> payment,
-                                            @CallContextBinder final CallContext context);
+                                      @CallContextBinder final CallContext context);
 
     public static final class PaymentAttemptModelDaoBinder extends BinderBase implements Binder<Bind, PaymentAttemptModelDao> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, PaymentAttemptModelDao attempt) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final PaymentAttemptModelDao attempt) {
             stmt.bind("id", attempt.getId().toString());
-            stmt.bind("paymentId", attempt.getPaymentId().toString());            
+            stmt.bind("paymentId", attempt.getPaymentId().toString());
             stmt.bind("processingStatus", attempt.getPaymentStatus().toString());
-            stmt.bind("paymentError", attempt.getPaymentError());            
-            stmt.bind("requestedAmount", attempt.getRequestedAmount());            
+            stmt.bind("paymentError", attempt.getPaymentError());
+            stmt.bind("requestedAmount", attempt.getRequestedAmount());
         }
     }
+
     public static class PaymentAttemptModelDaoMapper extends MapperBase implements ResultSetMapper<PaymentAttemptModelDao> {
 
         @Override
-        public PaymentAttemptModelDao map(int index, ResultSet rs, StatementContext ctx)
+        public PaymentAttemptModelDao map(final int index, final ResultSet rs, final StatementContext ctx)
                 throws SQLException {
-            UUID id = getUUID(rs, "id");
-            UUID accountId = getUUID(rs, "account_id");
-            UUID invoiceId = getUUID(rs, "invoice_id");            
-            UUID paymentId = getUUID(rs, "payment_id");  
-            DateTime effectiveDate = getDate(rs, "effective_date");            
-            PaymentStatus processingStatus = PaymentStatus.valueOf(rs.getString("processing_status"));
-            String paymentError = rs.getString("payment_error");
-            BigDecimal requestedAmount = rs.getBigDecimal("requested_amount");
+            final UUID id = getUUID(rs, "id");
+            final UUID accountId = getUUID(rs, "account_id");
+            final UUID invoiceId = getUUID(rs, "invoice_id");
+            final UUID paymentId = getUUID(rs, "payment_id");
+            final DateTime effectiveDate = getDate(rs, "effective_date");
+            final PaymentStatus processingStatus = PaymentStatus.valueOf(rs.getString("processing_status"));
+            final String paymentError = rs.getString("payment_error");
+            final BigDecimal requestedAmount = rs.getBigDecimal("requested_amount");
             return new PaymentAttemptModelDao(id, accountId, invoiceId, paymentId, processingStatus, effectiveDate, requestedAmount, paymentError);
         }
     }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
index e01a905..6580217 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
@@ -18,8 +18,6 @@ package com.ning.billing.payment.dao;
 import java.util.List;
 import java.util.UUID;
 
-import org.skife.jdbi.v2.sqlobject.Bind;
-
 import com.ning.billing.payment.api.PaymentStatus;
 import com.ning.billing.util.callcontext.CallContext;
 
@@ -31,25 +29,25 @@ public interface PaymentDao {
     public PaymentAttemptModelDao insertNewAttemptForPayment(final UUID paymentId, final PaymentAttemptModelDao attempt, final boolean scheduleTimeoutRetry, final CallContext context);
 
 
-    public void updateStatusForPayment(final UUID paymentId, final PaymentStatus paymentStatus, final CallContext context);    
+    public void updateStatusForPayment(final UUID paymentId, final PaymentStatus paymentStatus, final CallContext context);
 
     public void updateStatusForPaymentWithAttempt(final UUID paymentId, final PaymentStatus paymentStatus, final String paymentError, final UUID attemptId, final CallContext context);
-    
+
     public PaymentAttemptModelDao getPaymentAttempt(final UUID attemptId);
-    
+
     public List<PaymentModelDao> getPaymentsForInvoice(final UUID invoiceId);
-    
-    public List<PaymentModelDao> getPaymentsForAccount(final UUID accountId);    
-    
-    public PaymentModelDao getPayment(final UUID paymentId);    
+
+    public List<PaymentModelDao> getPaymentsForAccount(final UUID accountId);
+
+    public PaymentModelDao getPayment(final UUID paymentId);
 
     public List<PaymentAttemptModelDao> getAttemptsForPayment(final UUID paymentId);
-    
+
     public PaymentMethodModelDao insertPaymentMethod(final PaymentMethodModelDao paymentMethod, final CallContext context);
-    
+
     public PaymentMethodModelDao getPaymentMethod(final UUID paymentMethodId);
-    
-    public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId);   
+
+    public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId);
 
     public void deletedPaymentMethod(final UUID paymentMethodId);
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentHistoryBinder.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentHistoryBinder.java
index b5d5d02..a68de8c 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentHistoryBinder.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentHistoryBinder.java
@@ -35,16 +35,16 @@ import com.ning.billing.util.dao.EntityHistory;
 public @interface PaymentHistoryBinder {
     public static class PaymentHistoryBinderFactory extends BinderBase implements BinderFactory {
         @Override
-        public Binder<PaymentHistoryBinder, EntityHistory<PaymentModelDao>> build(Annotation annotation) {
+        public Binder<PaymentHistoryBinder, EntityHistory<PaymentModelDao>> build(final Annotation annotation) {
             return new Binder<PaymentHistoryBinder, EntityHistory<PaymentModelDao>>() {
                 @Override
-                public void bind(@SuppressWarnings("rawtypes") SQLStatement q, PaymentHistoryBinder bind, EntityHistory<PaymentModelDao> history) {
+                public void bind(final SQLStatement<?> q, final PaymentHistoryBinder bind, final EntityHistory<PaymentModelDao> history) {
                     q.bind("recordId", history.getValue());
                     q.bind("changeType", history.getChangeType().toString());
-                    PaymentModelDao payment = history.getEntity();
+                    final PaymentModelDao payment = history.getEntity();
                     q.bind("id", payment.getId().toString());
-                    q.bind("accountId", payment.getAccountId().toString());            
-                    q.bind("invoiceId", payment.getInvoiceId().toString());            
+                    q.bind("accountId", payment.getAccountId().toString());
+                    q.bind("invoiceId", payment.getInvoiceId().toString());
                     q.bind("paymentMethodId", ""); //payment.getPaymentMethodId().toString());
                     q.bind("amount", payment.getAmount());
                     q.bind("currency", payment.getCurrency().toString());
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodHistoryBinder.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodHistoryBinder.java
index 988964e..b74d528 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodHistoryBinder.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodHistoryBinder.java
@@ -35,17 +35,17 @@ import com.ning.billing.util.dao.EntityHistory;
 public @interface PaymentMethodHistoryBinder {
     public static class PaymentMethodHistoryBinderFactory extends BinderBase implements BinderFactory {
         @Override
-        public Binder<PaymentMethodHistoryBinder, EntityHistory<PaymentMethodModelDao>> build(Annotation annotation) {
+        public Binder<PaymentMethodHistoryBinder, EntityHistory<PaymentMethodModelDao>> build(final Annotation annotation) {
             return new Binder<PaymentMethodHistoryBinder, EntityHistory<PaymentMethodModelDao>>() {
                 @Override
-                public void bind(@SuppressWarnings("rawtypes") SQLStatement q, PaymentMethodHistoryBinder bind, EntityHistory<PaymentMethodModelDao> history) {
+                public void bind(final SQLStatement<?> q, final PaymentMethodHistoryBinder bind, final EntityHistory<PaymentMethodModelDao> history) {
                     q.bind("recordId", history.getValue());
                     q.bind("changeType", history.getChangeType().toString());
-                    PaymentMethodModelDao paymentMethod = history.getEntity();
+                    final PaymentMethodModelDao paymentMethod = history.getEntity();
                     q.bind("id", paymentMethod.getId().toString());
-                    q.bind("isActive", paymentMethod.isActive());                    
-                    q.bind("accountId", paymentMethod.getAccountId().toString());            
-                    q.bind("pluginName", paymentMethod.getPluginName()); 
+                    q.bind("isActive", paymentMethod.isActive());
+                    q.bind("accountId", paymentMethod.getAccountId().toString());
+                    q.bind("pluginName", paymentMethod.getPluginName());
                     q.bind("externalId", paymentMethod.getExternalId());
                 }
             };
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodModelDao.java
index b3dadd5..cbf98ea 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodModelDao.java
@@ -20,14 +20,14 @@ import java.util.UUID;
 import com.ning.billing.util.entity.EntityBase;
 
 public class PaymentMethodModelDao extends EntityBase {
-    
+
     private final UUID accountId;
     private final String pluginName;
     private final Boolean isActive;
     private final String externalId;
-    
+
     public PaymentMethodModelDao(final UUID id, final UUID accountId, final String pluginName,
-            final Boolean isActive, final String externalId) {
+                                 final Boolean isActive, final String externalId) {
         super(id);
         this.accountId = accountId;
         this.pluginName = pluginName;
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodSqlDao.java
index 4912901..dc85154 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentMethodSqlDao.java
@@ -42,16 +42,16 @@ import com.ning.billing.util.entity.dao.UpdatableEntitySqlDao;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(PaymentMethodSqlDao.PaymentMethodDaoMapper.class)
-public interface PaymentMethodSqlDao extends Transactional<PaymentMethodSqlDao>, UpdatableEntitySqlDao<PaymentMethodModelDao>, Transmogrifier,  CloseMe {
+public interface PaymentMethodSqlDao extends Transactional<PaymentMethodSqlDao>, UpdatableEntitySqlDao<PaymentMethodModelDao>, Transmogrifier, CloseMe {
+
 
-    
     @SqlUpdate
     void insertPaymentMethod(@Bind(binder = PaymentMethodModelDaoBinder.class) final PaymentMethodModelDao paymentMethod,
-                           @CallContextBinder final CallContext context);
-    
+                             @CallContextBinder final CallContext context);
+
     @SqlUpdate
     void markPaymentMethodAsDeleted(@Bind("id") final String paymentMethodId);
-    
+
     @SqlQuery
     PaymentMethodModelDao getPaymentMethod(@Bind("id") final String paymentMethodId);
 
@@ -62,30 +62,30 @@ public interface PaymentMethodSqlDao extends Transactional<PaymentMethodSqlDao>,
     @Override
     @SqlUpdate
     public void insertHistoryFromTransaction(@PaymentMethodHistoryBinder final EntityHistory<PaymentMethodModelDao> payment,
-                                            @CallContextBinder final CallContext context);
+                                             @CallContextBinder final CallContext context);
+
 
-    
     public static final class PaymentMethodModelDaoBinder extends BinderBase implements Binder<Bind, PaymentMethodModelDao> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, PaymentMethodModelDao method) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final PaymentMethodModelDao method) {
             stmt.bind("id", method.getId().toString());
-            stmt.bind("accountId", method.getAccountId().toString());            
-            stmt.bind("pluginName", method.getPluginName());            
-            stmt.bind("isActive", method.isActive());            
-            stmt.bind("externalId", method.getExternalId());              
+            stmt.bind("accountId", method.getAccountId().toString());
+            stmt.bind("pluginName", method.getPluginName());
+            stmt.bind("isActive", method.isActive());
+            stmt.bind("externalId", method.getExternalId());
         }
     }
-    
+
     public static class PaymentMethodDaoMapper extends MapperBase implements ResultSetMapper<PaymentMethodModelDao> {
 
         @Override
-        public PaymentMethodModelDao map(int index, ResultSet rs, StatementContext ctx)
+        public PaymentMethodModelDao map(final int index, final ResultSet rs, final StatementContext ctx)
                 throws SQLException {
-            UUID id = getUUID(rs, "id");
-            UUID accountId = getUUID(rs, "account_id");
-            String pluginName = rs.getString("plugin_name");
-            Boolean isActive = rs.getBoolean("is_active");
-            String externalId = rs.getString("external_id");
+            final UUID id = getUUID(rs, "id");
+            final UUID accountId = getUUID(rs, "account_id");
+            final String pluginName = rs.getString("plugin_name");
+            final Boolean isActive = rs.getBoolean("is_active");
+            final String externalId = rs.getString("external_id");
             return new PaymentMethodModelDao(id, accountId, pluginName, isActive, externalId);
         }
     }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java
index 1511ca8..6ee7ea1 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentModelDao.java
@@ -22,13 +22,12 @@ import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.payment.api.PaymentStatus;
-import com.ning.billing.util.entity.Entity;
 import com.ning.billing.util.entity.EntityBase;
 
 public class PaymentModelDao extends EntityBase {
 
-    public final static Integer INVALID_PAYMENT_NUMBER = new Integer(-13);
-    
+    public static final Integer INVALID_PAYMENT_NUMBER = new Integer(-13);
+
     private final UUID accountId;
     private final UUID invoiceId;
     private final UUID paymentMethodId;
@@ -36,16 +35,16 @@ public class PaymentModelDao extends EntityBase {
     private final Currency currency;
     private final DateTime effectiveDate;
     private final Integer paymentNumber;
-    private final PaymentStatus paymentStatus;    
+    private final PaymentStatus paymentStatus;
+
 
-    
-    public PaymentModelDao(UUID id, UUID accountId, UUID invoiceId, UUID paymentMethodId,
-            Integer paymentNumber, BigDecimal amount, Currency currency,
-            PaymentStatus paymentStatus, DateTime effectiveDate) {
+    public PaymentModelDao(final UUID id, final UUID accountId, final UUID invoiceId, final UUID paymentMethodId,
+                           final Integer paymentNumber, final BigDecimal amount, final Currency currency,
+                           final PaymentStatus paymentStatus, final DateTime effectiveDate) {
         super(id);
         this.accountId = accountId;
         this.invoiceId = invoiceId;
-        this.paymentMethodId = paymentMethodId; 
+        this.paymentMethodId = paymentMethodId;
         this.paymentNumber = paymentNumber;
         this.amount = amount;
         this.currency = currency;
@@ -53,15 +52,16 @@ public class PaymentModelDao extends EntityBase {
         this.effectiveDate = effectiveDate;
     }
 
-    public PaymentModelDao(UUID accountId, UUID invoiceId,
-            BigDecimal amount, Currency currency, DateTime effectiveDate) {
+    public PaymentModelDao(final UUID accountId, final UUID invoiceId,
+                           final BigDecimal amount, final Currency currency, final DateTime effectiveDate) {
         this(UUID.randomUUID(), accountId, invoiceId, null, INVALID_PAYMENT_NUMBER, amount, currency, PaymentStatus.UNKNOWN, effectiveDate);
     }
 
-    public PaymentModelDao(PaymentModelDao src, PaymentStatus newPaymentStatus) {
+    public PaymentModelDao(final PaymentModelDao src, final PaymentStatus newPaymentStatus) {
         this(src.getId(), src.getAccountId(), src.getInvoiceId(), null, src.getPaymentNumber(), src.getAmount(), src.getCurrency(), newPaymentStatus, src.getEffectiveDate())
-;    }
-    
+        ;
+    }
+
     public UUID getAccountId() {
         return accountId;
     }
@@ -73,7 +73,7 @@ public class PaymentModelDao extends EntityBase {
     public UUID getPaymentMethodId() {
         return paymentMethodId;
     }
-    
+
     public Integer getPaymentNumber() {
         return paymentNumber;
     }
@@ -81,7 +81,7 @@ public class PaymentModelDao extends EntityBase {
     public BigDecimal getAmount() {
         return amount;
     }
-    
+
     public PaymentStatus getPaymentStatus() {
         return paymentStatus;
     }
@@ -92,5 +92,5 @@ public class PaymentModelDao extends EntityBase {
 
     public DateTime getEffectiveDate() {
         return effectiveDate;
-    }    
+    }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
index b0db533..4173ac2 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
@@ -46,66 +46,65 @@ import com.ning.billing.util.entity.dao.UpdatableEntitySqlDao;
 
 @ExternalizedSqlViaStringTemplate3()
 @RegisterMapper(PaymentSqlDao.PaymentModelDaoMapper.class)
-public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, UpdatableEntitySqlDao<PaymentModelDao>, Transmogrifier,  CloseMe {
+public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, UpdatableEntitySqlDao<PaymentModelDao>, Transmogrifier, CloseMe {
 
     @SqlUpdate
     void insertPayment(@Bind(binder = PaymentModelDaoBinder.class) final PaymentModelDao paymentInfo,
-                           @CallContextBinder final CallContext context);
-    
+                       @CallContextBinder final CallContext context);
+
     @SqlUpdate
     void updatePaymentStatus(@Bind("id") final String paymentId, @Bind("paymentStatus") final String paymentStatus,
-            @CallContextBinder final CallContext context);
+                             @CallContextBinder final CallContext context);
 
     @SqlUpdate
     void updatePaymentAmount(@Bind("id") final String paymentId, @Bind("amount") final BigDecimal amount,
-            @CallContextBinder final CallContext context);
+                             @CallContextBinder final CallContext context);
 
     @SqlQuery
     PaymentModelDao getPayment(@Bind("id") final String paymentId);
- 
+
     @SqlQuery
     List<PaymentModelDao> getPaymentsForInvoice(@Bind("invoiceId") final String invoiceId);
 
     @SqlQuery
     List<PaymentModelDao> getPaymentsForAccount(@Bind("accountId") final String accountId);
 
-    
+
     @Override
     @SqlUpdate
     void insertHistoryFromTransaction(@PaymentHistoryBinder final EntityHistory<PaymentModelDao> payment,
-                                            @CallContextBinder final CallContext context);
+                                      @CallContextBinder final CallContext context);
 
 
-
-     public static final class PaymentModelDaoBinder extends BinderBase implements Binder<Bind, PaymentModelDao> {
+    public static final class PaymentModelDaoBinder extends BinderBase implements Binder<Bind, PaymentModelDao> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, PaymentModelDao payment) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final PaymentModelDao payment) {
             stmt.bind("id", payment.getId().toString());
-            stmt.bind("accountId", payment.getAccountId().toString());            
-            stmt.bind("invoiceId", payment.getInvoiceId().toString());            
+            stmt.bind("accountId", payment.getAccountId().toString());
+            stmt.bind("invoiceId", payment.getInvoiceId().toString());
             stmt.bind("paymentMethodId", "");
             stmt.bind("amount", payment.getAmount());
             stmt.bind("currency", payment.getCurrency().toString());
             stmt.bind("effectiveDate", getDate(payment.getEffectiveDate()));
-            stmt.bind("paymentStatus", payment.getPaymentStatus().toString());            
+            stmt.bind("paymentStatus", payment.getPaymentStatus().toString());
         }
     }
-    
+
     public static class PaymentModelDaoMapper extends MapperBase implements ResultSetMapper<PaymentModelDao> {
 
         @Override
-        public PaymentModelDao map(int index, ResultSet rs, StatementContext ctx)
+        public PaymentModelDao map(final int index, final ResultSet rs, final StatementContext ctx)
                 throws SQLException {
-            UUID id = getUUID(rs, "id");
-            UUID accountId = getUUID(rs, "account_id");
-            UUID invoiceId = getUUID(rs, "invoice_id");            
-            UUID paymentMethodId = null; //getUUID(rs, "payment_method_id"); // STEPH needs to be fixed!                       
-            Integer paymentNumber = rs.getInt("payment_number");
-            BigDecimal amount = rs.getBigDecimal("amount");
-            DateTime effectiveDate = getDate(rs, "effective_date");
-            Currency currency = Currency.valueOf(rs.getString("currency"));
-            PaymentStatus paymentStatus = PaymentStatus.valueOf(rs.getString("payment_status"));
-            
+            final UUID id = getUUID(rs, "id");
+            final UUID accountId = getUUID(rs, "account_id");
+            final UUID invoiceId = getUUID(rs, "invoice_id");
+            final UUID paymentMethodId = null; //getUUID(rs, "payment_method_id"); // STEPH needs to be fixed!
+            final Integer paymentNumber = rs.getInt("payment_number");
+            final BigDecimal amount = rs.getBigDecimal("amount");
+            final DateTime effectiveDate = getDate(rs, "effective_date");
+            final Currency currency = Currency.valueOf(rs.getString("currency"));
+            final PaymentStatus paymentStatus = PaymentStatus.valueOf(rs.getString("payment_status"));
+
             return new PaymentModelDao(id, accountId, invoiceId, paymentMethodId, paymentNumber, amount, currency, paymentStatus, effectiveDate);
         }
     }
diff --git a/payment/src/main/java/com/ning/billing/payment/dispatcher/PluginDispatcher.java b/payment/src/main/java/com/ning/billing/payment/dispatcher/PluginDispatcher.java
index a439b19..a6c9c72 100644
--- a/payment/src/main/java/com/ning/billing/payment/dispatcher/PluginDispatcher.java
+++ b/payment/src/main/java/com/ning/billing/payment/dispatcher/PluginDispatcher.java
@@ -29,28 +29,28 @@ import com.ning.billing.ErrorCode;
 import com.ning.billing.payment.api.PaymentApiException;
 
 public class PluginDispatcher<T> {
-    
+
     private static final Logger log = LoggerFactory.getLogger(PluginDispatcher.class);
-    
-    private final long DEFAULT_PLUGIN_TIMEOUT_SEC = 30;
+
     private final TimeUnit DEEFAULT_PLUGIN_TIMEOUT_UNIT = TimeUnit.SECONDS;
-    
+
     private final ExecutorService executor;
-    
-    public PluginDispatcher(ExecutorService executor) {
+
+    public PluginDispatcher(final ExecutorService executor) {
         this.executor = executor;
     }
-    
-    public T dispatchWithAccountLock(Callable<T> task) 
-        throws PaymentApiException, TimeoutException {
+
+    public T dispatchWithAccountLock(final Callable<T> task)
+            throws PaymentApiException, TimeoutException {
+        final long DEFAULT_PLUGIN_TIMEOUT_SEC = 30;
         return dispatchWithAccountLockAndTimeout(task, DEFAULT_PLUGIN_TIMEOUT_SEC, DEEFAULT_PLUGIN_TIMEOUT_UNIT);
     }
-    
-    public T dispatchWithAccountLockAndTimeout(Callable<T> task, long timeout, TimeUnit unit)
-    throws PaymentApiException, TimeoutException  {
+
+    public T dispatchWithAccountLockAndTimeout(final Callable<T> task, final long timeout, final TimeUnit unit)
+            throws PaymentApiException, TimeoutException {
 
         try {
-            Future<T> future = executor.submit(task);
+            final Future<T> future = executor.submit(task);
             return future.get(timeout, unit);
         } catch (ExecutionException e) {
             if (e.getCause() instanceof PaymentApiException) {
@@ -61,8 +61,8 @@ public class PluginDispatcher<T> {
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, e.getMessage());
-        } 
+        }
     }
-    
-  
+
+
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java b/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java
index 1a774df..9bd547b 100644
--- a/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java
+++ b/payment/src/main/java/com/ning/billing/payment/glue/DefaultPaymentService.java
@@ -46,7 +46,7 @@ public class DefaultPaymentService implements PaymentService {
 
     @Inject
     public DefaultPaymentService(final InvoiceHandler requestProcessor, final PaymentApi api, final Bus eventBus,
-            final FailedPaymentRetryService failedRetryService, final PluginFailureRetryService timedoutRetryService) {
+                                 final FailedPaymentRetryService failedRetryService, final PluginFailureRetryService timedoutRetryService) {
         this.requestProcessor = requestProcessor;
         this.eventBus = eventBus;
         this.api = api;
@@ -64,17 +64,16 @@ public class DefaultPaymentService implements PaymentService {
         failedRetryService.initialize(SERVICE_NAME);
         timedoutRetryService.initialize(SERVICE_NAME);
     }
-    
+
     @LifecycleHandlerType(LifecycleHandlerType.LifecycleLevel.REGISTER_EVENTS)
     public void registerForNotifications() {
         try {
             eventBus.register(requestProcessor);
-        }
-        catch (Bus.EventBusException e) {
+        } catch (Bus.EventBusException e) {
             log.error("Unable to register with the EventBus!", e);
         }
     }
-    
+
     @LifecycleHandlerType(LifecycleLevel.START_SERVICE)
     public void start() {
         failedRetryService.start();
diff --git a/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java b/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
index 01f7bbf..803b818 100644
--- a/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
+++ b/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
@@ -21,8 +21,11 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 
+import org.skife.config.ConfigSource;
 import org.skife.config.ConfigurationObjectFactory;
+import org.skife.config.SimplePropertyConfigSource;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.inject.AbstractModule;
 import com.google.inject.name.Names;
 import com.ning.billing.config.PaymentConfig;
@@ -43,44 +46,46 @@ import com.ning.billing.payment.retry.PluginFailureRetryService;
 import com.ning.billing.payment.retry.PluginFailureRetryService.PluginFailureRetryServiceScheduler;
 
 public class PaymentModule extends AbstractModule {
-    
-    private final static int PLUGIN_NB_THREADS = 3;
-    private final static String PLUGIN_THREAD_PREFIX = "Plugin-th-";
-    
-    public final static String PLUGIN_EXECUTOR_NAMED = "PluginExecutor";
-    
+    private static final int PLUGIN_NB_THREADS = 3;
+    private static final String PLUGIN_THREAD_PREFIX = "Plugin-th-";
 
-    protected final Properties props;
+    public static final String PLUGIN_EXECUTOR_NAMED = "PluginExecutor";
+
+    @VisibleForTesting
+    protected ConfigSource configSource;
 
     public PaymentModule() {
-        this.props = System.getProperties();
+        this(System.getProperties());
+    }
+
+    public PaymentModule(final ConfigSource configSource) {
+        this.configSource = configSource;
     }
 
-    public PaymentModule(Properties props) {
-        this.props = props;
+    public PaymentModule(final Properties properties) {
+        this(new SimplePropertyConfigSource(properties));
     }
 
     protected void installPaymentDao() {
         bind(PaymentDao.class).to(AuditedPaymentDao.class).asEagerSingleton();
     }
 
-    protected void installPaymentProviderPlugins(PaymentConfig config) {
+    protected void installPaymentProviderPlugins(final PaymentConfig config) {
     }
 
     protected void installRetryEngines() {
         bind(FailedPaymentRetryService.class).asEagerSingleton();
-        bind(PluginFailureRetryService.class).asEagerSingleton(); 
+        bind(PluginFailureRetryService.class).asEagerSingleton();
         bind(FailedPaymentRetryServiceScheduler.class).asEagerSingleton();
-        bind(PluginFailureRetryServiceScheduler.class).asEagerSingleton();        
+        bind(PluginFailureRetryServiceScheduler.class).asEagerSingleton();
     }
-    
-    
+
     protected void installProcessors() {
         final ExecutorService pluginExecutorService = Executors.newFixedThreadPool(PLUGIN_NB_THREADS, new ThreadFactory() {
 
             @Override
-            public Thread newThread(Runnable r) {
-                Thread th = new Thread(r);
+            public Thread newThread(final Runnable r) {
+                final Thread th = new Thread(r);
                 th.setName(PLUGIN_THREAD_PREFIX + th.getId());
                 return th;
             }
@@ -93,7 +98,7 @@ public class PaymentModule extends AbstractModule {
 
     @Override
     protected void configure() {
-        final ConfigurationObjectFactory factory = new ConfigurationObjectFactory(props);
+        final ConfigurationObjectFactory factory = new ConfigurationObjectFactory(configSource);
         final PaymentConfig paymentConfig = factory.build(PaymentConfig.class);
 
         bind(PaymentConfig.class).toInstance(paymentConfig);
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentInfoPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentInfoPlugin.java
index 1476fff..325d03d 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentInfoPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentInfoPlugin.java
@@ -16,25 +16,21 @@
 package com.ning.billing.payment.provider;
 
 import java.math.BigDecimal;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.ning.billing.payment.api.PaymentInfoEvent;
 import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
-import com.ning.billing.payment.plugin.api.PaymentInfoPlugin.PaymentPluginStatus;
 
 public class DefaultNoOpPaymentInfoPlugin implements PaymentInfoPlugin {
-    
+
     private final BigDecimal amount;
     private final DateTime effectiveDate;
-    private final DateTime createdDate;    
-    private final PaymentPluginStatus status; 
+    private final DateTime createdDate;
+    private final PaymentPluginStatus status;
     private final String error;
-   
 
-    public DefaultNoOpPaymentInfoPlugin(BigDecimal amount, DateTime effectiveDate,
-            DateTime createdDate, PaymentPluginStatus status, String error) {
+    public DefaultNoOpPaymentInfoPlugin(final BigDecimal amount, final DateTime effectiveDate,
+                                        final DateTime createdDate, final PaymentPluginStatus status, final String error) {
         super();
         this.amount = amount;
         this.effectiveDate = effectiveDate;
@@ -55,7 +51,7 @@ public class DefaultNoOpPaymentInfoPlugin implements PaymentInfoPlugin {
         return effectiveDate;
     }
 
-     @Override
+    @Override
     public PaymentPluginStatus getStatus() {
         return status;
     }
@@ -64,6 +60,7 @@ public class DefaultNoOpPaymentInfoPlugin implements PaymentInfoPlugin {
     public DateTime getCreatedDate() {
         return createdDate;
     }
+
     @Override
     public String getGatewayError() {
         return error;
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
index 049cabd..af88c29 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
@@ -19,22 +19,21 @@ import java.util.List;
 import java.util.UUID;
 
 import com.ning.billing.payment.api.PaymentMethodPlugin;
-import com.ning.billing.payment.api.PaymentMethodPlugin.PaymentMethodKVInfo;
 
 public class DefaultNoOpPaymentMethodPlugin implements PaymentMethodPlugin {
 
     private String externalId;
     private boolean isDefault;
     private List<PaymentMethodKVInfo> props;
-    
-    public DefaultNoOpPaymentMethodPlugin(PaymentMethodPlugin src) {
+
+    public DefaultNoOpPaymentMethodPlugin(final PaymentMethodPlugin src) {
         this.externalId = UUID.randomUUID().toString();
         this.isDefault = src.isDefaultPaymentMethod();
         this.props = src.getProperties();
     }
-    
-    public DefaultNoOpPaymentMethodPlugin(String externalId, boolean isDefault,
-            List<PaymentMethodKVInfo> props) {
+
+    public DefaultNoOpPaymentMethodPlugin(final String externalId, final boolean isDefault,
+                                          final List<PaymentMethodKVInfo> props) {
         super();
         this.externalId = externalId;
         this.isDefault = isDefault;
@@ -56,24 +55,24 @@ public class DefaultNoOpPaymentMethodPlugin implements PaymentMethodPlugin {
         return props;
     }
 
-    public void setExternalId(String externalId) {
+    public void setExternalId(final String externalId) {
         this.externalId = externalId;
     }
 
-    public void setDefault(boolean isDefault) {
+    public void setDefault(final boolean isDefault) {
         this.isDefault = isDefault;
     }
 
-    public void setProps(List<PaymentMethodKVInfo> props) {
+    public void setProps(final List<PaymentMethodKVInfo> props) {
         this.props = props;
     }
 
     @Override
-    public String getValueString(String key) {
+    public String getValueString(final String key) {
         if (props == null) {
             return null;
         }
-        for (PaymentMethodKVInfo cur : props) {
+        for (final PaymentMethodKVInfo cur : props) {
             if (cur.getKey().equals(key)) {
                 return cur.getValue().toString();
             }
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
index 810883b..5591937 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
@@ -24,22 +24,17 @@ import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.apache.commons.lang.RandomStringUtils;
-
 import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.payment.api.PaymentMethodPlugin;
 import com.ning.billing.payment.plugin.api.NoOpPaymentPluginApi;
 import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
+import com.ning.billing.payment.plugin.api.PaymentInfoPlugin.PaymentPluginStatus;
 import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
 import com.ning.billing.payment.plugin.api.PaymentProviderAccount;
-import com.ning.billing.payment.plugin.api.PaymentPluginApi;
-import com.ning.billing.payment.plugin.api.PaymentInfoPlugin.PaymentPluginStatus;
 import com.ning.billing.util.clock.Clock;
 
 public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
-
-    
     private final AtomicBoolean makeNextInvoiceFailWithError = new AtomicBoolean(false);
     private final AtomicBoolean makeNextInvoiceFailWithException = new AtomicBoolean(false);
     private final AtomicBoolean makeAllInvoicesFailWithError = new AtomicBoolean(false);
@@ -51,18 +46,18 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     private final Clock clock;
 
     @Inject
-    public DefaultNoOpPaymentProviderPlugin(Clock clock) {
+    public DefaultNoOpPaymentProviderPlugin(final Clock clock) {
         this.clock = clock;
         clear();
     }
-    
+
     @Override
     public void clear() {
         makeNextInvoiceFailWithException.set(false);
         makeAllInvoicesFailWithError.set(false);
         makeNextInvoiceFailWithError.set(false);
     }
-    
+
     @Override
     public void makeNextPaymentFailWithError() {
         makeNextInvoiceFailWithError.set(true);
@@ -74,11 +69,11 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public void makeAllInvoicesFailWithError(boolean failure) {
+    public void makeAllInvoicesFailWithError(final boolean failure) {
         makeAllInvoicesFailWithError.set(failure);
     }
 
-    
+
     @Override
     public String getName() {
         return null;
@@ -86,21 +81,21 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
 
 
     @Override
-    public PaymentInfoPlugin processPayment(String externalKey, UUID paymentId, BigDecimal amount) throws PaymentPluginApiException {
+    public PaymentInfoPlugin processPayment(final String externalKey, final UUID paymentId, final BigDecimal amount) throws PaymentPluginApiException {
         if (makeNextInvoiceFailWithException.getAndSet(false)) {
             throw new PaymentPluginApiException("", "test error");
         }
 
-        PaymentPluginStatus status = (makeAllInvoicesFailWithError.get() || makeNextInvoiceFailWithError.getAndSet(false)) ? PaymentPluginStatus.ERROR : PaymentPluginStatus.PROCESSED;
-        PaymentInfoPlugin result = new DefaultNoOpPaymentInfoPlugin(amount, clock.getUTCNow(), clock.getUTCNow(), status, null);
+        final PaymentPluginStatus status = (makeAllInvoicesFailWithError.get() || makeNextInvoiceFailWithError.getAndSet(false)) ? PaymentPluginStatus.ERROR : PaymentPluginStatus.PROCESSED;
+        final PaymentInfoPlugin result = new DefaultNoOpPaymentInfoPlugin(amount, clock.getUTCNow(), clock.getUTCNow(), status, null);
         payments.put(paymentId, result);
         return result;
     }
 
 
     @Override
-    public PaymentInfoPlugin getPaymentInfo(UUID paymentId) throws PaymentPluginApiException {
-        PaymentInfoPlugin payment = payments.get(paymentId);
+    public PaymentInfoPlugin getPaymentInfo(final UUID paymentId) throws PaymentPluginApiException {
+        final PaymentInfoPlugin payment = payments.get(paymentId);
         if (payment == null) {
             throw new PaymentPluginApiException("", "No payment found for id " + paymentId);
         }
@@ -108,54 +103,53 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public String createPaymentProviderAccount(Account account)  throws PaymentPluginApiException {
+    public String createPaymentProviderAccount(final Account account) throws PaymentPluginApiException {
         if (account != null) {
-            String id = String.valueOf(RandomStringUtils.randomAlphanumeric(10));
-            String paymentMethodId = String.valueOf(RandomStringUtils.randomAlphanumeric(10));            
+            final String id = UUID.randomUUID().toString();
+            final String paymentMethodId = UUID.randomUUID().toString();
             accounts.put(account.getExternalKey(),
                          new PaymentProviderAccount.Builder().setAccountKey(account.getExternalKey())
                                                              .setId(id)
                                                              .setDefaultPaymentMethod(paymentMethodId)
                                                              .build());
             return id;
-        }
-        else {
+        } else {
             throw new PaymentPluginApiException("", "Did not get account to create payment provider account");
         }
     }
 
     @Override
-    public String addPaymentMethod(String accountKey, PaymentMethodPlugin paymentMethodProps, boolean setDefault)  throws PaymentPluginApiException {
-        PaymentMethodPlugin realWithID = new DefaultNoOpPaymentMethodPlugin(paymentMethodProps);
+    public String addPaymentMethod(final String accountKey, final PaymentMethodPlugin paymentMethodProps, final boolean setDefault) throws PaymentPluginApiException {
+        final PaymentMethodPlugin realWithID = new DefaultNoOpPaymentMethodPlugin(paymentMethodProps);
         List<PaymentMethodPlugin> pms = paymentMethods.get(accountKey);
         if (pms == null) {
             pms = new LinkedList<PaymentMethodPlugin>();
             paymentMethods.put(accountKey, pms);
         }
         pms.add(realWithID);
-        
-        
+
+
         return realWithID.getExternalPaymentMethodId();
     }
 
 
     @Override
-    public void updatePaymentMethod(String accountKey, PaymentMethodPlugin paymentMethodProps)
-        throws PaymentPluginApiException {
-        DefaultNoOpPaymentMethodPlugin e = getPaymentMethod(accountKey, paymentMethodProps.getExternalPaymentMethodId());
+    public void updatePaymentMethod(final String accountKey, final PaymentMethodPlugin paymentMethodProps)
+            throws PaymentPluginApiException {
+        final DefaultNoOpPaymentMethodPlugin e = getPaymentMethod(accountKey, paymentMethodProps.getExternalPaymentMethodId());
         if (e != null) {
             e.setProps(paymentMethodProps.getProperties());
         }
     }
 
     @Override
-    public void deletePaymentMethod(String accountKey, String paymentMethodId)  throws PaymentPluginApiException {
+    public void deletePaymentMethod(final String accountKey, final String paymentMethodId) throws PaymentPluginApiException {
 
         PaymentMethodPlugin toBeDeleted = null;
-        List<PaymentMethodPlugin> pms = paymentMethods.get(accountKey);
+        final List<PaymentMethodPlugin> pms = paymentMethods.get(accountKey);
         if (pms != null) {
 
-            for (PaymentMethodPlugin cur : pms) {
+            for (final PaymentMethodPlugin cur : pms) {
                 if (cur.getExternalPaymentMethodId().equals(paymentMethodId)) {
                     toBeDeleted = cur;
                     break;
@@ -168,37 +162,37 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
     }
 
     @Override
-    public List<PaymentMethodPlugin> getPaymentMethodDetails(String accountKey)
+    public List<PaymentMethodPlugin> getPaymentMethodDetails(final String accountKey)
             throws PaymentPluginApiException {
         return paymentMethods.get(accountKey);
     }
 
     @Override
-    public PaymentMethodPlugin getPaymentMethodDetail(String accountKey, String externalPaymentId) 
-    throws PaymentPluginApiException {
+    public PaymentMethodPlugin getPaymentMethodDetail(final String accountKey, final String externalPaymentId)
+            throws PaymentPluginApiException {
         return getPaymentMethodDetail(accountKey, externalPaymentId);
     }
-    
-    private DefaultNoOpPaymentMethodPlugin getPaymentMethod(String accountKey, String externalPaymentId) {
-        List<PaymentMethodPlugin> pms = paymentMethods.get(accountKey);
+
+    private DefaultNoOpPaymentMethodPlugin getPaymentMethod(final String accountKey, final String externalPaymentId) {
+        final List<PaymentMethodPlugin> pms = paymentMethods.get(accountKey);
         if (pms == null) {
             return null;
         }
-        for (PaymentMethodPlugin cur : pms) {
+        for (final PaymentMethodPlugin cur : pms) {
             if (cur.getExternalPaymentMethodId().equals(externalPaymentId)) {
                 return (DefaultNoOpPaymentMethodPlugin) cur;
             }
         }
         return null;
     }
-    
+
     @Override
-    public void setDefaultPaymentMethod(String accountKey,
-            String externalPaymentId) throws PaymentPluginApiException {
+    public void setDefaultPaymentMethod(final String accountKey,
+                                        final String externalPaymentId) throws PaymentPluginApiException {
     }
 
     @Override
-    public List<PaymentInfoPlugin> processRefund(Account account)
+    public List<PaymentInfoPlugin> processRefund(final Account account)
             throws PaymentPluginApiException {
         return null;
     }
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/DefaultPaymentProviderPluginRegistry.java b/payment/src/main/java/com/ning/billing/payment/provider/DefaultPaymentProviderPluginRegistry.java
index c762e93..200eaca 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/DefaultPaymentProviderPluginRegistry.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/DefaultPaymentProviderPluginRegistry.java
@@ -20,31 +20,29 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.commons.lang.StringUtils;
-
+import com.google.common.base.Strings;
 import com.google.inject.Inject;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.payment.plugin.api.PaymentPluginApi;
 
-
 public class DefaultPaymentProviderPluginRegistry implements PaymentProviderPluginRegistry {
-    
+
     private final String defaultPlugin;
     private final Map<String, PaymentPluginApi> pluginsByName = new ConcurrentHashMap<String, PaymentPluginApi>();
 
     @Inject
-    public DefaultPaymentProviderPluginRegistry(PaymentConfig config) {
+    public DefaultPaymentProviderPluginRegistry(final PaymentConfig config) {
         this.defaultPlugin = config.getDefaultPaymentProvider();
     }
 
     @Override
-    public void register(PaymentPluginApi plugin, String name) {
+    public void register(final PaymentPluginApi plugin, final String name) {
         pluginsByName.put(name.toLowerCase(), plugin);
     }
 
     @Override
-    public PaymentPluginApi getPlugin(String name) {
-        PaymentPluginApi plugin = pluginsByName.get(StringUtils.defaultIfEmpty(name, defaultPlugin).toLowerCase());
+    public PaymentPluginApi getPlugin(final String name) {
+        final PaymentPluginApi plugin = pluginsByName.get((Strings.emptyToNull(name) == null ? defaultPlugin : name).toLowerCase());
 
         if (plugin == null) {
             throw new IllegalArgumentException("No payment provider plugin is configured for " + name);
@@ -52,7 +50,7 @@ public class DefaultPaymentProviderPluginRegistry implements PaymentProviderPlug
 
         return plugin;
     }
-    
+
     @Override
     public Set<String> getRegisteredPluginNames() {
         return pluginsByName.keySet();
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginModule.java b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginModule.java
index 2fcc512..4774158 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginModule.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginModule.java
@@ -22,15 +22,15 @@ import com.google.inject.name.Names;
 public class NoOpPaymentProviderPluginModule extends AbstractModule {
     private final String instanceName;
 
-    public NoOpPaymentProviderPluginModule(String instanceName) {
+    public NoOpPaymentProviderPluginModule(final String instanceName) {
         this.instanceName = instanceName;
     }
 
     @Override
     protected void configure() {
         bind(DefaultNoOpPaymentProviderPlugin.class)
-            .annotatedWith(Names.named(instanceName))
-            .toProvider(new NoOpPaymentProviderPluginProvider(instanceName))
-            .asEagerSingleton();
+                .annotatedWith(Names.named(instanceName))
+                .toProvider(new NoOpPaymentProviderPluginProvider(instanceName))
+                .asEagerSingleton();
     }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginProvider.java b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginProvider.java
index b219133..51007ac 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginProvider.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginProvider.java
@@ -23,24 +23,24 @@ import com.ning.billing.util.clock.Clock;
 public class NoOpPaymentProviderPluginProvider implements Provider<DefaultNoOpPaymentProviderPlugin> {
 
     private final String instanceName;
-    
+
     private Clock clock;
     private PaymentProviderPluginRegistry registry;
-    
-    public NoOpPaymentProviderPluginProvider(String instanceName) {
+
+    public NoOpPaymentProviderPluginProvider(final String instanceName) {
         this.instanceName = instanceName;
 
     }
 
     @Inject
-    public void setPaymentProviderPluginRegistry(PaymentProviderPluginRegistry registry, Clock clock) {
+    public void setPaymentProviderPluginRegistry(final PaymentProviderPluginRegistry registry, final Clock clock) {
         this.clock = clock;
         this.registry = registry;
     }
 
     @Override
     public DefaultNoOpPaymentProviderPlugin get() {
-        DefaultNoOpPaymentProviderPlugin plugin = new DefaultNoOpPaymentProviderPlugin(clock);
+        final DefaultNoOpPaymentProviderPlugin plugin = new DefaultNoOpPaymentProviderPlugin(clock);
 
         registry.register(plugin, instanceName);
         return plugin;
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/BaseRetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/BaseRetryService.java
index e9600df..292583e 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/BaseRetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/BaseRetryService.java
@@ -15,6 +15,7 @@
  */
 package com.ning.billing.payment.retry;
 
+import java.io.IOException;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -34,34 +35,38 @@ import com.ning.billing.util.notificationq.NotificationQueueService.Notification
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 
 public abstract class BaseRetryService implements RetryService {
-    
+
     private static final Logger log = LoggerFactory.getLogger(BaseRetryService.class);
-    
+
     private final NotificationQueueService notificationQueueService;
-    private final Clock clock;
     private final PaymentConfig config;
-    
+
     private NotificationQueue retryQueue;
-    
+
     public BaseRetryService(final NotificationQueueService notificationQueueService,
             final Clock clock, final PaymentConfig config) {
         this.notificationQueueService = notificationQueueService;
-        this.clock = clock;
+        final Clock clock1 = clock;
         this.config = config;
     }
-   
+
 
     @Override
     public void initialize(final String svcName) throws NotificationQueueAlreadyExists {
         retryQueue = notificationQueueService.createNotificationQueue(svcName, getQueueName(), new NotificationQueueHandler() {
             @Override
-            public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
-                retry(UUID.fromString(notificationKey));
+            public void handleReadyNotification(final NotificationKey notificationKey, final DateTime eventDateTime) {
+                if (! (notificationKey instanceof PaymentRetryNotificationKey)) {
+                    log.error("Payment service got an unexpected notification type {}", notificationKey.getClass().getName());
+                    return;
+                }
+                final PaymentRetryNotificationKey key = (PaymentRetryNotificationKey) notificationKey;
+                retry(key.getUuidKey());
             }
         },
         config);
     }
-
+    
     @Override
     public void start() {
         retryQueue.startQueue();
@@ -74,27 +79,27 @@ public abstract class BaseRetryService implements RetryService {
             notificationQueueService.deleteNotificationQueue(retryQueue.getServiceName(), retryQueue.getQueueName());
         }
     }
-    
+
     public abstract String getQueueName();
-    
-    
+
+
     public abstract static class RetryServiceScheduler {
-        
+
         private final NotificationQueueService notificationQueueService;
-        
+
         @Inject
         public RetryServiceScheduler(final NotificationQueueService notificationQueueService) {
             this.notificationQueueService = notificationQueueService;
         }
-    
+
         public boolean scheduleRetryFromTransaction(final UUID paymentId, final DateTime timeOfRetry, final Transmogrifier transactionalDao) {
             return scheduleRetryInternal(paymentId, timeOfRetry, transactionalDao);
         }
-        
+
         public boolean scheduleRetry(final UUID paymentId, final DateTime timeOfRetry) {
             return scheduleRetryInternal(paymentId, timeOfRetry, null);
         }
-        
+
         // STEPH TimedoutPaymentRetryServiceScheduler
         public void cancelAllScheduleRetryForKey(final UUID paymentId) {
             /*
@@ -110,19 +115,14 @@ public abstract class BaseRetryService implements RetryService {
             } catch (NoSuchNotificationQueue e) {
                 log.error(String.format("Failed to retrieve notification queue %s:%s", DefaultPaymentService.SERVICE_NAME, getQueueName()));
             }
-            */
+             */
         }
-        
+
         private boolean scheduleRetryInternal(final UUID paymentId, final DateTime timeOfRetry, final Transmogrifier transactionalDao) {
 
             try {
-                NotificationQueue retryQueue = notificationQueueService.getNotificationQueue(DefaultPaymentService.SERVICE_NAME, getQueueName());
-                NotificationKey key = new NotificationKey() {
-                    @Override
-                    public String toString() {
-                        return paymentId.toString();
-                    }
-                };
+                final NotificationQueue retryQueue = notificationQueueService.getNotificationQueue(DefaultPaymentService.SERVICE_NAME, getQueueName());
+                final NotificationKey key = new PaymentRetryNotificationKey(paymentId);
                 if (retryQueue != null) {
                     if (transactionalDao == null) {
                         retryQueue.recordFutureNotification(timeOfRetry, key);
@@ -133,9 +133,13 @@ public abstract class BaseRetryService implements RetryService {
             } catch (NoSuchNotificationQueue e) {
                 log.error(String.format("Failed to retrieve notification queue %s:%s", DefaultPaymentService.SERVICE_NAME, getQueueName()));
                 return false;
+            } catch (IOException e) {
+                log.error(String.format("Failed to serialize notificationQueue event for paymentId %s", paymentId));
+                return false;
             }
             return true;
         }
+
         public abstract String getQueueName();
     }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java
index 0abf68e..2259ce6 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/FailedPaymentRetryService.java
@@ -19,10 +19,6 @@ package com.ning.billing.payment.retry;
 import java.util.List;
 import java.util.UUID;
 
-
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.notificationq.NotificationQueueService;
-
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -32,66 +28,67 @@ import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.payment.core.PaymentProcessor;
 import com.ning.billing.payment.dao.PaymentDao;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.notificationq.NotificationQueueService;
 
 
 public class FailedPaymentRetryService extends BaseRetryService implements RetryService {
-    
+
     private static final Logger log = LoggerFactory.getLogger(FailedPaymentRetryService.class);
-    
+
     public static final String QUEUE_NAME = "failed-payment";
 
     private final PaymentProcessor paymentProcessor;
 
-    
+
     @Inject
     public FailedPaymentRetryService(final AccountUserApi accountUserApi,
-            final Clock clock,
-            final NotificationQueueService notificationQueueService,
-            final PaymentConfig config,
-            final PaymentProcessor paymentProcessor,
-            final PaymentDao paymentDao) {
+                                     final Clock clock,
+                                     final NotificationQueueService notificationQueueService,
+                                     final PaymentConfig config,
+                                     final PaymentProcessor paymentProcessor,
+                                     final PaymentDao paymentDao) {
         super(notificationQueueService, clock, config);
         this.paymentProcessor = paymentProcessor;
     }
 
-    
 
     @Override
     public void retry(final UUID paymentId) {
         paymentProcessor.retryFailedPayment(paymentId);
     }
-    
-    
+
+
     public static class FailedPaymentRetryServiceScheduler extends RetryServiceScheduler {
-        
+
         private final PaymentConfig config;
         private final Clock clock;
-        
+
         @Inject
         public FailedPaymentRetryServiceScheduler(final NotificationQueueService notificationQueueService,
-                final Clock clock, final PaymentConfig config) {
+                                                  final Clock clock, final PaymentConfig config) {
             super(notificationQueueService);
             this.config = config;
             this.clock = clock;
         }
-        
+
         public boolean scheduleRetry(final UUID paymentId, final int retryAttempt) {
-            DateTime timeOfRetry = getNextRetryDate(retryAttempt);
+            final DateTime timeOfRetry = getNextRetryDate(retryAttempt);
             if (timeOfRetry == null) {
                 return false;
             }
             return scheduleRetry(paymentId, timeOfRetry);
         }
-        
-        
-        private DateTime getNextRetryDate(int retryAttempt) {
+
+
+        private DateTime getNextRetryDate(final int retryAttempt) {
 
             DateTime result = null;
             final List<Integer> retryDays = config.getPaymentRetryDays();
-            int retryCount = retryAttempt - 1;
+            final int retryCount = retryAttempt - 1;
             if (retryCount < retryDays.size()) {
                 int retryInDays = 0;
-                DateTime nextRetryDate = clock.getUTCNow();
+                final DateTime nextRetryDate = clock.getUTCNow();
                 try {
                     retryInDays = retryDays.get(retryCount);
                     result = nextRetryDate.plusDays(retryInDays);
@@ -99,7 +96,7 @@ public class FailedPaymentRetryService extends BaseRetryService implements Retry
                     log.error("Could not get retry day for retry count {}", retryCount);
                 }
             }
-            return result;            
+            return result;
         }
 
 
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/PaymentRetryNotificationKey.java b/payment/src/main/java/com/ning/billing/payment/retry/PaymentRetryNotificationKey.java
new file mode 100644
index 0000000..8d81911
--- /dev/null
+++ b/payment/src/main/java/com/ning/billing/payment/retry/PaymentRetryNotificationKey.java
@@ -0,0 +1,30 @@
+/* 
+ * Copyright 2010-2011 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.payment.retry;
+
+import java.util.UUID;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.ning.billing.util.notificationq.DefaultUUIDNotificationKey;
+
+public class PaymentRetryNotificationKey extends DefaultUUIDNotificationKey {
+
+    @JsonCreator
+    public PaymentRetryNotificationKey(@JsonProperty("uuidKey") UUID uuidKey) {
+        super(uuidKey);
+    }
+}
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/PluginFailureRetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/PluginFailureRetryService.java
index d3e9c8a..2fca8e0 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/PluginFailureRetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/PluginFailureRetryService.java
@@ -17,7 +17,6 @@ package com.ning.billing.payment.retry;
 
 import java.util.UUID;
 
-
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
@@ -27,45 +26,43 @@ import com.google.inject.Inject;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.payment.core.PaymentProcessor;
-
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationQueueService;
 
 public class PluginFailureRetryService extends BaseRetryService implements RetryService {
 
-  private static final Logger log = LoggerFactory.getLogger(PluginFailureRetryService.class);
-    
+    private static final Logger log = LoggerFactory.getLogger(PluginFailureRetryService.class);
+
     public static final String QUEUE_NAME = "plugin-failure";
 
     private final PaymentProcessor paymentProcessor;
 
-    
+
     @Inject
     public PluginFailureRetryService(final AccountUserApi accountUserApi,
-            final Clock clock,
-            final NotificationQueueService notificationQueueService,
-            final PaymentConfig config,
-            final PaymentProcessor paymentProcessor) {
+                                     final Clock clock,
+                                     final NotificationQueueService notificationQueueService,
+                                     final PaymentConfig config,
+                                     final PaymentProcessor paymentProcessor) {
         super(notificationQueueService, clock, config);
         this.paymentProcessor = paymentProcessor;
     }
 
-    
 
     @Override
     public void retry(final UUID paymentId) {
         paymentProcessor.retryPluginFailure(paymentId);
     }
-    
-    
+
+
     public static class PluginFailureRetryServiceScheduler extends RetryServiceScheduler {
-        
+
         private final Clock clock;
         private final PaymentConfig config;
-        
+
         @Inject
         public PluginFailureRetryServiceScheduler(final NotificationQueueService notificationQueueService,
-                final Clock clock, final PaymentConfig config) {
+                                                  final Clock clock, final PaymentConfig config) {
             super(notificationQueueService);
             this.clock = clock;
             this.config = config;
@@ -75,25 +72,25 @@ public class PluginFailureRetryService extends BaseRetryService implements Retry
         public String getQueueName() {
             return QUEUE_NAME;
         }
-        
+
         public boolean scheduleRetry(final UUID paymentId, final int retryAttempt) {
-            DateTime nextRetryDate = getNextRetryDate(retryAttempt);
+            final DateTime nextRetryDate = getNextRetryDate(retryAttempt);
             if (nextRetryDate == null) {
                 return false;
             }
             return scheduleRetry(paymentId, nextRetryDate);
         }
-        
+
         public boolean scheduleRetryFromTransaction(final UUID paymentId, final int retryAttempt, final Transmogrifier transactionalDao) {
-            DateTime nextRetryDate = getNextRetryDate(retryAttempt);
+            final DateTime nextRetryDate = getNextRetryDate(retryAttempt);
             if (nextRetryDate == null) {
                 return false;
             }
             return scheduleRetryFromTransaction(paymentId, nextRetryDate, transactionalDao);
         }
-        
+
         private DateTime getNextRetryDate(final int retryAttempt) {
-            
+
 
             if (retryAttempt > config.getPluginFailureRetryMaxAttempts()) {
                 return null;
@@ -105,7 +102,7 @@ public class PluginFailureRetryService extends BaseRetryService implements Retry
             }
             return clock.getUTCNow().plusSeconds(nbSec);
         }
-        
+
     }
 
     @Override
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java
index 8f181bd..b4be707 100644
--- a/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java
+++ b/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java
@@ -21,17 +21,17 @@ import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotifi
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
 
 public interface RetryService {
-    
+
     public void initialize(final String svcName)
-        throws NotificationQueueAlreadyExists;
-    
+            throws NotificationQueueAlreadyExists;
+
     public void start();
-    
+
     public void stop()
-        throws NoSuchNotificationQueue;
-    
+            throws NoSuchNotificationQueue;
+
     public String getQueueName();
-    
+
     public void retry(UUID paymentId);
 
 }
diff --git a/payment/src/main/resources/com/ning/billing/payment/ddl.sql b/payment/src/main/resources/com/ning/billing/payment/ddl.sql
index ba4ff80..b8fa010 100644
--- a/payment/src/main/resources/com/ning/billing/payment/ddl.sql
+++ b/payment/src/main/resources/com/ning/billing/payment/ddl.sql
@@ -17,6 +17,8 @@ CREATE TABLE payments (
     PRIMARY KEY (record_id)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
 CREATE UNIQUE INDEX payments_id ON payments(id);
+CREATE INDEX payments_inv ON payments(invoice_id);
+CREATE INDEX payments_accnt ON payments(account_id);
 
 DROP TABLE IF EXISTS payment_history; 
 CREATE TABLE payment_history (
@@ -54,6 +56,7 @@ CREATE TABLE payment_attempts (
     PRIMARY KEY (record_id)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
 CREATE UNIQUE INDEX payment_attempts_id ON payment_attempts(id);
+CREATE INDEX payment_attempts_payment ON payment_attempts(payment_id);
 
 
 DROP TABLE IF EXISTS payment_attempt_history;
@@ -89,6 +92,7 @@ CREATE TABLE payment_methods (
     PRIMARY KEY (record_id)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
 CREATE UNIQUE INDEX payment_methods_id ON payment_methods(id);
+CREATE INDEX payment_methods_active_accnt ON payment_methods(is_active, account_id);
 
 
 DROP TABLE IF EXISTS payment_method_history;
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestEventJson.java b/payment/src/test/java/com/ning/billing/payment/api/TestEventJson.java
index e704d51..371f7b1 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestEventJson.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestEventJson.java
@@ -18,31 +18,32 @@ package com.ning.billing.payment.api;
 import java.math.BigDecimal;
 import java.util.UUID;
 
-import com.ning.billing.util.jackson.ObjectMapper;
 import org.joda.time.DateTime;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import com.ning.billing.util.jackson.ObjectMapper;
+
 public class TestEventJson {
-    private ObjectMapper mapper = new ObjectMapper();
+    private final ObjectMapper mapper = new ObjectMapper();
 
-    @Test(groups= {"fast"})
+    @Test(groups = {"fast"})
     public void testPaymentErrorEvent() throws Exception {
-        PaymentErrorEvent e = new DefaultPaymentErrorEvent(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), "no message", UUID.randomUUID());
-        String json = mapper.writeValueAsString(e);
+        final PaymentErrorEvent e = new DefaultPaymentErrorEvent(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), "no message", UUID.randomUUID());
+        final String json = mapper.writeValueAsString(e);
 
-        Class<?> claz = Class.forName(DefaultPaymentErrorEvent.class.getName());
-        Object obj =  mapper.readValue(json, claz);
+        final Class<?> claz = Class.forName(DefaultPaymentErrorEvent.class.getName());
+        final Object obj = mapper.readValue(json, claz);
         Assert.assertTrue(obj.equals(e));
     }
-    
-    @Test(groups= {"fast"})
+
+    @Test(groups = {"fast"})
     public void testPaymentInfoEvent() throws Exception {
-        PaymentInfoEvent e = new DefaultPaymentInfoEvent(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), new BigDecimal(12.9), new Integer(13), PaymentStatus.SUCCESS, UUID.randomUUID(), new DateTime());
-        String json = mapper.writeValueAsString(e);
+        final PaymentInfoEvent e = new DefaultPaymentInfoEvent(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID(), new BigDecimal(12.9), new Integer(13), PaymentStatus.SUCCESS, UUID.randomUUID(), new DateTime());
+        final String json = mapper.writeValueAsString(e);
 
-        Class<?> clazz = Class.forName(DefaultPaymentInfoEvent.class.getName());
-        Object obj =  mapper.readValue(json, clazz);
+        final Class<?> clazz = Class.forName(DefaultPaymentInfoEvent.class.getName());
+        final Object obj = mapper.readValue(json, clazz);
         Assert.assertTrue(obj.equals(e));
     }
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
index d1b94c1..df8ef98 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.payment.api;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.List;
@@ -61,12 +56,17 @@ import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.glue.CallContextModule;
 
-@Guice(modules = { PaymentTestModuleWithMocks.class, MockClockModule.class, MockJunctionModule.class, CallContextModule.class })
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Guice(modules = {PaymentTestModuleWithMocks.class, MockClockModule.class, MockJunctionModule.class, CallContextModule.class})
 @Test(groups = "fast")
 public class TestPaymentApi {
-    
+
     private static final Logger log = LoggerFactory.getLogger(TestPaymentApi.class);
-    
+
     @Inject
     private Bus eventBus;
     @Inject
@@ -80,17 +80,17 @@ public class TestPaymentApi {
 
     protected CallContext context;
 
-    private Account account; 
-    
-    
+    private Account account;
+
+
     @Inject
-    public TestPaymentApi(Clock clock) {
+    public TestPaymentApi(final Clock clock) {
         context = new DefaultCallContext("Payment Tests", CallOrigin.INTERNAL, UserType.SYSTEM, clock);
     }
-    
+
     @BeforeClass
     public void setupClass() throws Exception {
-        account = testHelper.createTestAccount("yoyo.yahoo.com");        
+        account = testHelper.createTestAccount("yoyo.yahoo.com");
     }
 
     @BeforeMethod(alwaysRun = true)
@@ -103,67 +103,67 @@ public class TestPaymentApi {
         eventBus.stop();
     }
 
-    
-    @Test(enabled=true)
+
+    @Test(enabled = true)
     public void testSimplePaymentWithNoAmount() throws Exception {
         final BigDecimal invoiceAmount = new BigDecimal("10.0011");
         final BigDecimal requestedAmount = null;
-        final BigDecimal expectedAmount = invoiceAmount;        
-        
+        final BigDecimal expectedAmount = invoiceAmount;
+
         testSimplePayment(invoiceAmount, requestedAmount, expectedAmount);
     }
 
-    @Test(enabled=true)
+    @Test(enabled = true)
     public void testSimplePaymentWithInvoiceAmount() throws Exception {
         final BigDecimal invoiceAmount = new BigDecimal("10.0011");
         final BigDecimal requestedAmount = invoiceAmount;
-        final BigDecimal expectedAmount = invoiceAmount;        
-        
+        final BigDecimal expectedAmount = invoiceAmount;
+
         testSimplePayment(invoiceAmount, requestedAmount, expectedAmount);
     }
 
-    @Test(enabled=true)
+    @Test(enabled = true)
     public void testSimplePaymentWithLowerAmount() throws Exception {
         final BigDecimal invoiceAmount = new BigDecimal("10.0011");
         final BigDecimal requestedAmount = new BigDecimal("8.0091");
-        final BigDecimal expectedAmount = requestedAmount;        
-        
+        final BigDecimal expectedAmount = requestedAmount;
+
         testSimplePayment(invoiceAmount, requestedAmount, expectedAmount);
     }
 
-    @Test(enabled=true)
+    @Test(enabled = true)
     public void testSimplePaymentWithInvalidAmount() throws Exception {
         final BigDecimal invoiceAmount = new BigDecimal("10.0011");
         final BigDecimal requestedAmount = new BigDecimal("80.0091");
-        final BigDecimal expectedAmount = null;        
-        
+        final BigDecimal expectedAmount = null;
+
         testSimplePayment(invoiceAmount, requestedAmount, expectedAmount);
     }
-    
 
-    private void testSimplePayment(BigDecimal invoiceAmount, BigDecimal requestedAmount, BigDecimal expectedAmount) throws Exception {
-        
-        ((ZombieControl)invoicePaymentApi).addResult("notifyOfPaymentAttempt", BrainDeadProxyFactory.ZOMBIE_VOID);
+
+    private void testSimplePayment(final BigDecimal invoiceAmount, final BigDecimal requestedAmount, final BigDecimal expectedAmount) throws Exception {
+
+        ((ZombieControl) invoicePaymentApi).addResult("notifyOfPaymentAttempt", BrainDeadProxyFactory.ZOMBIE_VOID);
 
         final DateTime now = new DateTime(DateTimeZone.UTC);
         final Invoice invoice = testHelper.createTestInvoice(account, now, Currency.USD);
-        
+
         final UUID subscriptionId = UUID.randomUUID();
         final UUID bundleId = UUID.randomUUID();
 
 
         invoice.addInvoiceItem(new MockRecurringInvoiceItem(invoice.getId(), account.getId(),
-                                                       subscriptionId,
-                                                       bundleId,
-                                                       "test plan", "test phase",
-                                                       now,
-                                                       now.plusMonths(1),
-                                                       invoiceAmount,
-                                                       new BigDecimal("1.0"),
-                                                       Currency.USD));
+                                                            subscriptionId,
+                                                            bundleId,
+                                                            "test plan", "test phase",
+                                                            now,
+                                                            now.plusMonths(1),
+                                                            invoiceAmount,
+                                                            new BigDecimal("1.0"),
+                                                            Currency.USD));
 
         try {
-            Payment paymentInfo = paymentApi.createPayment(account.getExternalKey(), invoice.getId(), requestedAmount, context);
+            final Payment paymentInfo = paymentApi.createPayment(account.getExternalKey(), invoice.getId(), requestedAmount, context);
             if (expectedAmount == null) {
                 fail("Expected to fail because requested amount > invoice amount");
             }
@@ -175,7 +175,7 @@ public class TestPaymentApi {
             assertEquals(paymentInfo.getInvoiceId(), invoice.getId());
             assertEquals(paymentInfo.getCurrency(), Currency.USD);
 
-            PaymentAttempt paymentAttempt = paymentInfo.getAttempts().get(0);
+            final PaymentAttempt paymentAttempt = paymentInfo.getAttempts().get(0);
             assertNotNull(paymentAttempt);
             assertNotNull(paymentAttempt.getId());
         } catch (PaymentApiException e) {
@@ -187,28 +187,27 @@ public class TestPaymentApi {
             }
         }
     }
-    
-    @Test(enabled=true)
-    public void testPaymentMethods() throws Exception  {
+
+    @Test(enabled = true)
+    public void testPaymentMethods() throws Exception {
 
         List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, false);
         assertEquals(methods.size(), 1);
-        
-        PaymentMethod initDefaultMethod = methods.get(0);
+
+        final PaymentMethod initDefaultMethod = methods.get(0);
         assertEquals(initDefaultMethod.getId(), account.getPaymentMethodId());
-        
 
-        
+
         //((ZombieControl)accountApi).addResult("updateAccount", );
-        PaymentMethodPlugin newPaymenrMethod = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), true, null);
-        UUID newPaymentMethodId = paymentApi.addPaymentMethod(PaymentTestModuleWithMocks.PLUGIN_TEST_NAME, account, true, newPaymenrMethod, context);
-        ((ZombieControl)account).addResult("getPaymentMethodId", newPaymentMethodId);
-        
+        final PaymentMethodPlugin newPaymenrMethod = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), true, null);
+        final UUID newPaymentMethodId = paymentApi.addPaymentMethod(PaymentTestModuleWithMocks.PLUGIN_TEST_NAME, account, true, newPaymenrMethod, context);
+        ((ZombieControl) account).addResult("getPaymentMethodId", newPaymentMethodId);
+
         methods = paymentApi.getPaymentMethods(account, false);
         assertEquals(methods.size(), 2);
-        
+
         assertEquals(newPaymentMethodId, account.getPaymentMethodId());
-        
+
         boolean failed = false;
         try {
             paymentApi.deletedPaymentMethod(account, newPaymentMethodId, context);
@@ -218,9 +217,9 @@ public class TestPaymentApi {
         assertTrue(failed);
 
         paymentApi.deletedPaymentMethod(account, initDefaultMethod.getId(), context);
-        methods = paymentApi.getPaymentMethods(account, false);        
+        methods = paymentApi.getPaymentMethods(account, false);
         assertEquals(methods.size(), 1);
     }
 
-    
+
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
index dfcf639..fb6a281 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
@@ -28,13 +28,13 @@ import com.ning.billing.util.callcontext.CallContext;
 
 public class MockPaymentDao implements PaymentDao {
 
-    private final Map<UUID, PaymentModelDao> payments =  new HashMap<UUID, PaymentModelDao>();
-    private final Map<UUID, PaymentAttemptModelDao> attempts =  new HashMap<UUID, PaymentAttemptModelDao>();
-    
+    private final Map<UUID, PaymentModelDao> payments = new HashMap<UUID, PaymentModelDao>();
+    private final Map<UUID, PaymentAttemptModelDao> attempts = new HashMap<UUID, PaymentAttemptModelDao>();
+
     @Override
-    public PaymentModelDao insertPaymentWithAttempt(PaymentModelDao paymentInfo, PaymentAttemptModelDao attempt,
-            final boolean scheduleTimeoutRetry, CallContext context) {
-        synchronized(this) {
+    public PaymentModelDao insertPaymentWithAttempt(final PaymentModelDao paymentInfo, final PaymentAttemptModelDao attempt,
+                                                    final boolean scheduleTimeoutRetry, final CallContext context) {
+        synchronized (this) {
             payments.put(paymentInfo.getId(), paymentInfo);
             attempts.put(attempt.getId(), attempt);
         }
@@ -42,52 +42,52 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public PaymentAttemptModelDao insertNewAttemptForPayment(UUID paymentId,
-            PaymentAttemptModelDao attempt, final boolean scheduleTimeoutRetry, CallContext context) {
-        synchronized(this) {
+    public PaymentAttemptModelDao insertNewAttemptForPayment(final UUID paymentId,
+                                                             final PaymentAttemptModelDao attempt, final boolean scheduleTimeoutRetry, final CallContext context) {
+        synchronized (this) {
             attempts.put(attempt.getId(), attempt);
         }
         return attempt;
     }
 
     @Override
-    public void updateStatusForPaymentWithAttempt(UUID paymentId,
-            PaymentStatus paymentStatus, String paymentError, UUID attemptId,
-            CallContext context) {
-        synchronized(this) {
-            PaymentModelDao entry = payments.remove(paymentId);
+    public void updateStatusForPaymentWithAttempt(final UUID paymentId,
+                                                  final PaymentStatus paymentStatus, final String paymentError, final UUID attemptId,
+                                                  final CallContext context) {
+        synchronized (this) {
+            final PaymentModelDao entry = payments.remove(paymentId);
             if (entry != null) {
-               payments.put(paymentId, new PaymentModelDao(entry, paymentStatus));
+                payments.put(paymentId, new PaymentModelDao(entry, paymentStatus));
             }
-            PaymentAttemptModelDao tmp = attempts.remove(attemptId);
+            final PaymentAttemptModelDao tmp = attempts.remove(attemptId);
             if (tmp != null) {
                 attempts.put(attemptId, new PaymentAttemptModelDao(tmp, paymentStatus, paymentError));
             }
         }
     }
-    
+
     @Override
-    public void updateStatusForPayment(UUID paymentId,
-            PaymentStatus paymentStatus, CallContext context) {
-        synchronized(this) {
-            PaymentModelDao entry = payments.remove(paymentId);
+    public void updateStatusForPayment(final UUID paymentId,
+                                       final PaymentStatus paymentStatus, final CallContext context) {
+        synchronized (this) {
+            final PaymentModelDao entry = payments.remove(paymentId);
             if (entry != null) {
-               payments.put(paymentId, new PaymentModelDao(entry, paymentStatus));
+                payments.put(paymentId, new PaymentModelDao(entry, paymentStatus));
             }
         }
     }
 
 
     @Override
-    public PaymentAttemptModelDao getPaymentAttempt(UUID attemptId) {
+    public PaymentAttemptModelDao getPaymentAttempt(final UUID attemptId) {
         return attempts.get(attemptId);
     }
 
     @Override
-    public List<PaymentModelDao> getPaymentsForInvoice(UUID invoiceId) {
-        List<PaymentModelDao> result = new ArrayList<PaymentModelDao>();
-        synchronized(this) {
-            for (PaymentModelDao cur :payments.values()) {
+    public List<PaymentModelDao> getPaymentsForInvoice(final UUID invoiceId) {
+        final List<PaymentModelDao> result = new ArrayList<PaymentModelDao>();
+        synchronized (this) {
+            for (final PaymentModelDao cur : payments.values()) {
                 if (cur.getInvoiceId().equals(invoiceId)) {
                     result.add(cur);
                 }
@@ -97,10 +97,10 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public List<PaymentModelDao> getPaymentsForAccount(UUID accountId) {
-        List<PaymentModelDao> result = new ArrayList<PaymentModelDao>();
-        synchronized(this) {
-            for (PaymentModelDao cur :payments.values()) {
+    public List<PaymentModelDao> getPaymentsForAccount(final UUID accountId) {
+        final List<PaymentModelDao> result = new ArrayList<PaymentModelDao>();
+        synchronized (this) {
+            for (final PaymentModelDao cur : payments.values()) {
                 if (cur.getAccountId().equals(accountId)) {
                     result.add(cur);
                 }
@@ -110,15 +110,15 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public PaymentModelDao getPayment(UUID paymentId) {
+    public PaymentModelDao getPayment(final UUID paymentId) {
         return payments.get(paymentId);
     }
 
     @Override
-    public List<PaymentAttemptModelDao> getAttemptsForPayment(UUID paymentId) {
-        List<PaymentAttemptModelDao> result = new ArrayList<PaymentAttemptModelDao>();
-        synchronized(this) {
-            for (PaymentAttemptModelDao cur : attempts.values()) {
+    public List<PaymentAttemptModelDao> getAttemptsForPayment(final UUID paymentId) {
+        final List<PaymentAttemptModelDao> result = new ArrayList<PaymentAttemptModelDao>();
+        synchronized (this) {
+            for (final PaymentAttemptModelDao cur : attempts.values()) {
                 if (cur.getPaymentId().equals(paymentId)) {
                     result.add(cur);
                 }
@@ -128,16 +128,16 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     private final List<PaymentMethodModelDao> paymentMethods = new LinkedList<PaymentMethodModelDao>();
-    
+
     @Override
-    public PaymentMethodModelDao insertPaymentMethod(PaymentMethodModelDao paymentMethod, CallContext context) {
+    public PaymentMethodModelDao insertPaymentMethod(final PaymentMethodModelDao paymentMethod, final CallContext context) {
         paymentMethods.add(paymentMethod);
         return paymentMethod;
     }
 
     @Override
-    public PaymentMethodModelDao getPaymentMethod(UUID paymentMethodId) {
-        for (PaymentMethodModelDao cur : paymentMethods) {
+    public PaymentMethodModelDao getPaymentMethod(final UUID paymentMethodId) {
+        for (final PaymentMethodModelDao cur : paymentMethods) {
             if (cur.getId().equals(paymentMethodId)) {
                 return cur;
             }
@@ -146,9 +146,9 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public List<PaymentMethodModelDao> getPaymentMethods(UUID accountId) {
-        List<PaymentMethodModelDao> result = new ArrayList<PaymentMethodModelDao>();
-        for (PaymentMethodModelDao cur : paymentMethods) {
+    public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId) {
+        final List<PaymentMethodModelDao> result = new ArrayList<PaymentMethodModelDao>();
+        for (final PaymentMethodModelDao cur : paymentMethods) {
             if (cur.getAccountId().equals(accountId)) {
                 result.add(cur);
             }
@@ -157,10 +157,10 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
-    public void deletedPaymentMethod(UUID paymentMethodId) {
-        Iterator<PaymentMethodModelDao> it = paymentMethods.iterator();
+    public void deletedPaymentMethod(final UUID paymentMethodId) {
+        final Iterator<PaymentMethodModelDao> it = paymentMethods.iterator();
         while (it.hasNext()) {
-            PaymentMethodModelDao cur = it.next();
+            final PaymentMethodModelDao cur = it.next();
             if (cur.getId().equals(paymentMethodId)) {
                 it.remove();
                 break;
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
index eb99b14..10c2ac5 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
@@ -15,23 +15,16 @@
  */
 package com.ning.billing.payment.dao;
 
-import static junit.framework.Assert.assertNull;
-import static org.testng.Assert.assertEquals;
-
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.List;
 import java.util.UUID;
 
-import junit.framework.Assert;
-
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
 import org.testng.annotations.AfterSuite;
-
 import org.testng.annotations.BeforeSuite;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
@@ -45,229 +38,231 @@ import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.TestCallContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
+import com.ning.billing.util.io.IOUtils;
+
+import static junit.framework.Assert.assertNull;
+import static org.testng.Assert.assertEquals;
 
 public class TestPaymentDao {
-    
-    static private CallContext context = new TestCallContext("PaymentTests");
-    
+    private static final CallContext context = new TestCallContext("PaymentTests");
+
     private PaymentDao paymentDao;
     private MysqlTestingHelper helper;
     private IDBI dbi;
     private Clock clock;
-    
-    @BeforeSuite(groups = { "slow"})
+
+    @BeforeSuite(groups = {"slow"})
     public void startMysql() throws IOException {
         final String paymentddl = IOUtils.toString(MysqlTestingHelper.class.getResourceAsStream("/com/ning/billing/payment/ddl.sql"));
         final String utilddl = IOUtils.toString(MysqlTestingHelper.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
 
-        
         clock = new DefaultClock();
-        
+
         setupDb();
-        
+
         helper.startMysql();
         helper.initDb(paymentddl);
         helper.initDb(utilddl);
 
         paymentDao = new AuditedPaymentDao(dbi, null);
     }
-    
+
     private void setupDb() {
         helper = new MysqlTestingHelper();
         if (helper.isUsingLocalInstance()) {
             final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
-            DBIProvider provider = new DBIProvider(config);
+            final DBIProvider provider = new DBIProvider(config);
             dbi = provider.get();
         } else {
             dbi = helper.getDBI();
         }
     }
 
-    @AfterSuite(groups = { "slow"})
+    @AfterSuite(groups = {"slow"})
     public void stopMysql() {
         helper.stopMysql();
     }
-    
-    @BeforeTest(groups = { "slow"})
+
+    @BeforeTest(groups = {"slow"})
     public void cleanupDb() {
         helper.cleanupAllTables();
     }
-    
- 
-    
-    @Test(groups={"slow"})
+
+
+    @Test(groups = {"slow"})
     public void testUpdateStatus() {
-        
-        UUID accountId = UUID.randomUUID();
-        UUID invoiceId = UUID.randomUUID(); 
-        BigDecimal amount = new BigDecimal(13);
-        Currency currency = Currency.USD;
-        DateTime effectiveDate = clock.getUTCNow();
-        
-        PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, amount, currency, effectiveDate);
-        PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
+
+        final UUID accountId = UUID.randomUUID();
+        final UUID invoiceId = UUID.randomUUID();
+        final BigDecimal amount = new BigDecimal(13);
+        final Currency currency = Currency.USD;
+        final DateTime effectiveDate = clock.getUTCNow();
+
+        final PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, amount, currency, effectiveDate);
+        final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
         PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, true, context);
-        
-        PaymentStatus paymentStatus = PaymentStatus.SUCCESS;
-        String paymentError = "No error";
-        
+
+        final PaymentStatus paymentStatus = PaymentStatus.SUCCESS;
+        final String paymentError = "No error";
+
         paymentDao.updateStatusForPaymentWithAttempt(payment.getId(), paymentStatus, paymentError, attempt.getId(), context);
-        
-        List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId);
+
+        final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId);
         assertEquals(payments.size(), 1);
         savedPayment = payments.get(0);
         assertEquals(savedPayment.getId(), payment.getId());
-        assertEquals(savedPayment.getAccountId(), accountId);        
-        assertEquals(savedPayment.getInvoiceId(), invoiceId);        
-        assertEquals(savedPayment.getPaymentMethodId(), null);         
-        assertEquals(savedPayment.getAmount().compareTo(amount), 0);        
-        assertEquals(savedPayment.getCurrency(), currency);         
-        assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0); 
-        assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.SUCCESS); 
-        
-        List<PaymentAttemptModelDao> attempts =  paymentDao.getAttemptsForPayment(payment.getId());
+        assertEquals(savedPayment.getAccountId(), accountId);
+        assertEquals(savedPayment.getInvoiceId(), invoiceId);
+        assertEquals(savedPayment.getPaymentMethodId(), null);
+        assertEquals(savedPayment.getAmount().compareTo(amount), 0);
+        assertEquals(savedPayment.getCurrency(), currency);
+        assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
+        assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.SUCCESS);
+
+        final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId());
         assertEquals(attempts.size(), 1);
-        PaymentAttemptModelDao savedAttempt = attempts.get(0);
+        final PaymentAttemptModelDao savedAttempt = attempts.get(0);
         assertEquals(savedAttempt.getId(), attempt.getId());
         assertEquals(savedAttempt.getPaymentId(), payment.getId());
         assertEquals(savedAttempt.getAccountId(), accountId);
-        assertEquals(savedAttempt.getInvoiceId(), invoiceId); 
+        assertEquals(savedAttempt.getInvoiceId(), invoiceId);
         assertEquals(savedAttempt.getPaymentStatus(), PaymentStatus.SUCCESS);
-        assertEquals(savedAttempt.getPaymentError(), paymentError); 
-        assertEquals(savedAttempt.getRequestedAmount().compareTo(amount), 0);                
+        assertEquals(savedAttempt.getPaymentError(), paymentError);
+        assertEquals(savedAttempt.getRequestedAmount().compareTo(amount), 0);
     }
-    
-    @Test(groups={"slow"})
+
+    @Test(groups = {"slow"})
     public void testPaymentWithAttempt() {
-        
-        UUID accountId = UUID.randomUUID();
-        UUID invoiceId = UUID.randomUUID(); 
-        BigDecimal amount = new BigDecimal(13);
-        Currency currency = Currency.USD;
-        DateTime effectiveDate = clock.getUTCNow();
-        
-        PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, amount, currency, effectiveDate);
-        PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
-        
-        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt,true, context);
+
+        final UUID accountId = UUID.randomUUID();
+        final UUID invoiceId = UUID.randomUUID();
+        final BigDecimal amount = new BigDecimal(13);
+        final Currency currency = Currency.USD;
+        final DateTime effectiveDate = clock.getUTCNow();
+
+        final PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, amount, currency, effectiveDate);
+        final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
+
+        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, true, context);
         assertEquals(savedPayment.getId(), payment.getId());
-        assertEquals(savedPayment.getAccountId(), accountId);        
-        assertEquals(savedPayment.getInvoiceId(), invoiceId);        
-        assertEquals(savedPayment.getPaymentMethodId(), null);         
-        assertEquals(savedPayment.getAmount().compareTo(amount), 0);        
-        assertEquals(savedPayment.getCurrency(), currency);         
-        assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0); 
-        assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.UNKNOWN); 
-
-        
+        assertEquals(savedPayment.getAccountId(), accountId);
+        assertEquals(savedPayment.getInvoiceId(), invoiceId);
+        assertEquals(savedPayment.getPaymentMethodId(), null);
+        assertEquals(savedPayment.getAmount().compareTo(amount), 0);
+        assertEquals(savedPayment.getCurrency(), currency);
+        assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
+        assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.UNKNOWN);
+
+
         PaymentAttemptModelDao savedAttempt = paymentDao.getPaymentAttempt(attempt.getId());
         assertEquals(savedAttempt.getId(), attempt.getId());
         assertEquals(savedAttempt.getPaymentId(), payment.getId());
         assertEquals(savedAttempt.getAccountId(), accountId);
-        assertEquals(savedAttempt.getInvoiceId(), invoiceId); 
+        assertEquals(savedAttempt.getInvoiceId(), invoiceId);
         assertEquals(savedAttempt.getPaymentStatus(), PaymentStatus.UNKNOWN);
 
-        List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId);
+        final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId);
         assertEquals(payments.size(), 1);
         savedPayment = payments.get(0);
         assertEquals(savedPayment.getId(), payment.getId());
-        assertEquals(savedPayment.getAccountId(), accountId);        
-        assertEquals(savedPayment.getInvoiceId(), invoiceId);        
-        assertEquals(savedPayment.getPaymentMethodId(), null);         
-        assertEquals(savedPayment.getAmount().compareTo(amount), 0);        
-        assertEquals(savedPayment.getCurrency(), currency);         
-        assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0); 
-        assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.UNKNOWN); 
-        
-        List<PaymentAttemptModelDao> attempts =  paymentDao.getAttemptsForPayment(payment.getId());
+        assertEquals(savedPayment.getAccountId(), accountId);
+        assertEquals(savedPayment.getInvoiceId(), invoiceId);
+        assertEquals(savedPayment.getPaymentMethodId(), null);
+        assertEquals(savedPayment.getAmount().compareTo(amount), 0);
+        assertEquals(savedPayment.getCurrency(), currency);
+        assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
+        assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.UNKNOWN);
+
+        final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId());
         assertEquals(attempts.size(), 1);
         savedAttempt = attempts.get(0);
         assertEquals(savedAttempt.getId(), attempt.getId());
         assertEquals(savedAttempt.getPaymentId(), payment.getId());
         assertEquals(savedAttempt.getAccountId(), accountId);
-        assertEquals(savedAttempt.getInvoiceId(), invoiceId); 
+        assertEquals(savedAttempt.getInvoiceId(), invoiceId);
         assertEquals(savedAttempt.getPaymentStatus(), PaymentStatus.UNKNOWN);
-        
+
     }
-    
-    @Test(groups={"slow"})
+
+    @Test(groups = {"slow"})
     public void testNewAttempt() {
-        UUID accountId = UUID.randomUUID();
-        UUID invoiceId = UUID.randomUUID(); 
-        BigDecimal amount = new BigDecimal(13);
-        Currency currency = Currency.USD;
-        DateTime effectiveDate = clock.getUTCNow();
-        
-        PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, amount, currency, effectiveDate);
-        PaymentAttemptModelDao firstAttempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
-        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, firstAttempt, true,context);
-        
-        BigDecimal newAmount = new BigDecimal(15.23).setScale(2, RoundingMode.HALF_EVEN);
-        PaymentAttemptModelDao secondAttempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), newAmount);        
+        final UUID accountId = UUID.randomUUID();
+        final UUID invoiceId = UUID.randomUUID();
+        final BigDecimal amount = new BigDecimal(13);
+        final Currency currency = Currency.USD;
+        final DateTime effectiveDate = clock.getUTCNow();
+
+        final PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, amount, currency, effectiveDate);
+        final PaymentAttemptModelDao firstAttempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
+        PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, firstAttempt, true, context);
+
+        final BigDecimal newAmount = new BigDecimal(15.23).setScale(2, RoundingMode.HALF_EVEN);
+        final PaymentAttemptModelDao secondAttempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), newAmount);
         paymentDao.insertNewAttemptForPayment(payment.getId(), secondAttempt, true, context);
-        
-        List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId);
+
+        final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId);
         assertEquals(payments.size(), 1);
         savedPayment = payments.get(0);
         assertEquals(savedPayment.getId(), payment.getId());
-        assertEquals(savedPayment.getAccountId(), accountId);        
-        assertEquals(savedPayment.getInvoiceId(), invoiceId);        
-        assertEquals(savedPayment.getPaymentMethodId(), null);         
-        assertEquals(savedPayment.getAmount().compareTo(newAmount), 0);        
-        assertEquals(savedPayment.getCurrency(), currency);         
-        assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0); 
-        assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.UNKNOWN); 
-
-        List<PaymentAttemptModelDao> attempts =  paymentDao.getAttemptsForPayment(payment.getId());
+        assertEquals(savedPayment.getAccountId(), accountId);
+        assertEquals(savedPayment.getInvoiceId(), invoiceId);
+        assertEquals(savedPayment.getPaymentMethodId(), null);
+        assertEquals(savedPayment.getAmount().compareTo(newAmount), 0);
+        assertEquals(savedPayment.getCurrency(), currency);
+        assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
+        assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.UNKNOWN);
+
+        final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId());
         assertEquals(attempts.size(), 2);
-        PaymentAttemptModelDao savedAttempt1 = attempts.get(0);
+        final PaymentAttemptModelDao savedAttempt1 = attempts.get(0);
         assertEquals(savedAttempt1.getPaymentId(), payment.getId());
         assertEquals(savedAttempt1.getAccountId(), accountId);
-        assertEquals(savedAttempt1.getInvoiceId(), invoiceId); 
+        assertEquals(savedAttempt1.getInvoiceId(), invoiceId);
         assertEquals(savedAttempt1.getPaymentStatus(), PaymentStatus.UNKNOWN);
-        assertEquals(savedAttempt1.getPaymentError(), null); 
-        assertEquals(savedAttempt1.getRequestedAmount().compareTo(amount), 0);        
+        assertEquals(savedAttempt1.getPaymentError(), null);
+        assertEquals(savedAttempt1.getRequestedAmount().compareTo(amount), 0);
 
-    
-        PaymentAttemptModelDao savedAttempt2 = attempts.get(1);
+
+        final PaymentAttemptModelDao savedAttempt2 = attempts.get(1);
         assertEquals(savedAttempt2.getPaymentId(), payment.getId());
         assertEquals(savedAttempt2.getAccountId(), accountId);
-        assertEquals(savedAttempt2.getInvoiceId(), invoiceId); 
+        assertEquals(savedAttempt2.getInvoiceId(), invoiceId);
         assertEquals(savedAttempt2.getPaymentStatus(), PaymentStatus.UNKNOWN);
-        assertEquals(savedAttempt2.getPaymentError(), null); 
-        assertEquals(savedAttempt2.getRequestedAmount().compareTo(newAmount), 0);        
-}
-    @Test(groups={"slow"})
+        assertEquals(savedAttempt2.getPaymentError(), null);
+        assertEquals(savedAttempt2.getRequestedAmount().compareTo(newAmount), 0);
+    }
+
+    @Test(groups = {"slow"})
     public void testPaymentMethod() {
-        
-        UUID paymentMethodId = UUID.randomUUID();
-        UUID accountId = UUID.randomUUID();
-        String pluginName = "nobody";
-        Boolean isActive = Boolean.TRUE;
-        String externalPaymentId = UUID.randomUUID().toString();
-        
-        PaymentMethodModelDao method = new PaymentMethodModelDao(paymentMethodId, accountId, pluginName, isActive, externalPaymentId);
-        
+
+        final UUID paymentMethodId = UUID.randomUUID();
+        final UUID accountId = UUID.randomUUID();
+        final String pluginName = "nobody";
+        final Boolean isActive = Boolean.TRUE;
+        final String externalPaymentId = UUID.randomUUID().toString();
+
+        final PaymentMethodModelDao method = new PaymentMethodModelDao(paymentMethodId, accountId, pluginName, isActive, externalPaymentId);
+
         PaymentMethodModelDao savedMethod = paymentDao.insertPaymentMethod(method, context);
         assertEquals(savedMethod.getId(), paymentMethodId);
-        assertEquals(savedMethod.getAccountId(), accountId);        
+        assertEquals(savedMethod.getAccountId(), accountId);
         assertEquals(savedMethod.getPluginName(), pluginName);
         assertEquals(savedMethod.isActive(), isActive);
-        
-        List<PaymentMethodModelDao> result =  paymentDao.getPaymentMethods(accountId);
+
+        final List<PaymentMethodModelDao> result = paymentDao.getPaymentMethods(accountId);
         assertEquals(result.size(), 1);
         savedMethod = result.get(0);
         assertEquals(savedMethod.getId(), paymentMethodId);
-        assertEquals(savedMethod.getAccountId(), accountId);        
+        assertEquals(savedMethod.getAccountId(), accountId);
         assertEquals(savedMethod.getPluginName(), pluginName);
         assertEquals(savedMethod.isActive(), isActive);
         assertEquals(savedMethod.getExternalId(), externalPaymentId);
-        
+
         paymentDao.deletedPaymentMethod(paymentMethodId);
-        
-        PaymentMethodModelDao deletedPaymentMethod = paymentDao.getPaymentMethod(paymentMethodId);
+
+        final PaymentMethodModelDao deletedPaymentMethod = paymentDao.getPaymentMethod(paymentMethodId);
         assertNull(deletedPaymentMethod);
-        
-        
+
+
     }
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithEmbeddedDb.java b/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithEmbeddedDb.java
index 4cf7981..4937184 100644
--- a/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithEmbeddedDb.java
+++ b/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithEmbeddedDb.java
@@ -17,17 +17,11 @@
 package com.ning.billing.payment.glue;
 
 import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.commons.collections.MapUtils;
-
-import com.google.common.collect.ImmutableMap;
 import com.google.inject.Provider;
 import com.ning.billing.config.PaymentConfig;
-import com.ning.billing.junction.api.BillingApi;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
-import com.ning.billing.payment.glue.PaymentModule;
 import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.bus.Bus;
@@ -38,32 +32,18 @@ import com.ning.billing.util.notificationq.NotificationQueueService;
 import com.ning.billing.util.tag.Tag;
 
 public class PaymentTestModuleWithEmbeddedDb extends PaymentModule {
-    /*
-	public static class MockProvider implements Provider<BillingApi> {
-		@Override
-		public BillingApi get() {
-			return BrainDeadProxyFactory.createBrainDeadProxyFor(BillingApi.class);
-		}
-
-	}
-	*/
-
     public static class MockTagApiProvider implements Provider<TagUserApi> {
-
         @Override
         public TagUserApi get() {
-            TagUserApi api = BrainDeadProxyFactory.createBrainDeadProxyFor(TagUserApi.class);
+            final TagUserApi api = BrainDeadProxyFactory.createBrainDeadProxyFor(TagUserApi.class);
             ((ZombieControl) api).addResult("getTags", new HashMap<String, Tag>());
             return api;
         }
-        
-    }
-	public PaymentTestModuleWithEmbeddedDb() {
-        super(MapUtils.toProperties(ImmutableMap.of("killbill.payment.provider.default", "my-mock")));
+
     }
 
     @Override
-    protected void installPaymentProviderPlugins(PaymentConfig config) {
+    protected void installPaymentProviderPlugins(final PaymentConfig config) {
         install(new MockPaymentProviderPluginModule("my-mock"));
     }
 
diff --git a/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java b/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java
index 7f39f8c..ca497f6 100644
--- a/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java
+++ b/payment/src/test/java/com/ning/billing/payment/glue/PaymentTestModuleWithMocks.java
@@ -16,66 +16,69 @@
 
 package com.ning.billing.payment.glue;
 
-import static org.testng.Assert.assertNotNull;
-
 import java.io.IOException;
 import java.net.URL;
+import java.util.Map;
 import java.util.Properties;
 
-import org.apache.commons.collections.MapUtils;
+import org.skife.config.ConfigSource;
+import org.skife.config.SimplePropertyConfigSource;
 
-import com.google.common.collect.ImmutableMap;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.mock.glue.MockInvoiceModule;
 import com.ning.billing.mock.glue.MockNotificationQueueModule;
 import com.ning.billing.mock.glue.TestDbiModule;
 import com.ning.billing.payment.dao.MockPaymentDao;
 import com.ning.billing.payment.dao.PaymentDao;
-import com.ning.billing.payment.glue.PaymentModule;
 import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
 import com.ning.billing.util.globallocker.GlobalLocker;
 import com.ning.billing.util.globallocker.MockGlobalLocker;
 import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.BusModule.BusType;
-
 import com.ning.billing.util.glue.TagStoreModule;
 
+import static org.testng.Assert.assertNotNull;
+
 public class PaymentTestModuleWithMocks extends PaymentModule {
-    /*
-	public static class MockProvider implements Provider<BillingApi> {
-		@Override
-		public BillingApi get() {
-			return BrainDeadProxyFactory.createBrainDeadProxyFor(BillingApi.class);
-		}
-
-	}
-	*/
-
-    public final static String PLUGIN_TEST_NAME = "my-mock";
-    
+    public static final String PLUGIN_TEST_NAME = "my-mock";
+
     private void loadSystemPropertiesFromClasspath(final String resource) {
         final URL url = PaymentTestModuleWithMocks.class.getResource(resource);
         assertNotNull(url);
 
         try {
-            props.load(url.openStream());
+            final Properties properties = System.getProperties();
+            properties.load(url.openStream());
+
+            properties.setProperty("killbill.payment.provider.default", PLUGIN_TEST_NAME);
+            properties.setProperty("killbill.payment.engine.events.off", "false");
+
+            configSource = new SimplePropertyConfigSource(properties);
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
     }
-    
-    public PaymentTestModuleWithMocks() {
-        super(MapUtils.toProperties(ImmutableMap.of("killbill.payment.provider.default", PLUGIN_TEST_NAME,
-                "killbill.payment.engine.events.off", "false")));
+
+    private static final class MapConfigSource implements ConfigSource {
+        private final Map<String, String> map;
+
+        private MapConfigSource(final Map<String, String> map) {
+            this.map = map;
+        }
+
+        @Override
+        public String getString(final String propertyName) {
+            return map.get(propertyName);
+        }
     }
 
     @Override
     protected void installPaymentDao() {
-       bind(PaymentDao.class).to(MockPaymentDao.class).asEagerSingleton();
+        bind(PaymentDao.class).to(MockPaymentDao.class).asEagerSingleton();
     }
 
     @Override
-    protected void installPaymentProviderPlugins(PaymentConfig config) {
+    protected void installPaymentProviderPlugins(final PaymentConfig config) {
         install(new MockPaymentProviderPluginModule(PLUGIN_TEST_NAME));
     }
 
diff --git a/payment/src/test/java/com/ning/billing/payment/MockInvoice.java b/payment/src/test/java/com/ning/billing/payment/MockInvoice.java
index 802b49a..9cabab5 100644
--- a/payment/src/test/java/com/ning/billing/payment/MockInvoice.java
+++ b/payment/src/test/java/com/ning/billing/payment/MockInvoice.java
@@ -16,19 +16,18 @@
 
 package com.ning.billing.payment;
 
+import javax.annotation.Nullable;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-import javax.annotation.Nullable;
-
-import com.ning.billing.invoice.api.InvoiceItemType;
 import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.util.entity.EntityBase;
 
@@ -43,13 +42,13 @@ public class MockInvoice extends EntityBase implements Invoice {
     private final boolean migrationInvoice;
 
     // used to create a new invoice
-    public MockInvoice(UUID accountId, DateTime invoiceDate, DateTime targetDate, Currency currency) {
+    public MockInvoice(final UUID accountId, final DateTime invoiceDate, final DateTime targetDate, final Currency currency) {
         this(UUID.randomUUID(), accountId, null, invoiceDate, targetDate, currency, false);
     }
 
     // used to hydrate invoice from persistence layer
-    public MockInvoice(UUID invoiceId, UUID accountId, @Nullable Integer invoiceNumber, DateTime invoiceDate,
-                          DateTime targetDate, Currency currency, boolean isMigrationInvoice) {
+    public MockInvoice(final UUID invoiceId, final UUID accountId, @Nullable final Integer invoiceNumber, final DateTime invoiceDate,
+                       final DateTime targetDate, final Currency currency, final boolean isMigrationInvoice) {
         super(invoiceId);
         this.accountId = accountId;
         this.invoiceNumber = invoiceNumber;
@@ -75,10 +74,10 @@ public class MockInvoice extends EntityBase implements Invoice {
     }
 
     @Override
-    public <T extends InvoiceItem> List<InvoiceItem> getInvoiceItems(Class<T> clazz) {
-        List<InvoiceItem> results = new ArrayList<InvoiceItem>();
-        for (InvoiceItem item : invoiceItems) {
-            if ( clazz.isInstance(item) ) {
+    public <T extends InvoiceItem> List<InvoiceItem> getInvoiceItems(final Class<T> clazz) {
+        final List<InvoiceItem> results = new ArrayList<InvoiceItem>();
+        for (final InvoiceItem item : invoiceItems) {
+            if (clazz.isInstance(item)) {
                 results.add(item);
             }
         }
@@ -122,6 +121,7 @@ public class MockInvoice extends EntityBase implements Invoice {
 
     /**
      * null until retrieved from the database
+     *
      * @return the invoice number
      */
     @Override
@@ -143,18 +143,18 @@ public class MockInvoice extends EntityBase implements Invoice {
     public Currency getCurrency() {
         return currency;
     }
-    
+
     @Override
     public boolean isMigrationInvoice() {
-		return migrationInvoice;
-	}
+        return migrationInvoice;
+    }
 
-	@Override
+    @Override
     public DateTime getLastPaymentAttempt() {
         DateTime lastPaymentAttempt = null;
 
         for (final InvoicePayment paymentAttempt : payments) {
-            DateTime paymentAttemptDate = paymentAttempt.getPaymentAttemptDate();
+            final DateTime paymentAttemptDate = paymentAttempt.getPaymentAttemptDate();
             if (lastPaymentAttempt == null) {
                 lastPaymentAttempt = paymentAttemptDate;
             }
@@ -181,8 +181,8 @@ public class MockInvoice extends EntityBase implements Invoice {
     @Override
     public BigDecimal getAmountCharged() {
         BigDecimal result = BigDecimal.ZERO;
-    
-        for(InvoiceItem i : invoiceItems) {
+
+        for (final InvoiceItem i : invoiceItems) {
             if (!i.getInvoiceItemType().equals(InvoiceItemType.CREDIT)) {
                 result = result.add(i.getAmount());
             }
@@ -194,7 +194,7 @@ public class MockInvoice extends EntityBase implements Invoice {
     public BigDecimal getAmountCredited() {
         BigDecimal result = BigDecimal.ZERO;
 
-        for(InvoiceItem i : invoiceItems) {
+        for (final InvoiceItem i : invoiceItems) {
             if (i.getInvoiceItemType().equals(InvoiceItemType.CREDIT)) {
                 result = result.add(i.getAmount());
             }
@@ -213,7 +213,7 @@ public class MockInvoice extends EntityBase implements Invoice {
             return false;
         }
 
-        DateTime lastPaymentAttempt = getLastPaymentAttempt();
+        final DateTime lastPaymentAttempt = getLastPaymentAttempt();
         if (lastPaymentAttempt == null) {
             return true;
         }
diff --git a/payment/src/test/java/com/ning/billing/payment/MockInvoiceCreationEvent.java b/payment/src/test/java/com/ning/billing/payment/MockInvoiceCreationEvent.java
index da9b6ab..3b17037 100644
--- a/payment/src/test/java/com/ning/billing/payment/MockInvoiceCreationEvent.java
+++ b/payment/src/test/java/com/ning/billing/payment/MockInvoiceCreationEvent.java
@@ -19,16 +19,16 @@ package com.ning.billing.payment;
 import java.math.BigDecimal;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import org.joda.time.DateTime;
-
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.InvoiceCreationEvent;
 
 public class MockInvoiceCreationEvent implements InvoiceCreationEvent {
-	
+
     private final UUID invoiceId;
     private final UUID accountId;
     private final BigDecimal amountOwed;
@@ -37,12 +37,12 @@ public class MockInvoiceCreationEvent implements InvoiceCreationEvent {
     private final UUID userToken;
 
     @JsonCreator
-    public MockInvoiceCreationEvent(@JsonProperty("invoiceId") UUID invoiceId,
-            @JsonProperty("accountId") UUID accountId,
-            @JsonProperty("amountOwed") BigDecimal amountOwed,
-            @JsonProperty("currency") Currency currency,
-            @JsonProperty("invoiceCreationDate") DateTime invoiceCreationDate,
-            @JsonProperty("userToken") UUID userToken) {
+    public MockInvoiceCreationEvent(@JsonProperty("invoiceId") final UUID invoiceId,
+                                    @JsonProperty("accountId") final UUID accountId,
+                                    @JsonProperty("amountOwed") final BigDecimal amountOwed,
+                                    @JsonProperty("currency") final Currency currency,
+                                    @JsonProperty("invoiceCreationDate") final DateTime invoiceCreationDate,
+                                    @JsonProperty("userToken") final UUID userToken) {
         this.invoiceId = invoiceId;
         this.accountId = accountId;
         this.amountOwed = amountOwed;
@@ -52,15 +52,15 @@ public class MockInvoiceCreationEvent implements InvoiceCreationEvent {
     }
 
     @JsonIgnore
-	@Override
-	public BusEventType getBusEventType() {
-		return BusEventType.INVOICE_CREATION;
-	}
+    @Override
+    public BusEventType getBusEventType() {
+        return BusEventType.INVOICE_CREATION;
+    }
 
-	@Override
-	public UUID getUserToken() {
-		return userToken;
-	}
+    @Override
+    public UUID getUserToken() {
+        return userToken;
+    }
 
     @Override
     public UUID getInvoiceId() {
@@ -105,7 +105,7 @@ public class MockInvoiceCreationEvent implements InvoiceCreationEvent {
         result = prime
                 * result
                 + ((invoiceCreationDate == null) ? 0 : invoiceCreationDate
-                        .hashCode());
+                .hashCode());
         result = prime * result
                 + ((invoiceId == null) ? 0 : invoiceId.hashCode());
         result = prime * result
@@ -114,43 +114,57 @@ public class MockInvoiceCreationEvent implements InvoiceCreationEvent {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        MockInvoiceCreationEvent other = (MockInvoiceCreationEvent) obj;
+        }
+        final MockInvoiceCreationEvent other = (MockInvoiceCreationEvent) obj;
         if (accountId == null) {
-            if (other.accountId != null)
+            if (other.accountId != null) {
                 return false;
-        } else if (!accountId.equals(other.accountId))
+            }
+        } else if (!accountId.equals(other.accountId)) {
             return false;
+        }
         if (amountOwed == null) {
-            if (other.amountOwed != null)
+            if (other.amountOwed != null) {
                 return false;
-        } else if (!amountOwed.equals(other.amountOwed))
+            }
+        } else if (!amountOwed.equals(other.amountOwed)) {
             return false;
-        if (currency != other.currency)
+        }
+        if (currency != other.currency) {
             return false;
+        }
         if (invoiceCreationDate == null) {
-            if (other.invoiceCreationDate != null)
+            if (other.invoiceCreationDate != null) {
                 return false;
-        } else if (invoiceCreationDate.compareTo(other.invoiceCreationDate) != 0)
+            }
+        } else if (invoiceCreationDate.compareTo(other.invoiceCreationDate) != 0) {
             return false;
+        }
         if (invoiceId == null) {
-            if (other.invoiceId != null)
+            if (other.invoiceId != null) {
                 return false;
-        } else if (!invoiceId.equals(other.invoiceId))
+            }
+        } else if (!invoiceId.equals(other.invoiceId)) {
             return false;
+        }
         if (userToken == null) {
-            if (other.userToken != null)
+            if (other.userToken != null) {
                 return false;
-        } else if (!userToken.equals(other.userToken))
+            }
+        } else if (!userToken.equals(other.userToken)) {
             return false;
+        }
         return true;
     }
-    
-    
+
+
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/MockRecurringInvoiceItem.java b/payment/src/test/java/com/ning/billing/payment/MockRecurringInvoiceItem.java
index e55c7e4..534bfb2 100644
--- a/payment/src/test/java/com/ning/billing/payment/MockRecurringInvoiceItem.java
+++ b/payment/src/test/java/com/ning/billing/payment/MockRecurringInvoiceItem.java
@@ -16,19 +16,17 @@
 
 package com.ning.billing.payment;
 
+import javax.annotation.Nullable;
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.util.entity.EntityBase;
 
-import org.apache.commons.lang.NotImplementedException;
-import org.joda.time.DateTime;
-
-import java.math.BigDecimal;
-import java.util.UUID;
-
-import javax.annotation.Nullable;
-
 public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem {
     private final BigDecimal rate;
     private final UUID reversedItemId;
@@ -44,46 +42,47 @@ public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem 
     protected final Currency currency;
 
 
-    public MockRecurringInvoiceItem(UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
-                                DateTime startDate, DateTime endDate,
-                                BigDecimal amount, BigDecimal rate,
-                                Currency currency) { 
+    public MockRecurringInvoiceItem(final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId, final String planName, final String phaseName,
+                                    final DateTime startDate, final DateTime endDate,
+                                    final BigDecimal amount, final BigDecimal rate,
+                                    final Currency currency) {
         this(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, rate, null);
 
     }
 
-    public MockRecurringInvoiceItem(UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
-                                DateTime startDate, DateTime endDate,
-                                BigDecimal amount, BigDecimal rate,
-                                Currency currency, UUID reversedItemId) {
+    public MockRecurringInvoiceItem(final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId, final String planName, final String phaseName,
+                                    final DateTime startDate, final DateTime endDate,
+                                    final BigDecimal amount, final BigDecimal rate,
+                                    final Currency currency, final UUID reversedItemId) {
         this(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate,
-                amount, currency, rate, reversedItemId);
+             amount, currency, rate, reversedItemId);
     }
 
-    public MockRecurringInvoiceItem(UUID id, UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
-                                DateTime startDate, DateTime endDate,
-                                BigDecimal amount, BigDecimal rate,
-                                Currency currency) {
+    public MockRecurringInvoiceItem(final UUID id, final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId, final String planName, final String phaseName,
+                                    final DateTime startDate, final DateTime endDate,
+                                    final BigDecimal amount, final BigDecimal rate,
+                                    final Currency currency) {
         this(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, rate, null);
 
     }
 
-    public MockRecurringInvoiceItem(UUID id, UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
-                                DateTime startDate, DateTime endDate,
-                                BigDecimal amount, BigDecimal rate,
-                                Currency currency, UUID reversedItemId) {
+    public MockRecurringInvoiceItem(final UUID id, final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId, final String planName, final String phaseName,
+                                    final DateTime startDate, final DateTime endDate,
+                                    final BigDecimal amount, final BigDecimal rate,
+                                    final Currency currency, final UUID reversedItemId) {
         this(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, rate, reversedItemId);
     }
-    public MockRecurringInvoiceItem(UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
-            DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency, BigDecimal rate, UUID reversedItemId){
+
+    public MockRecurringInvoiceItem(final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId, final String planName, final String phaseName,
+                                    final DateTime startDate, final DateTime endDate, final BigDecimal amount, final Currency currency, final BigDecimal rate, final UUID reversedItemId) {
         this(UUID.randomUUID(), invoiceId, accountId, bundleId, subscriptionId, planName, phaseName,
-                startDate, endDate, amount, currency, rate, reversedItemId);
+             startDate, endDate, amount, currency, rate, reversedItemId);
     }
 
 
-    public MockRecurringInvoiceItem(UUID id, UUID invoiceId, UUID accountId, @Nullable UUID bundleId, @Nullable UUID subscriptionId, String planName, String phaseName,
-            DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
-            BigDecimal rate, UUID reversedItemId) {
+    public MockRecurringInvoiceItem(final UUID id, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId, @Nullable final UUID subscriptionId, final String planName, final String phaseName,
+                                    final DateTime startDate, final DateTime endDate, final BigDecimal amount, final Currency currency,
+                                    final BigDecimal rate, final UUID reversedItemId) {
         super(id);
         this.invoiceId = invoiceId;
         this.accountId = accountId;
@@ -113,7 +112,7 @@ public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem 
     public UUID getBundleId() {
         return bundleId;
     }
-    
+
     public UUID getAccountId() {
         return accountId;
     }
@@ -160,7 +159,7 @@ public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem 
 
     @Override
     public InvoiceItem asReversingItem() {
-        throw new NotImplementedException();
+        throw new UnsupportedOperationException();
     }
 
     @Override
@@ -181,7 +180,7 @@ public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem 
     }
 
     @Override
-    public int compareTo(InvoiceItem item) {
+    public int compareTo(final InvoiceItem item) {
         if (item == null) {
             return -1;
         }
@@ -189,15 +188,15 @@ public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem 
             return -1;
         }
 
-        MockRecurringInvoiceItem that = (MockRecurringInvoiceItem) item;
-        int compareAccounts = getAccountId().compareTo(that.getAccountId());
+        final MockRecurringInvoiceItem that = (MockRecurringInvoiceItem) item;
+        final int compareAccounts = getAccountId().compareTo(that.getAccountId());
         if (compareAccounts == 0 && bundleId != null) {
-            int compareBundles = getBundleId().compareTo(that.getBundleId());
+            final int compareBundles = getBundleId().compareTo(that.getBundleId());
             if (compareBundles == 0 && subscriptionId != null) {
 
-                int compareSubscriptions = getSubscriptionId().compareTo(that.getSubscriptionId());
+                final int compareSubscriptions = getSubscriptionId().compareTo(that.getSubscriptionId());
                 if (compareSubscriptions == 0) {
-                    int compareStartDates = getStartDate().compareTo(that.getStartDate());
+                    final int compareStartDates = getStartDate().compareTo(that.getStartDate());
                     if (compareStartDates == 0) {
                         return getEndDate().compareTo(that.getEndDate());
                     } else {
@@ -215,26 +214,49 @@ public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem 
     }
 
     @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        MockRecurringInvoiceItem that = (MockRecurringInvoiceItem) o;
-
-        if (accountId.compareTo(that.accountId) != 0) return false;
-        if (amount.compareTo(that.amount) != 0) return false;
-        if (currency != that.currency) return false;
-        if (startDate.compareTo(that.startDate) != 0) return false;
-        if (endDate.compareTo(that.endDate) != 0) return false;
-        if (!phaseName.equals(that.phaseName)) return false;
-        if (!planName.equals(that.planName)) return false;
-        if (rate.compareTo(that.rate) != 0) return false;
-        if (reversedItemId != null ? !reversedItemId.equals(that.reversedItemId) : that.reversedItemId != null)
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
             return false;
-        if (subscriptionId != null ? !subscriptionId.equals(that.subscriptionId) : that.subscriptionId != null)
+        }
+
+        final MockRecurringInvoiceItem that = (MockRecurringInvoiceItem) o;
+
+        if (accountId.compareTo(that.accountId) != 0) {
             return false;
-        if (bundleId != null ? !bundleId.equals(that.bundleId) : that.bundleId != null)
+        }
+        if (amount.compareTo(that.amount) != 0) {
             return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (startDate.compareTo(that.startDate) != 0) {
+            return false;
+        }
+        if (endDate.compareTo(that.endDate) != 0) {
+            return false;
+        }
+        if (!phaseName.equals(that.phaseName)) {
+            return false;
+        }
+        if (!planName.equals(that.planName)) {
+            return false;
+        }
+        if (rate.compareTo(that.rate) != 0) {
+            return false;
+        }
+        if (reversedItemId != null ? !reversedItemId.equals(that.reversedItemId) : that.reversedItemId != null) {
+            return false;
+        }
+        if (subscriptionId != null ? !subscriptionId.equals(that.subscriptionId) : that.subscriptionId != null) {
+            return false;
+        }
+        if (bundleId != null ? !bundleId.equals(that.bundleId) : that.bundleId != null) {
+            return false;
+        }
 
         return true;
     }
@@ -257,7 +279,7 @@ public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem 
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
+        final StringBuilder sb = new StringBuilder();
 
         sb.append(phaseName).append(", ");
         sb.append(startDate.toString()).append(", ");
diff --git a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
index 6d9cc1a..c26211b 100644
--- a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
+++ b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
@@ -21,9 +21,9 @@ import com.ning.billing.payment.plugin.api.PaymentPluginApi;
 import com.ning.billing.util.clock.Clock;
 
 public class MockPaymentProviderPlugin extends DefaultNoOpPaymentProviderPlugin implements PaymentPluginApi {
-    
+
     @Inject
-    public MockPaymentProviderPlugin(Clock clock) {
+    public MockPaymentProviderPlugin(final Clock clock) {
         super(clock);
     }
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginModule.java b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginModule.java
index 441fcf8..565bd81 100644
--- a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginModule.java
+++ b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginModule.java
@@ -22,15 +22,15 @@ import com.google.inject.name.Names;
 public class MockPaymentProviderPluginModule extends AbstractModule {
     private final String instanceName;
 
-    public MockPaymentProviderPluginModule(String instanceName) {
+    public MockPaymentProviderPluginModule(final String instanceName) {
         this.instanceName = instanceName;
     }
 
     @Override
     protected void configure() {
         bind(MockPaymentProviderPlugin.class)
-            .annotatedWith(Names.named(instanceName))
-            .toProvider(new MockPaymentProviderPluginProvider(instanceName))
-            .asEagerSingleton();
+                .annotatedWith(Names.named(instanceName))
+                .toProvider(new MockPaymentProviderPluginProvider(instanceName))
+                .asEagerSingleton();
     }
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginProvider.java b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginProvider.java
index fa778e9..63efaf7 100644
--- a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginProvider.java
+++ b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginProvider.java
@@ -28,18 +28,18 @@ public class MockPaymentProviderPluginProvider implements Provider<MockPaymentPr
     @Inject
     private Clock clock;
 
-    public MockPaymentProviderPluginProvider(String instanceName) {
+    public MockPaymentProviderPluginProvider(final String instanceName) {
         this.instanceName = instanceName;
     }
 
     @Inject
-    public void setPaymentProviderPluginRegistry(PaymentProviderPluginRegistry registry) {
+    public void setPaymentProviderPluginRegistry(final PaymentProviderPluginRegistry registry) {
         this.registry = registry;
     }
 
     @Override
     public MockPaymentProviderPlugin get() {
-        MockPaymentProviderPlugin plugin = new MockPaymentProviderPlugin(clock);
+        final MockPaymentProviderPlugin plugin = new MockPaymentProviderPlugin(clock);
 
         registry.register(plugin, instanceName);
         return plugin;
diff --git a/payment/src/test/java/com/ning/billing/payment/TestHelper.java b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
index 9d04ceb..6a9e422 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestHelper.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
@@ -18,7 +18,6 @@ package com.ning.billing.payment;
 
 import java.util.UUID;
 
-import org.apache.commons.lang.RandomStringUtils;
 import org.joda.time.DateTime;
 
 import com.google.inject.Inject;
@@ -32,9 +31,7 @@ import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 import com.ning.billing.payment.api.PaymentApi;
-import com.ning.billing.payment.api.PaymentMethod;
 import com.ning.billing.payment.api.PaymentMethodPlugin;
-import com.ning.billing.payment.dao.PaymentDao;
 import com.ning.billing.payment.glue.PaymentTestModuleWithMocks;
 import com.ning.billing.payment.provider.DefaultNoOpPaymentMethodPlugin;
 import com.ning.billing.util.bus.Bus;
@@ -43,10 +40,8 @@ import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.UserType;
-import com.ning.billing.util.entity.EntityPersistenceException;
 
 public class TestHelper {
-
     protected final AccountUserApi accountUserApi;
     protected final InvoicePaymentApi invoicePaymentApi;
     protected PaymentApi paymentApi;
@@ -54,7 +49,7 @@ public class TestHelper {
     private final Bus eventBus;
 
     @Inject
-    public TestHelper(CallContextFactory factory, AccountUserApi accountUserApi, InvoicePaymentApi invoicePaymentApi, PaymentApi paymentApi, Bus eventBus) {
+    public TestHelper(final CallContextFactory factory, final AccountUserApi accountUserApi, final InvoicePaymentApi invoicePaymentApi, final PaymentApi paymentApi, final Bus eventBus) {
         this.eventBus = eventBus;
         this.accountUserApi = accountUserApi;
         this.invoicePaymentApi = invoicePaymentApi;
@@ -62,47 +57,46 @@ public class TestHelper {
         context = factory.createCallContext("Princess Buttercup", CallOrigin.TEST, UserType.TEST);
     }
 
-  
-    
-    public Invoice createTestInvoice(Account account,
-                                     DateTime targetDate,
-                                     Currency currency,
-                                     InvoiceItem... items) throws EventBusException {
-        Invoice invoice = new MockInvoice(account.getId(), new DateTime(), targetDate, currency);
 
-        for (InvoiceItem item : items) {
+    public Invoice createTestInvoice(final Account account,
+                                     final DateTime targetDate,
+                                     final Currency currency,
+                                     final InvoiceItem... items) throws EventBusException {
+        final Invoice invoice = new MockInvoice(account.getId(), new DateTime(), targetDate, currency);
+
+        for (final InvoiceItem item : items) {
             if (item instanceof MockRecurringInvoiceItem) {
-                MockRecurringInvoiceItem recurringInvoiceItem = (MockRecurringInvoiceItem) item;
+                final MockRecurringInvoiceItem recurringInvoiceItem = (MockRecurringInvoiceItem) item;
                 invoice.addInvoiceItem(new MockRecurringInvoiceItem(invoice.getId(),
-                                                               account.getId(),
-                                                               recurringInvoiceItem.getBundleId(),
-                                                               recurringInvoiceItem.getSubscriptionId(),
-                                                               recurringInvoiceItem.getPlanName(),
-                                                               recurringInvoiceItem.getPhaseName(),
-                                                               recurringInvoiceItem.getStartDate(),
-                                                               recurringInvoiceItem.getEndDate(),
-                                                               recurringInvoiceItem.getAmount(),
-                                                               recurringInvoiceItem.getRate(),
-                                                               recurringInvoiceItem.getCurrency()));
+                                                                    account.getId(),
+                                                                    recurringInvoiceItem.getBundleId(),
+                                                                    recurringInvoiceItem.getSubscriptionId(),
+                                                                    recurringInvoiceItem.getPlanName(),
+                                                                    recurringInvoiceItem.getPhaseName(),
+                                                                    recurringInvoiceItem.getStartDate(),
+                                                                    recurringInvoiceItem.getEndDate(),
+                                                                    recurringInvoiceItem.getAmount(),
+                                                                    recurringInvoiceItem.getRate(),
+                                                                    recurringInvoiceItem.getCurrency()));
             }
         }
 
-        ((ZombieControl)invoicePaymentApi).addResult("getInvoice", invoice);
-        InvoiceCreationEvent event = new MockInvoiceCreationEvent(invoice.getId(), invoice.getAccountId(),
-                invoice.getBalance(), invoice.getCurrency(),
-                invoice.getInvoiceDate(),
-                context.getUserToken());
-        
+        ((ZombieControl) invoicePaymentApi).addResult("getInvoice", invoice);
+        final InvoiceCreationEvent event = new MockInvoiceCreationEvent(invoice.getId(), invoice.getAccountId(),
+                                                                        invoice.getBalance(), invoice.getCurrency(),
+                                                                        invoice.getInvoiceDate(),
+                                                                        context.getUserToken());
+
         eventBus.post(event);
         return invoice;
     }
 
-    public Account createTestAccount(String email) throws Exception {
-        final String name = "First" + RandomStringUtils.randomAlphanumeric(5) + " " + "Last" + RandomStringUtils.randomAlphanumeric(5);
-        final String externalKey = RandomStringUtils.randomAlphanumeric(10);
+    public Account createTestAccount(final String email) throws Exception {
+        final String name = "First" + UUID.randomUUID().toString() + " " + "Last" + UUID.randomUUID().toString();
+        final String externalKey = UUID.randomUUID().toString();
 
-        Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
-        ZombieControl zombie = (ZombieControl) account;
+        final Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+        final ZombieControl zombie = (ZombieControl) account;
         zombie.addResult("getId", UUID.randomUUID());
         zombie.addResult("getExternalKey", externalKey);
         zombie.addResult("getName", name);
@@ -112,33 +106,33 @@ public class TestHelper {
         zombie.addResult("getCurrency", Currency.USD);
         zombie.addResult("getBillCycleDay", 1);
         zombie.addResult("isMigrated", false);
-        zombie.addResult("isNotifiedForInvoices", false);        
+        zombie.addResult("isNotifiedForInvoices", false);
         zombie.addResult("getTimeZone", BrainDeadProxyFactory.ZOMBIE_VOID);
-        zombie.addResult("getLocale", BrainDeadProxyFactory.ZOMBIE_VOID);        
+        zombie.addResult("getLocale", BrainDeadProxyFactory.ZOMBIE_VOID);
         zombie.addResult("getAddress1", BrainDeadProxyFactory.ZOMBIE_VOID);
-        zombie.addResult("getAddress2", BrainDeadProxyFactory.ZOMBIE_VOID);        
+        zombie.addResult("getAddress2", BrainDeadProxyFactory.ZOMBIE_VOID);
         zombie.addResult("getCompanyName", BrainDeadProxyFactory.ZOMBIE_VOID);
-        zombie.addResult("getCity", BrainDeadProxyFactory.ZOMBIE_VOID);        
+        zombie.addResult("getCity", BrainDeadProxyFactory.ZOMBIE_VOID);
         zombie.addResult("getStateOrProvince", BrainDeadProxyFactory.ZOMBIE_VOID);
-        zombie.addResult("getCountry", BrainDeadProxyFactory.ZOMBIE_VOID);        
+        zombie.addResult("getCountry", BrainDeadProxyFactory.ZOMBIE_VOID);
         zombie.addResult("getPostalCode", BrainDeadProxyFactory.ZOMBIE_VOID);
-        zombie.addResult("getPhone", BrainDeadProxyFactory.ZOMBIE_VOID);        
+        zombie.addResult("getPhone", BrainDeadProxyFactory.ZOMBIE_VOID);
         zombie.addResult("getPaymentMethodId", BrainDeadProxyFactory.ZOMBIE_VOID);
-        
-        ((ZombieControl)accountUserApi).addResult("getAccountById", account);
-        ((ZombieControl)accountUserApi).addResult("getAccountByKey", account);
-        ((ZombieControl)accountUserApi).addResult("updateAccount", BrainDeadProxyFactory.ZOMBIE_VOID);        
+
+        ((ZombieControl) accountUserApi).addResult("getAccountById", account);
+        ((ZombieControl) accountUserApi).addResult("getAccountByKey", account);
+        ((ZombieControl) accountUserApi).addResult("updateAccount", BrainDeadProxyFactory.ZOMBIE_VOID);
         //updateAccount
 
-        PaymentMethodPlugin pm = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), true, null);
+        final PaymentMethodPlugin pm = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), true, null);
         addTestPaymentMethod(account, pm);
         return account;
     }
-    
-    private void addTestPaymentMethod(Account account, PaymentMethodPlugin paymentMethodInfo) throws Exception {
-        UUID paymentMethodId = paymentApi.addPaymentMethod(PaymentTestModuleWithMocks.PLUGIN_TEST_NAME, account, true, paymentMethodInfo, context);
-        ZombieControl zombie = (ZombieControl) account;
-        zombie.addResult("getPaymentMethodId", paymentMethodId); 
+
+    private void addTestPaymentMethod(final Account account, final PaymentMethodPlugin paymentMethodInfo) throws Exception {
+        final UUID paymentMethodId = paymentApi.addPaymentMethod(PaymentTestModuleWithMocks.PLUGIN_TEST_NAME, account, true, paymentMethodInfo, context);
+        final ZombieControl zombie = (ZombieControl) account;
+        zombie.addResult("getPaymentMethodId", paymentMethodId);
     }
 
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
index a2bc8f9..b9ab5d0 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
@@ -16,12 +16,6 @@
 
 package com.ning.billing.payment;
 
-import static com.jayway.awaitility.Awaitility.await;
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
 import java.math.BigDecimal;
 import java.util.Collections;
 import java.util.Comparator;
@@ -30,18 +24,7 @@ import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeoutException;
 
-import com.ning.billing.payment.api.Payment;
-import com.ning.billing.payment.api.Payment.PaymentAttempt;
-import com.ning.billing.payment.api.PaymentApi;
-import com.ning.billing.payment.api.PaymentApiException;
-import com.ning.billing.payment.api.PaymentStatus;
-import com.ning.billing.payment.core.PaymentProcessor;
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.DefaultCallContext;
-import com.ning.billing.util.callcontext.UserType;
 import org.joda.time.DateTime;
-import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
@@ -58,6 +41,11 @@ import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 import com.ning.billing.mock.glue.MockClockModule;
 import com.ning.billing.mock.glue.MockJunctionModule;
+import com.ning.billing.payment.api.Payment;
+import com.ning.billing.payment.api.Payment.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentApiException;
+import com.ning.billing.payment.api.PaymentStatus;
+import com.ning.billing.payment.core.PaymentProcessor;
 import com.ning.billing.payment.glue.DefaultPaymentService;
 import com.ning.billing.payment.glue.PaymentTestModuleWithMocks;
 import com.ning.billing.payment.provider.MockPaymentProviderPlugin;
@@ -65,10 +53,20 @@ import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
 import com.ning.billing.payment.retry.FailedPaymentRetryService;
 import com.ning.billing.payment.retry.PluginFailureRetryService;
 import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.glue.CallContextModule;
 
-@Guice(modules = { PaymentTestModuleWithMocks.class, MockClockModule.class, MockJunctionModule.class, CallContextModule.class })
+import static com.jayway.awaitility.Awaitility.await;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Guice(modules = {PaymentTestModuleWithMocks.class, MockClockModule.class, MockJunctionModule.class, CallContextModule.class})
 public class TestRetryService {
     @Inject
     private PaymentConfig paymentConfig;
@@ -93,27 +91,20 @@ public class TestRetryService {
     private MockPaymentProviderPlugin mockPaymentProviderPlugin;
     private CallContext context;
 
-    @BeforeClass(groups = "fast")
-    public void initialize() throws Exception {
-        
-    }
-
     @BeforeMethod(groups = "fast")
     public void setUp() throws Exception {
-
         pluginRetryService.initialize(DefaultPaymentService.SERVICE_NAME);
         pluginRetryService.start();
-        
+
         retryService.initialize(DefaultPaymentService.SERVICE_NAME);
         retryService.start();
         eventBus.start();
-        
+
         mockPaymentProviderPlugin = (MockPaymentProviderPlugin) registry.getPlugin(null);
         mockPaymentProviderPlugin.clear();
-        
-        context = new DefaultCallContext("RetryServiceTests", CallOrigin.INTERNAL, UserType.TEST, clock);
-        ((ZombieControl)invoicePaymentApi).addResult("notifyOfPaymentAttempt", BrainDeadProxyFactory.ZOMBIE_VOID);
 
+        context = new DefaultCallContext("RetryServiceTests", CallOrigin.INTERNAL, UserType.TEST, clock);
+        ((ZombieControl) invoicePaymentApi).addResult("notifyOfPaymentAttempt", BrainDeadProxyFactory.ZOMBIE_VOID);
     }
 
     @AfterMethod(groups = "fast")
@@ -123,16 +114,14 @@ public class TestRetryService {
         eventBus.stop();
     }
 
-    
     private Payment getPaymentForInvoice(final UUID invoiceId) throws PaymentApiException {
-        List<Payment> payments = paymentProcessor.getInvoicePayments(invoiceId);
+        final List<Payment> payments = paymentProcessor.getInvoicePayments(invoiceId);
         assertEquals(payments.size(), 1);
-        Payment payment = payments.get(0);
+        final Payment payment = payments.get(0);
         assertEquals(payment.getInvoiceId(), invoiceId);
         return payment;
     }
 
-
     @Test(groups = "fast")
     public void testFailedPluginWithOneSuccessfulRetry() throws Exception {
         testSchedulesRetryInternal(1, FailureType.PLUGIN_EXCEPTION);
@@ -164,9 +153,8 @@ public class TestRetryService {
         testSchedulesRetryInternal(paymentConfig.getPaymentRetryDays().size() + 1, FailureType.PAYMENT_FAILURE);
     }
 
+    private void testSchedulesRetryInternal(final int maxTries, final FailureType failureType) throws Exception {
 
-    private void testSchedulesRetryInternal(int maxTries, final FailureType failureType) throws Exception {
-        
         final Account account = testHelper.createTestAccount("yiyi.gmail.com");
         final Invoice invoice = testHelper.createTestInvoice(account, clock.getUTCNow(), Currency.USD);
         final BigDecimal amount = new BigDecimal("10.00");
@@ -176,15 +164,15 @@ public class TestRetryService {
         final DateTime startDate = clock.getUTCNow();
         final DateTime endDate = startDate.plusMonths(1);
         invoice.addInvoiceItem(new MockRecurringInvoiceItem(invoice.getId(),
-                                                       account.getId(),
-                                                       subscriptionId,
-                                                       bundleId,
-                                                       "test plan", "test phase",
-                                                       startDate,
-                                                       endDate,
-                                                       amount,
-                                                       new BigDecimal("1.0"),
-                                                       Currency.USD));
+                                                            account.getId(),
+                                                            subscriptionId,
+                                                            bundleId,
+                                                            "test plan", "test phase",
+                                                            startDate,
+                                                            endDate,
+                                                            amount,
+                                                            new BigDecimal("1.0"),
+                                                            Currency.USD));
         setPaymentFailure(failureType);
         boolean failed = false;
         try {
@@ -197,17 +185,17 @@ public class TestRetryService {
         for (int curFailure = 0; curFailure < maxTries; curFailure++) {
 
             if (curFailure < maxTries - 1) {
-                setPaymentFailure(failureType);                
+                setPaymentFailure(failureType);
             }
 
             if (curFailure < getMaxRetrySizeForFailureType(failureType)) {
-                
+
                 moveClockForFailureType(failureType, curFailure);
                 try {
                     await().atMost(3, SECONDS).until(new Callable<Boolean>() {
                         @Override
                         public Boolean call() throws Exception {
-                            Payment payment = getPaymentForInvoice(invoice.getId());
+                            final Payment payment = getPaymentForInvoice(invoice.getId());
                             return payment.getPaymentStatus() == PaymentStatus.SUCCESS;
                         }
                     });
@@ -218,70 +206,69 @@ public class TestRetryService {
                 }
             }
         }
-        Payment payment = getPaymentForInvoice(invoice.getId());
-        List<PaymentAttempt> attempts = payment.getAttempts();
-        
-        int expectedAttempts = maxTries < getMaxRetrySizeForFailureType(failureType) ?
+        final Payment payment = getPaymentForInvoice(invoice.getId());
+        final List<PaymentAttempt> attempts = payment.getAttempts();
+
+        final int expectedAttempts = maxTries < getMaxRetrySizeForFailureType(failureType) ?
                 maxTries + 1 : getMaxRetrySizeForFailureType(failureType) + 1;
         assertEquals(attempts.size(), expectedAttempts);
         Collections.sort(attempts, new Comparator<PaymentAttempt>() {
             @Override
-            public int compare(PaymentAttempt o1, PaymentAttempt o2) {
+            public int compare(final PaymentAttempt o1, final PaymentAttempt o2) {
                 return o1.getEffectiveDate().compareTo(o2.getEffectiveDate());
             }
         });
- 
+
         for (int i = 0; i < attempts.size(); i++) {
-            PaymentAttempt cur = attempts.get(i);
+            final PaymentAttempt cur = attempts.get(i);
             if (i < attempts.size() - 1) {
                 if (failureType == FailureType.PAYMENT_FAILURE) {
                     assertEquals(cur.getPaymentStatus(), PaymentStatus.PAYMENT_FAILURE);
                 } else {
-                    assertEquals(cur.getPaymentStatus(), PaymentStatus.PLUGIN_FAILURE);                    
+                    assertEquals(cur.getPaymentStatus(), PaymentStatus.PLUGIN_FAILURE);
                 }
             } else if (maxTries <= getMaxRetrySizeForFailureType(failureType)) {
                 assertEquals(cur.getPaymentStatus(), PaymentStatus.SUCCESS);
                 assertEquals(payment.getPaymentStatus(), PaymentStatus.SUCCESS);
             } else {
                 if (failureType == FailureType.PAYMENT_FAILURE) {
-                    assertEquals(cur.getPaymentStatus(), PaymentStatus.PAYMENT_FAILURE_ABORTED);      
+                    assertEquals(cur.getPaymentStatus(), PaymentStatus.PAYMENT_FAILURE_ABORTED);
                     assertEquals(payment.getPaymentStatus(), PaymentStatus.PAYMENT_FAILURE_ABORTED);
                 } else {
-                    assertEquals(cur.getPaymentStatus(), PaymentStatus.PLUGIN_FAILURE_ABORTED);      
+                    assertEquals(cur.getPaymentStatus(), PaymentStatus.PLUGIN_FAILURE_ABORTED);
                     assertEquals(payment.getPaymentStatus(), PaymentStatus.PLUGIN_FAILURE_ABORTED);
                 }
             }
         }
     }
-    
+
     private enum FailureType {
         PLUGIN_EXCEPTION,
         PAYMENT_FAILURE
     }
-    
-    private void setPaymentFailure(FailureType failureType) {
+
+    private void setPaymentFailure(final FailureType failureType) {
         if (failureType == FailureType.PAYMENT_FAILURE) {
             mockPaymentProviderPlugin.makeNextPaymentFailWithError();
         } else if (failureType == FailureType.PLUGIN_EXCEPTION) {
-            mockPaymentProviderPlugin.makeNextPaymentFailWithException();            
+            mockPaymentProviderPlugin.makeNextPaymentFailWithException();
         }
     }
-    
-    private void moveClockForFailureType(FailureType failureType, int curFailure) {
+
+    private void moveClockForFailureType(final FailureType failureType, final int curFailure) {
         if (failureType == FailureType.PAYMENT_FAILURE) {
-            int nbDays = paymentConfig.getPaymentRetryDays().get(curFailure);            
+            final int nbDays = paymentConfig.getPaymentRetryDays().get(curFailure);
             clock.addDays(nbDays + 1);
         } else {
             clock.addDays(1);
         }
     }
-    
-    private int getMaxRetrySizeForFailureType(FailureType failureType) {
-        if (failureType == FailureType.PAYMENT_FAILURE) {        
+
+    private int getMaxRetrySizeForFailureType(final FailureType failureType) {
+        if (failureType == FailureType.PAYMENT_FAILURE) {
             return paymentConfig.getPaymentRetryDays().size();
         } else {
             return paymentConfig.getPluginFailureRetryMaxAttempts();
         }
     }
-     
 }

pom.xml 60(+19 -41)

diff --git a/pom.xml b/pom.xml
index f516c7a..aec8629 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
     <groupId>com.ning.billing</groupId>
     <artifactId>killbill</artifactId>
     <packaging>pom</packaging>
-    <version>0.1.13-SNAPSHOT</version>
+    <version>0.1.20-SNAPSHOT</version>
     <name>killbill</name>
     <description>Library for managing recurring subscriptions and the associated billing</description>
     <url>http://github.com/ning/killbill</url>
@@ -35,6 +35,7 @@
     </scm>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <slf4j.version>1.6.5</slf4j.version>
     </properties>
     <modules>
         <module>account</module>
@@ -53,11 +54,11 @@
     </modules>
     <dependencyManagement>
         <dependencies>
-           <dependency>
+            <dependency>
                 <groupId>javax.ws.rs</groupId>
                 <artifactId>jsr311-api</artifactId>
                 <version>1.1.1</version>
-           </dependency>
+            </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
                 <artifactId>killbill-beatrix</artifactId>
@@ -227,7 +228,7 @@
             <dependency>
                 <groupId>com.google.guava</groupId>
                 <artifactId>guava</artifactId>
-                <version>10.0.1</version>
+                <version>12.0</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
@@ -265,37 +266,11 @@
                 <version>1.2</version>
             </dependency>
             <dependency>
-                <groupId>org.apache.directory.studio</groupId>
-                <artifactId>org.apache.commons.io</artifactId>
-                <version>2.1</version>
-            </dependency>
-            <dependency>
-                <groupId>commons-io</groupId>
-                <artifactId>commons-io</artifactId>
-                <version>2.0</version>
-            </dependency>
-            <dependency>
-                <groupId>commons-lang</groupId>
-                <artifactId>commons-lang</artifactId>
-                <version>2.6</version>
-            </dependency>
-            <dependency>
-                <groupId>commons-collections</groupId>
-                <artifactId>commons-collections</artifactId>
-                <version>3.2.1</version>
-            </dependency>
-            <dependency>
                 <groupId>joda-time</groupId>
                 <artifactId>joda-time</artifactId>
                 <version>2.0</version>
             </dependency>
             <dependency>
-                <!-- For dependencies resolution -->
-                <groupId>log4j</groupId>
-                <artifactId>log4j</artifactId>
-                <version>1.2.16</version>
-            </dependency>
-            <dependency>
                 <groupId>mysql</groupId>
                 <artifactId>mysql-connector-java</artifactId>
                 <version>5.1.17</version>
@@ -310,32 +285,32 @@
             <dependency>
                 <groupId>org.jdbi</groupId>
                 <artifactId>jdbi</artifactId>
-                <version>2.32</version>
+                <version>2.37.1</version>
             </dependency>
             <dependency>
                 <groupId>org.skife.config</groupId>
                 <artifactId>config-magic</artifactId>
-                <version>0.13</version>
+                <version>0.14</version>
             </dependency>
             <dependency>
                 <groupId>org.slf4j</groupId>
                 <artifactId>slf4j-api</artifactId>
-                <version>1.6.4</version>
+                <version>${slf4j.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.slf4j</groupId>
-                <artifactId>jcl-over-slf4j</artifactId>
-                <version>1.6.4</version>
+                <artifactId>slf4j-simple</artifactId>
+                <version>${slf4j.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.slf4j</groupId>
-                <artifactId>jul-to-slf4j</artifactId>
-                <version>1.6.4</version>
+                <artifactId>jcl-over-slf4j</artifactId>
+                <version>${slf4j.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.slf4j</groupId>
-                <artifactId>slf4j-log4j12</artifactId>
-                <version>1.6.4</version>
+                <artifactId>jul-to-slf4j</artifactId>
+                <version>${slf4j.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.testng</groupId>
@@ -487,6 +462,7 @@
                                 <exclude>bin/**</exclude>
                                 <!-- exclude mustache template files -->
                                 <exclude>**/*.mustache</exclude>
+                                <exclude>examples/**</exclude>
                             </excludes>
                         </configuration>
                     </execution>
@@ -568,9 +544,11 @@
                             <groups>fast,slow</groups>
                             <useManifestOnlyJar>false</useManifestOnlyJar>
                             <systemPropertyVariables>
-                                <log4j.configuration>file:${project.basedir}/src/test/resources/log4j.xml</log4j.configuration>
+                                <log4j.configuration>file:${project.basedir}/src/test/resources/log4j.xml
+                                </log4j.configuration>
                                 <com.ning.billing.dbi.test.useLocalDb>true</com.ning.billing.dbi.test.useLocalDb>
-                                <com.ning.billing.dbi.jdbc.url>jdbc:mysql://127.0.0.1:3306/killbill</com.ning.billing.dbi.jdbc.url>
+                                <com.ning.billing.dbi.jdbc.url>jdbc:mysql://127.0.0.1:3306/killbill
+                                </com.ning.billing.dbi.jdbc.url>
                                 <file.encoding>UTF-8</file.encoding>
                                 <user.timezone>GMT</user.timezone>
                             </systemPropertyVariables>

server/pom.xml 831(+422 -409)

diff --git a/server/pom.xml b/server/pom.xml
index 0d19d77..7feeaff 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -9,151 +9,144 @@
 	the specific language governing permissions and limitations ~ under the License. -->
 
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<parent>
-		<groupId>com.ning.billing</groupId>
-		<artifactId>killbill</artifactId>
-		<version>0.1.13-SNAPSHOT</version>
-		<relativePath>../pom.xml</relativePath>
-	</parent>
-	<artifactId>killbill-server</artifactId>
-	<name>killbill-server</name>
-	<packaging>war</packaging>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.ning.billing</groupId>
+        <artifactId>killbill</artifactId>
+        <version>0.1.20-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>killbill-server</artifactId>
+    <name>killbill-server</name>
+    <packaging>war</packaging>
 
-	<properties>
-		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-		<guice.version>3.0</guice.version>
-		<jersey.version>1.12</jersey.version>
-		<jetty.version>8.1.2.v20120308</jetty.version>
-		<logback.version>1.0.1</logback.version>
-		<metrics.version>2.1.2</metrics.version>
-		<slf4j.version>1.6.4</slf4j.version>
-		<skeleton.version>0.1.2</skeleton.version>
-		<async-http-client.version>1.6.5</async-http-client.version>
-	</properties>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <guice.version>3.0</guice.version>
+        <jersey.version>1.12</jersey.version>
+        <jetty.version>8.1.2.v20120308</jetty.version>
+        <logback.version>1.0.1</logback.version>
+        <metrics.version>2.1.2</metrics.version>
+        <skeleton.version>0.1.4</skeleton.version>
+        <async-http-client.version>1.7.1</async-http-client.version>
+    </properties>
 
-	<dependencies>
-                <!-- Jetty provided scope -->
-		<dependency>
-			<groupId>org.eclipse.jetty</groupId>
-			<artifactId>jetty-http</artifactId>
-			<version>${jetty.version}</version>
-			<scope>provided</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.eclipse.jetty</groupId>
-			<artifactId>jetty-io</artifactId>
-			<version>${jetty.version}</version>
-			<scope>provided</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.eclipse.jetty</groupId>
-			<artifactId>jetty-util</artifactId>
-			<version>${jetty.version}</version>
-			<scope>provided</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.eclipse.jetty</groupId>
-			<artifactId>jetty-server</artifactId>
-			<version>${jetty.version}</version>
-			<scope>provided</scope>
-		</dependency>
-
-		<dependency>
-			<groupId>org.eclipse.jetty</groupId>
-			<artifactId>jetty-deploy</artifactId>
-			<version>${jetty.version}</version>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.eclipse.jetty</groupId>
-			<artifactId>jetty-jmx</artifactId>
-			<version>${jetty.version}</version>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.eclipse.jetty</groupId>
-			<artifactId>jetty-xml</artifactId>
-			<version>${jetty.version}</version>
-			<scope>test</scope>
-		</dependency>
+    <dependencies>
+        <!-- Jetty test scope -->
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-http</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-io</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-deploy</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-jmx</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-xml</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
 
-		<!-- NOT in master POM; include version as well -->
-		<dependency>
-			<groupId>org.weakref</groupId>
-			<artifactId>jmxutils</artifactId>
-			<version>1.12</version>
-		</dependency>
-		<dependency>
-			<groupId>com.google.inject.extensions</groupId>
-			<artifactId>guice-servlet</artifactId>
-			<version>${guice.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>com.yammer.metrics</groupId>
-			<artifactId>metrics-core</artifactId>
-			<version>${metrics.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>com.yammer.metrics</groupId>
-			<artifactId>metrics-guice</artifactId>
-			<version>${metrics.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>com.sun.jersey</groupId>
-			<artifactId>jersey-server</artifactId>
-			<version>${jersey.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>com.sun.jersey.contribs</groupId>
-			<artifactId>jersey-guice</artifactId>
-			<version>${jersey.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>javax.servlet</groupId>
-			<artifactId>javax.servlet-api</artifactId>
-			<version>3.0.1</version>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.jetty</groupId>
-			<artifactId>ning-service-skeleton-base</artifactId>
-			<version>${skeleton.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.jetty</groupId>
-			<artifactId>ning-service-skeleton-jdbi</artifactId>
-			<version>${skeleton.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.jetty</groupId>
-			<artifactId>ning-service-skeleton-log4j</artifactId>
-			<version>${skeleton.version}</version>
-			<classifier>selfcontained</classifier>
-			<scope>provided</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.slf4j</groupId>
-			<artifactId>slf4j-api</artifactId>
-			<version>${slf4j.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.slf4j</groupId>
-			<artifactId>jcl-over-slf4j</artifactId>
-			<version>${slf4j.version}</version>
-			<scope>runtime</scope>
-		</dependency>
-		<dependency>
-			<groupId>ch.qos.logback</groupId>
-			<artifactId>logback-core</artifactId>
-			<version>${logback.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>ch.qos.logback</groupId>
-			<artifactId>logback-classic</artifactId>
-			<version>${logback.version}</version>
-		</dependency>
+        <!-- NOT in master POM; include version as well -->
+        <dependency>
+            <groupId>org.weakref</groupId>
+            <artifactId>jmxutils</artifactId>
+            <version>1.12</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject.extensions</groupId>
+            <artifactId>guice-servlet</artifactId>
+            <version>${guice.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.yammer.metrics</groupId>
+            <artifactId>metrics-core</artifactId>
+            <version>${metrics.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.yammer.metrics</groupId>
+            <artifactId>metrics-guice</artifactId>
+            <version>${metrics.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-server</artifactId>
+            <version>${jersey.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey.contribs</groupId>
+            <artifactId>jersey-guice</artifactId>
+            <version>${jersey.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>3.0.1</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.jetty</groupId>
+            <artifactId>ning-service-skeleton-base</artifactId>
+            <version>${skeleton.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.jetty</groupId>
+            <artifactId>ning-service-skeleton-jdbi</artifactId>
+            <version>${skeleton.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <version>${slf4j.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <version>${logback.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>${logback.version}</version>
+            <scope>runtime</scope>
+        </dependency>
 
-		<!-- FROM MASTER POM / LIBRARY -->
+        <!-- FROM MASTER POM / LIBRARY -->
         <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-api</artifactId>
@@ -162,272 +155,292 @@
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-account</artifactId>
         </dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-jaxrs</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-beatrix</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-util</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-entitlement</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-invoice</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-payment</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-catalog</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-analytics</artifactId>
-		</dependency>
-                <dependency>
-                        <groupId>com.ning.billing</groupId>
-                        <artifactId>killbill-junction</artifactId>
-                </dependency>
-		<dependency>
-			<groupId>com.google.guava</groupId>
-			<artifactId>guava</artifactId>
-			<version>11.0.2</version>
-			<scope>compile</scope>
-		</dependency>
-		<dependency>
-			<groupId>com.google.inject</groupId>
-			<artifactId>guice</artifactId>
-			<scope>compile</scope>
-		</dependency>
-		<dependency><!-- Needed by jmxutils -->
-			<groupId>com.google.inject.extensions</groupId>
-			<artifactId>guice-multibindings</artifactId>
-			<scope>compile</scope>
-		</dependency>
-		<dependency>
-			<groupId>mysql</groupId>
-			<artifactId>mysql-connector-java</artifactId>
-			<scope>runtime</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.antlr</groupId>
-			<artifactId>stringtemplate</artifactId>
-			<scope>runtime</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.skife.config</groupId>
-			<artifactId>config-magic</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>javax.ws.rs</groupId>
-			<artifactId>jsr311-api</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>joda-time</groupId>
-			<artifactId>joda-time</artifactId>
-		</dependency>
-                <dependency>
-                        <groupId>commons-io</groupId>
-                        <artifactId>commons-io</artifactId>
-                </dependency>
-		<dependency>
-			<groupId>com.ning</groupId>
-			<artifactId>async-http-client</artifactId>
-			<version>${async-http-client.version}</version>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.testng</groupId>
-			<artifactId>testng</artifactId>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-util</artifactId>
-			<type>test-jar</type>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-beatrix</artifactId>
-			<type>test-jar</type>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>com.ning.billing</groupId>
-			<artifactId>killbill-payment</artifactId>
-			<type>test-jar</type>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>mysql</groupId>
-			<artifactId>mysql-connector-mxj</artifactId>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>mysql</groupId>
-			<artifactId>mysql-connector-mxj-db-files</artifactId>
-			<scope>test</scope>
-		</dependency>
-	</dependencies>
-	<build>
-		<resources>
-			<resource>
-				<directory>${basedir}/src/main/resources</directory>
-			</resource>
-		</resources>
-		<plugins>
-			<plugin>
-				<groupId>com.ning.maven.plugins</groupId>
-				<artifactId>maven-dependency-versions-check-plugin</artifactId>
-				<version>2.0.2</version>
-				<configuration>
-					<failBuildInCaseOfConflict>true</failBuildInCaseOfConflict>
-				</configuration>
-				<executions>
-					<execution>
-						<phase>verify</phase>
-						<goals>
-							<goal>check</goal>
-						</goals>
-					</execution>
-				</executions>
-			</plugin>
-			<plugin>
-				<!-- To make eclipse happy -->
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-resources-plugin</artifactId>
-				<version>2.5</version>
-			</plugin>
-			<plugin>
-				<groupId>com.ning.maven.plugins</groupId>
-				<artifactId>maven-duplicate-finder-plugin</artifactId>
-				<version>1.0.2</version>
-				<configuration>
-					<failBuildInCaseOfConflict>false</failBuildInCaseOfConflict>
-					<!-- That's for Jetty -->
-					<ignoredResources>
-						<ignoredResource>about.html</ignoredResource>
-					</ignoredResources>
-				</configuration>
-				<executions>
-					<execution>
-						<phase>verify</phase>
-						<goals>
-							<goal>check</goal>
-						</goals>
-					</execution>
-				</executions>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-compiler-plugin</artifactId>
-				<version>2.3.2</version>
-				<configuration>
-					<source>1.6</source>
-					<target>1.6</target>
-				</configuration>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-dependency-plugin</artifactId>
-				<version>2.3</version>
-				<executions>
-					<execution>
-						<id>analyze</id>
-						<goals>
-							<goal>analyze-only</goal>
-						</goals>
-						<configuration>
-							<ignoreNonCompile>true</ignoreNonCompile>
-							<failOnWarning>false</failOnWarning>
-						</configuration>
-					</execution>
-				</executions>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-release-plugin</artifactId>
-				<version>2.2.1</version>
-				<configuration>
-					<mavenExecutorId>forked-path</mavenExecutorId>
-				</configuration>
-				<dependencies>
-					<dependency>
-						<groupId>org.apache.maven.scm</groupId>
-						<artifactId>maven-scm-provider-gitexe</artifactId>
-						<version>1.4</version>
-					</dependency>
-					<dependency>
-						<groupId>org.codehaus.plexus</groupId>
-						<artifactId>plexus-utils</artifactId>
-						<version>1.5.9</version>
-					</dependency>
-				</dependencies>
-			</plugin>
-			<plugin>
-				<!-- TODO: fix for http://jira.codehaus.org/browse/MSITE-286? -->
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-site-plugin</artifactId>
-				<version>3.0</version>
-			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-war-plugin</artifactId>
-				<version>2.1.1</version>
-				<configuration>
-					<attachClasses>true</attachClasses>
-				</configuration>
-			</plugin>
-			<plugin>
-				<groupId>org.mortbay.jetty</groupId>
-				<artifactId>jetty-maven-plugin</artifactId>
-				<version>${jetty.version}</version>
-				<dependencies>
-					<dependency><!-- For LogLevelCounterAppender -->
-						<groupId>com.ning.jetty</groupId>
-						<artifactId>ning-service-skeleton-log4j</artifactId>
-						<version>${skeleton.version}</version>
-						<classifier>selfcontained</classifier>
-						<scope>runtime</scope>
-					</dependency>
-					<!-- Needed to redirect Jetty logs to slf4j -->
-					<dependency>
-						<groupId>org.slf4j</groupId>
-						<artifactId>slf4j-api</artifactId>
-						<version>${slf4j.version}</version>
-					</dependency>
-					<dependency>
-						<groupId>ch.qos.logback</groupId>
-						<artifactId>logback-core</artifactId>
-						<version>${logback.version}</version>
-					</dependency>
-					<dependency>
-						<groupId>ch.qos.logback</groupId>
-						<artifactId>logback-classic</artifactId>
-						<version>${logback.version}</version>
-					</dependency>
-				</dependencies>
-				<configuration>
-					<scanIntervalSeconds>60</scanIntervalSeconds>
-					<systemProperties>
-						<systemProperty>
-							<name>logback.configurationFile</name>
-							<value>file:${basedir}/src/main/resources/logback.xml</value>
-						</systemProperty>
-					</systemProperties>
-				</configuration>
-			</plugin>
-		</plugins>
-	</build>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-jaxrs</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-beatrix</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-entitlement</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-invoice</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-payment</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-catalog</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-analytics</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-junction</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>11.0.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency><!-- Needed by jmxutils -->
+            <groupId>com.google.inject.extensions</groupId>
+            <artifactId>guice-multibindings</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.antlr</groupId>
+            <artifactId>stringtemplate</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.skife.config</groupId>
+            <artifactId>config-magic</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>jsr311-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning</groupId>
+            <artifactId>async-http-client</artifactId>
+            <version>${async-http-client.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-util</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-beatrix</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-payment</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-mxj</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-mxj-db-files</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <resources>
+            <resource>
+                <directory>${basedir}/src/main/resources</directory>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>1.4</version>
+                <executions>
+                    <execution>
+                        <id>assemble-killbill</id>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <phase>package</phase>
+                        <configuration>
+                            <createSourcesJar>true</createSourcesJar>
+                            <shadedArtifactAttached>true</shadedArtifactAttached>
+                            <shadedClassifierName>jar-with-dependencies</shadedClassifierName>
+                            <filters>
+                                <filter>
+                                    <artifact>${project.groupId}:${project.artifactId}</artifact>
+                                </filter>
+                            </filters>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.ning.maven.plugins</groupId>
+                <artifactId>maven-dependency-versions-check-plugin</artifactId>
+                <version>2.0.2</version>
+                <configuration>
+                    <failBuildInCaseOfConflict>true</failBuildInCaseOfConflict>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <!-- To make eclipse happy -->
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>2.5</version>
+            </plugin>
+            <plugin>
+                <groupId>com.ning.maven.plugins</groupId>
+                <artifactId>maven-duplicate-finder-plugin</artifactId>
+                <version>1.0.2</version>
+                <configuration>
+                    <failBuildInCaseOfConflict>false</failBuildInCaseOfConflict>
+                    <!-- That's for Jetty -->
+                    <ignoredResources>
+                        <ignoredResource>about.html</ignoredResource>
+                    </ignoredResources>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.3.2</version>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <version>2.3</version>
+                <executions>
+                    <execution>
+                        <id>analyze</id>
+                        <goals>
+                            <goal>analyze-only</goal>
+                        </goals>
+                        <configuration>
+                            <ignoreNonCompile>true</ignoreNonCompile>
+                            <failOnWarning>false</failOnWarning>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-release-plugin</artifactId>
+                <version>2.2.1</version>
+                <configuration>
+                    <mavenExecutorId>forked-path</mavenExecutorId>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.maven.scm</groupId>
+                        <artifactId>maven-scm-provider-gitexe</artifactId>
+                        <version>1.4</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.codehaus.plexus</groupId>
+                        <artifactId>plexus-utils</artifactId>
+                        <version>1.5.9</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
+                <!-- TODO: fix for http://jira.codehaus.org/browse/MSITE-286? -->
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-site-plugin</artifactId>
+                <version>3.0</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>2.1.1</version>
+                <configuration>
+                    <attachClasses>true</attachClasses>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.mortbay.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.version}</version>
+                <dependencies>
+                    <dependency><!-- For LogLevelCounterAppender -->
+                        <groupId>com.ning.jetty</groupId>
+                        <artifactId>ning-service-skeleton-log4j</artifactId>
+                        <version>${skeleton.version}</version>
+                        <classifier>selfcontained</classifier>
+                        <scope>runtime</scope>
+                    </dependency>
+                    <!-- Needed to redirect Jetty logs to slf4j -->
+                    <dependency>
+                        <groupId>org.slf4j</groupId>
+                        <artifactId>slf4j-api</artifactId>
+                        <version>${slf4j.version}</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>ch.qos.logback</groupId>
+                        <artifactId>logback-core</artifactId>
+                        <version>${logback.version}</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>ch.qos.logback</groupId>
+                        <artifactId>logback-classic</artifactId>
+                        <version>${logback.version}</version>
+                    </dependency>
+                </dependencies>
+                <configuration>
+                    <scanIntervalSeconds>60</scanIntervalSeconds>
+                    <systemProperties>
+                        <systemProperty>
+                            <name>logback.configurationFile</name>
+                            <value>file:${basedir}/src/main/resources/logback.xml</value>
+                        </systemProperty>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/server/src/main/java/com/ning/billing/server/config/KillbillServerConfig.java b/server/src/main/java/com/ning/billing/server/config/KillbillServerConfig.java
index 65e6faa..a88324b 100644
--- a/server/src/main/java/com/ning/billing/server/config/KillbillServerConfig.java
+++ b/server/src/main/java/com/ning/billing/server/config/KillbillServerConfig.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.server.config;
 
-public interface KillbillServerConfig
-{
-	
+public interface KillbillServerConfig {
+
 }
diff --git a/server/src/main/java/com/ning/billing/server/healthchecks/KillbillHealthcheck.java b/server/src/main/java/com/ning/billing/server/healthchecks/KillbillHealthcheck.java
index 62c79bf..0883e09 100644
--- a/server/src/main/java/com/ning/billing/server/healthchecks/KillbillHealthcheck.java
+++ b/server/src/main/java/com/ning/billing/server/healthchecks/KillbillHealthcheck.java
@@ -15,31 +15,27 @@
  */
 package com.ning.billing.server.healthchecks;
 
-import com.yammer.metrics.core.HealthCheck;
 import org.weakref.jmx.Managed;
 
-public class KillbillHealthcheck extends HealthCheck
-{
-    public KillbillHealthcheck()
-    {
+import com.yammer.metrics.core.HealthCheck;
+
+public class KillbillHealthcheck extends HealthCheck {
+    public KillbillHealthcheck() {
         super(KillbillHealthcheck.class.getSimpleName());
     }
 
     @Override
-    public Result check()
-    {
+    public Result check() {
         try {
             // STEPH obviously needs more than that
             return Result.healthy();
-        }
-        catch (Exception e) {
+        } catch (Exception e) {
             return Result.unhealthy(e);
         }
     }
 
     @Managed(description = "Basic killbill healthcheck")
-    public boolean isHealthy()
-    {
+    public boolean isHealthy() {
         return check().isHealthy();
     }
 }
diff --git a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
index 1aaef9b..808ff0d 100644
--- a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
+++ b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
@@ -16,6 +16,13 @@
 package com.ning.billing.server.listeners;
 
 
+import javax.servlet.ServletContextEvent;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Injector;
+import com.google.inject.Module;
 import com.ning.billing.beatrix.lifecycle.DefaultLifecycle;
 import com.ning.billing.jaxrs.util.KillbillEventHandler;
 import com.ning.billing.server.config.KillbillServerConfig;
@@ -26,18 +33,7 @@ import com.ning.billing.util.bus.BusService;
 import com.ning.jetty.base.modules.ServerModuleBuilder;
 import com.ning.jetty.core.listeners.SetupServer;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.PropertyNamingStrategy;
-import com.google.inject.Injector;
-import com.google.inject.Module;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.ServletContextEvent;
-
-public class KillbillGuiceListener extends SetupServer
-{
+public class KillbillGuiceListener extends SetupServer {
     public static final Logger logger = LoggerFactory.getLogger(KillbillGuiceListener.class);
 
     private DefaultLifecycle killbillLifecycle;
@@ -46,13 +42,14 @@ public class KillbillGuiceListener extends SetupServer
 
 
     protected Module getModule() {
-    	return new KillbillServerModule();
+        return new KillbillServerModule();
     }
 
+    
+   
     @Override
-    public void contextInitialized(ServletContextEvent event)
-    {
-    	
+    public void contextInitialized(final ServletContextEvent event) {
+
 
         final ServerModuleBuilder builder = new ServerModuleBuilder()
                 .addConfig(KillbillServerConfig.class)
@@ -67,16 +64,16 @@ public class KillbillGuiceListener extends SetupServer
         super.contextInitialized(event);
 
         logger.info("KillbillLifecycleListener : contextInitialized");
-        Injector theInjector = injector(event);
+        final Injector theInjector = injector(event);
         killbillLifecycle = theInjector.getInstance(DefaultLifecycle.class);
         killbillBusService = theInjector.getInstance(BusService.class);
-        killbilleventHandler = theInjector.getInstance(KillbillEventHandler.class); 
-        
+        killbilleventHandler = theInjector.getInstance(KillbillEventHandler.class);
+
         /*
-        ObjectMapper mapper = theInjector.getInstance(ObjectMapper.class);
-        mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());
-*/
-        
+                ObjectMapper mapper = theInjector.getInstance(ObjectMapper.class);
+                mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy());
+        */
+
         //
         // Fire all Startup levels up to service start
         //
@@ -86,8 +83,7 @@ public class KillbillGuiceListener extends SetupServer
         //
         try {
             killbillBusService.getBus().register(killbilleventHandler);
-        }
-        catch (Bus.EventBusException e) {
+        } catch (Bus.EventBusException e) {
             logger.error("Failed to register for event notifications, this is bad exiting!", e);
             System.exit(1);
         }
@@ -96,8 +92,7 @@ public class KillbillGuiceListener extends SetupServer
     }
 
     @Override
-    public void contextDestroyed(ServletContextEvent sce)
-    {
+    public void contextDestroyed(final ServletContextEvent sce) {
         super.contextDestroyed(sce);
 
         logger.info("IrsKillbillListener : contextDestroyed");
@@ -111,8 +106,7 @@ public class KillbillGuiceListener extends SetupServer
 
         try {
             killbillBusService.getBus().unregister(killbilleventHandler);
-        }
-        catch (Bus.EventBusException e) {
+        } catch (Bus.EventBusException e) {
             logger.warn("Failed to unregister for event notifications", e);
         }
 
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 68ac725..74ef8c3 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
@@ -16,6 +16,7 @@
 
 package com.ning.billing.server.modules;
 
+
 import org.skife.jdbi.v2.DBI;
 import org.skife.jdbi.v2.IDBI;
 
@@ -37,7 +38,6 @@ import com.ning.billing.jaxrs.resources.TagResource;
 import com.ning.billing.jaxrs.util.KillbillEventHandler;
 import com.ning.billing.jaxrs.util.TagHelper;
 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;
@@ -50,8 +50,7 @@ import com.ning.billing.util.glue.NotificationQueueModule;
 import com.ning.billing.util.glue.TagStoreModule;
 import com.ning.jetty.jdbi.guice.providers.DBIProvider;
 
-public class KillbillServerModule extends AbstractModule
-{
+public class KillbillServerModule extends AbstractModule {
     @Override
     protected void configure() {
         configureDao();
@@ -59,7 +58,13 @@ public class KillbillServerModule extends AbstractModule
         installKillbillModules();
     }
 
+    
     protected void configureDao() {
+        // Load mysql driver if needed
+        try {
+            Class.forName ("com.mysql.jdbc.Driver").newInstance ();
+        } catch (Exception ignore) {
+        }
         bind(IDBI.class).to(DBI.class).asEagerSingleton();
         bind(DBI.class).toProvider(DBIProvider.class).asEagerSingleton();
     }
@@ -72,22 +77,22 @@ public class KillbillServerModule extends AbstractModule
         bind(InvoiceResource.class).asEagerSingleton();
         bind(TagResource.class).asEagerSingleton();
         bind(CatalogResource.class).asEagerSingleton();
-        bind(PaymentMethodResource.class).asEagerSingleton();        
-        bind(PaymentResource.class).asEagerSingleton();                
+        bind(PaymentMethodResource.class).asEagerSingleton();
+        bind(PaymentResource.class).asEagerSingleton();
         bind(KillbillEventHandler.class).asEagerSingleton();
     }
 
     protected void installClock() {
-        install(new ClockModule());    	
+        install(new ClockModule());
     }
-    
+
     protected void installKillbillModules() {
         install(new EmailModule());
         install(new GlobalLockerModule());
         install(new CustomFieldModule());
         install(new TagStoreModule());
         install(new CatalogModule());
-    	install(new BusModule());
+        install(new BusModule());
         install(new NotificationQueueModule());
         install(new CallContextModule());
         install(new AccountModule());
@@ -97,7 +102,7 @@ public class KillbillServerModule extends AbstractModule
         install(new AnalyticsModule());
         install(new PaymentModule());
         install(new BeatrixModule());
-        install(new DefaultJunctionModule());        
+        install(new DefaultJunctionModule());
         installClock();
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
index 9fe5ade..3e00cdd 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
@@ -16,29 +16,19 @@
 package com.ning.billing.jaxrs;
 
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
+import javax.ws.rs.core.Response.Status;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-
-import javax.ws.rs.core.Response.Status;
-
-
-import com.ning.billing.jaxrs.resources.JaxrsResource;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
@@ -46,135 +36,137 @@ import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.AccountTimelineJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
-import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
 import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.json.PaymentMethodJson;
-import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodPluginDetailJson;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.json.TagDefinitionJson;
-import com.ning.billing.payment.api.PaymentMethod;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
 
 public class TestAccount extends TestJaxrsBase {
 
-	private static final Logger log = LoggerFactory.getLogger(TestAccount.class);
-	
-	@Test(groups="slow", enabled=true)
-	public void testAccountOk() throws Exception {
-		
-		AccountJson input = createAccount("xoxo", "shdgfhwe", "xoxo@yahoo.com");
-		
-		// Retrieves by external key
-		Map<String, String> queryParams = new HashMap<String, String>();
-		queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "shdgfhwe");
-		Response response = doGet(JaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-		String baseJson = response.getResponseBody();
-		AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
-		Assert.assertTrue(objFromJson.equals(input));
-		
-		// Update Account
-		AccountJson newInput = new AccountJson(objFromJson.getAccountId(),
-				"zozo", 4, objFromJson.getExternalKey(), "rr@google.com", 18, "EUR", null, "UTC", "bl1", "bh2", "", "ca", "usa", "415-255-2991");
-		baseJson = mapper.writeValueAsString(newInput);
-		final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + objFromJson.getAccountId();
-		response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-		baseJson = response.getResponseBody();
-		objFromJson = mapper.readValue(baseJson, AccountJson.class);
-		Assert.assertTrue(objFromJson.equals(newInput));
-	}
-
-
-	@Test(groups="slow", enabled=true)
-	public void testUpdateNonExistentAccount() throws Exception {
-		AccountJson input = getAccountJson("xoxo", "shghaahwe", "xoxo@yahoo.com");
-		String baseJson = mapper.writeValueAsString(input);
-		final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId();
-		Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-		String body = response.getResponseBody();
-		Assert.assertEquals(body, "");
-	}
-	
-	
-	@Test(groups="slow", enabled=true)
-	public void testAccountNonExistent() throws Exception {
-		final String uri = JaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
-		Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-	}
-	
-	@Test(groups="slow", enabled=true)
-	public void testAccountBadAccountId() throws Exception {
-		final String uri = JaxrsResource.ACCOUNTS_PATH + "/yo";
-		Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
-	}
-	
-	@Test(groups="slow", enabled=true)
-	public void testAccountTimeline() throws Exception {
-	    
+    private static final Logger log = LoggerFactory.getLogger(TestAccount.class);
+
+    @Test(groups = "slow", enabled = true)
+    public void testAccountOk() throws Exception {
+
+        final AccountJson input = createAccount("xoxo", "shdgfhwe", "xoxo@yahoo.com");
+
+        // Retrieves by external key
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "shdgfhwe");
+        Response response = doGet(JaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        String baseJson = response.getResponseBody();
+        AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
+        Assert.assertTrue(objFromJson.equals(input));
+
+        // Update Account
+        final AccountJson newInput = new AccountJson(objFromJson.getAccountId(),
+                                               "zozo", 4, objFromJson.getExternalKey(), "rr@google.com", 18, "EUR", null, "UTC", "bl1", "bh2", "", "ca", "usa", "415-255-2991");
+        baseJson = mapper.writeValueAsString(newInput);
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + objFromJson.getAccountId();
+        response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        baseJson = response.getResponseBody();
+        objFromJson = mapper.readValue(baseJson, AccountJson.class);
+        Assert.assertTrue(objFromJson.equals(newInput));
+    }
+
+
+    @Test(groups = "slow", enabled = true)
+    public void testUpdateNonExistentAccount() throws Exception {
+        final AccountJson input = getAccountJson("xoxo", "shghaahwe", "xoxo@yahoo.com");
+        final String baseJson = mapper.writeValueAsString(input);
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId();
+        final Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+        final String body = response.getResponseBody();
+        Assert.assertEquals(body, "");
+    }
+
+
+    @Test(groups = "slow", enabled = true)
+    public void testAccountNonExistent() throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+    }
+
+    @Test(groups = "slow", enabled = true)
+    public void testAccountBadAccountId() throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/yo";
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
+    }
+
+    @Test(groups = "slow", enabled = true)
+    public void testAccountTimeline() throws Exception {
+
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
-        
-        
-	    AccountJson accountJson = createAccountWithDefaultPaymentMethod("poney", "shdddqgfhwe", "poney@yahoo.com");
-	    assertNotNull(accountJson);
-	    
-	    BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "996599");
-	    assertNotNull(bundleJson);
-	    
-
-        SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+
+
+        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("poney", "shdddqgfhwe", "poney@yahoo.com");
+        assertNotNull(accountJson);
+
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "996599");
+        assertNotNull(bundleJson);
+
+
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
         assertNotNull(subscriptionJson);
 
         // MOVE AFTER TRIAL
         clock.addMonths(3);
 
         crappyWaitForLackOfProperSynchonization();
-        
+
         final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.TIMELINE;
 
-        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        String baseJson = response.getResponseBody();
-        AccountTimelineJson objFromJson = mapper.readValue(baseJson, AccountTimelineJson.class);
+        final String baseJson = response.getResponseBody();
+        final AccountTimelineJson objFromJson = mapper.readValue(baseJson, AccountTimelineJson.class);
         assertNotNull(objFromJson);
         log.info(baseJson);
 
         Assert.assertEquals(objFromJson.getPayments().size(), 3);
-        Assert.assertEquals(objFromJson.getInvoices().size(), 4);   
-        Assert.assertEquals(objFromJson.getBundles().size(), 1); 
+        Assert.assertEquals(objFromJson.getInvoices().size(), 4);
+        Assert.assertEquals(objFromJson.getBundles().size(), 1);
         Assert.assertEquals(objFromJson.getBundles().get(0).getSubscriptions().size(), 1);
-        Assert.assertEquals(objFromJson.getBundles().get(0).getSubscriptions().get(0).getEvents().size(), 2);        
+        Assert.assertEquals(objFromJson.getBundles().get(0).getSubscriptions().get(0).getEvents().size(), 2);
     }
 
-	
 
-    @Test(groups="slow", enabled=true)
+    @Test(groups = "slow", enabled = true)
     public void testAccountPaymentMethods() throws Exception {
 
-        AccountJson accountJson = createAccount("qwerty", "ytrewq", "qwerty@yahoo.com");
+        final AccountJson accountJson = createAccount("qwerty", "ytrewq", "qwerty@yahoo.com");
         assertNotNull(accountJson);
-        
+
         String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
         PaymentMethodJson paymentMethodJson = getPaymentMethodJson(accountJson.getAccountId(), getPaymentMethodCCProperties());
         String baseJson = mapper.writeValueAsString(paymentMethodJson);
         Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_PAYMENT_METHOD_IS_DEFAULT, "true");
-    
+
         Response response = doPost(uri, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        String locationCC = response.getHeader("Location");
+        final String locationCC = response.getHeader("Location");
         Assert.assertNotNull(locationCC);
 
         // Retrieves by Id based on Location returned
         response = doGetWithUrl(locationCC, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         baseJson = response.getResponseBody();
-        PaymentMethodJson paymentMethodCC = mapper.readValue(baseJson, PaymentMethodJson.class);
+        final PaymentMethodJson paymentMethodCC = mapper.readValue(baseJson, PaymentMethodJson.class);
         assertTrue(paymentMethodCC.isDefault());
         //
         // Add another payment method
@@ -182,18 +174,18 @@ public class TestAccount extends TestJaxrsBase {
         uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
         paymentMethodJson = getPaymentMethodJson(accountJson.getAccountId(), getPaymentMethodPaypalProperties());
         baseJson = mapper.writeValueAsString(paymentMethodJson);
-    
+
         response = doPost(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        String locationPP = response.getHeader("Location");
+        final String locationPP = response.getHeader("Location");
         assertNotNull(locationPP);
         response = doGetWithUrl(locationPP, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         baseJson = response.getResponseBody();
-        PaymentMethodJson paymentMethodPP = mapper.readValue(baseJson, PaymentMethodJson.class);
+        final PaymentMethodJson paymentMethodPP = mapper.readValue(baseJson, PaymentMethodJson.class);
         assertFalse(paymentMethodPP.isDefault());
-        
+
         //
         // FETCH ALL PAYMENT METHODS
         //
@@ -204,32 +196,32 @@ public class TestAccount extends TestJaxrsBase {
         baseJson = response.getResponseBody();
         List<PaymentMethodJson> paymentMethods = mapper.readValue(baseJson, new TypeReference<List<PaymentMethodJson>>() {});
         assertEquals(paymentMethods.size(), 2);
-        
-        
+
+
         //
         // CHANGE DEFAULT
         //
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS +  "/" + paymentMethodPP.getPaymentMethodId() + "/" + JaxrsResource.PAYMENT_METHODS_DEFAULT_PATH_POSTFIX;      
+        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS + "/" + paymentMethodPP.getPaymentMethodId() + "/" + JaxrsResource.PAYMENT_METHODS_DEFAULT_PATH_POSTFIX;
         response = doPut(uri, "{}", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
 
         response = doGetWithUrl(locationPP, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         baseJson = response.getResponseBody();
-        PaymentMethodJson paymentMethodPPDefault = mapper.readValue(baseJson, PaymentMethodJson.class);
+        final PaymentMethodJson paymentMethodPPDefault = mapper.readValue(baseJson, PaymentMethodJson.class);
         assertTrue(paymentMethodPPDefault.isDefault());
-        
+
         //
         // DELETE NON DEFAULT PM
         //
-        uri = JaxrsResource.PAYMENT_METHODS_PATH  + "/" + paymentMethodCC.getPaymentMethodId();
+        uri = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodCC.getPaymentMethodId();
         response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
 
         //
         // FETCH ALL PAYMENT METHODS
         //
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;        
+        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
         queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_PAYMENT_METHOD_PLUGIN_INFO, "true");
         response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -239,47 +231,45 @@ public class TestAccount extends TestJaxrsBase {
         assertEquals(paymentMethods.size(), 1);
     }
 
-    @Test(groups="slow", enabled=true)
+    @Test(groups = "slow", enabled = true)
     public void testAccountPayments() throws Exception {
 
-        clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
+        //clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
-        AccountJson accountJson = createAccountWithDefaultPaymentMethod("ermenehildo", "shtyrgfhwe", "ermenehildo@yahoo.com");
+        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("ermenehildo", "shtyrgfhwe", "ermenehildo@yahoo.com");
         assertNotNull(accountJson);
 
-        BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "396199");
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "396199");
         assertNotNull(bundleJson);
 
-        SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
         assertNotNull(subscriptionJson);
 
-        // MOVE AFTER TRIAL
-        clock.addMonths(3);
-
+        clock.addMonths(1);
         crappyWaitForLackOfProperSynchonization();
 
 
         final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENTS;
 
-        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        String baseJson = response.getResponseBody();
-        List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
-        Assert.assertEquals(objFromJson.size(), 3);
+        final String baseJson = response.getResponseBody();
+        final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+        Assert.assertEquals(objFromJson.size(), 1);
     }
 
-	@Test(groups="slow", enabled=true)
-	public void testTags() throws Exception {
-	    //Create Tag definition
-	    TagDefinitionJson input = new TagDefinitionJson("yoyo", "nothing more to say");
-	    String baseJson = mapper.writeValueAsString(input);
-	    Response response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-	    assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-	        
-	    Map<String, String> queryParams = new HashMap<String, String>();
+    @Test(groups = "slow", enabled = true)
+    public void testTags() throws Exception {
+        //Create Tag definition
+        final TagDefinitionJson input = new TagDefinitionJson("yoyo", "nothing more to say");
+        final String baseJson = mapper.writeValueAsString(input);
+        Response response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        final Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_TAGS, input.getName());
-        String uri = JaxrsResource.ACCOUNTS_PATH + "/" + JaxrsResource.TAGS + "/" + UUID.randomUUID().toString();
-	    response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + JaxrsResource.TAGS + "/" + UUID.randomUUID().toString();
+        response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
 
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
@@ -289,27 +279,27 @@ public class TestAccount extends TestJaxrsBase {
          */
 
         // Retrieves by Id based on Location returned
-        String url = getUrlFromUri(uri);
+        final String url = getUrlFromUri(uri);
         response = doGetWithUrl(url, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
     }
 
 
-    @Test(groups="slow", enabled=true)
-	public void testCustomFields() throws Exception {
+    @Test(groups = "slow", enabled = true)
+    public void testCustomFields() throws Exception {
 
-        List<CustomFieldJson> customFields =  new LinkedList<CustomFieldJson>();
+        final List<CustomFieldJson> customFields = new LinkedList<CustomFieldJson>();
         customFields.add(new CustomFieldJson("1", "value1"));
         customFields.add(new CustomFieldJson("2", "value2"));
-        customFields.add(new CustomFieldJson("3", "value3"));  
-        String baseJson = mapper.writeValueAsString(customFields);
+        customFields.add(new CustomFieldJson("3", "value3"));
+        final String baseJson = mapper.writeValueAsString(customFields);
 
-        String uri = JaxrsResource.ACCOUNTS_PATH + "/" + JaxrsResource.CUSTOM_FIELDS + "/" + UUID.randomUUID().toString();
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + JaxrsResource.CUSTOM_FIELDS + "/" + UUID.randomUUID().toString();
         Response response = doPost(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
         // Retrieves by Id based on Location returned
-        String url = getUrlFromUri(uri);
+        final String url = getUrlFromUri(uri);
         response = doGetWithUrl(url, 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/TestAccountEmail.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmail.java
new file mode 100644
index 0000000..fccecbf
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmail.java
@@ -0,0 +1,92 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.ning.billing.jaxrs.json.AccountEmailJson;
+import com.ning.billing.jaxrs.json.AccountJson;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.http.client.Response;
+
+import static org.testng.Assert.assertEquals;
+
+public class TestAccountEmail extends TestJaxrsBase {
+    @Test(groups = "slow")
+    public void testAddAndRemoveAccountEmail() throws Exception {
+        final AccountJson input = createAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        final String accountId = input.getAccountId();
+
+        final String email1 = UUID.randomUUID().toString();
+        final String email2 = UUID.randomUUID().toString();
+        final AccountEmailJson accountEmailJson1 = new AccountEmailJson(accountId, email1);
+        final AccountEmailJson accountEmailJson2 = new AccountEmailJson(accountId, email2);
+
+        final String baseUri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
+
+        // Verify the initial state
+        final Response firstResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(firstResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final List<AccountEmailJson> firstEmails = mapper.readValue(firstResponse.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
+        Assert.assertEquals(firstEmails.size(), 0);
+
+        // Add an email
+        final String firstEmailString = mapper.writeValueAsString(accountEmailJson1);
+        final Response secondResponse = doPost(baseUri, firstEmailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(secondResponse.getStatusCode(), javax.ws.rs.core.Response.Status.CREATED.getStatusCode());
+
+        // Verify we can retrieve it
+        final Response thirdResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(thirdResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final List<AccountEmailJson> secondEmails = mapper.readValue(thirdResponse.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
+        Assert.assertEquals(secondEmails.size(), 1);
+        Assert.assertEquals(secondEmails.get(0).getAccountId(), accountId);
+        Assert.assertEquals(secondEmails.get(0).getEmail(), email1);
+
+        // Add another email
+        final String secondEmailString = mapper.writeValueAsString(accountEmailJson2);
+        final Response thridResponse = doPost(baseUri, secondEmailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(thridResponse.getStatusCode(), javax.ws.rs.core.Response.Status.CREATED.getStatusCode());
+
+        // Verify we can retrieve both
+        final Response fourthResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(fourthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final List<AccountEmailJson> thirdEmails = mapper.readValue(fourthResponse.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
+        Assert.assertEquals(thirdEmails.size(), 2);
+        Assert.assertEquals(thirdEmails.get(0).getAccountId(), accountId);
+        Assert.assertEquals(thirdEmails.get(1).getAccountId(), accountId);
+        Assert.assertTrue(thirdEmails.get(0).getEmail().equals(email1) || thirdEmails.get(0).getEmail().equals(email2));
+        Assert.assertTrue(thirdEmails.get(1).getEmail().equals(email1) || thirdEmails.get(1).getEmail().equals(email2));
+
+        // Delete the first email
+        final Response fifthResponse = doDelete(baseUri + "/" + email1, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(fifthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+
+        // Verify it has been deleted
+        final Response sixthResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(sixthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final List<AccountEmailJson> fourthEmails = mapper.readValue(sixthResponse.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
+        Assert.assertEquals(fourthEmails.size(), 1);
+        Assert.assertEquals(fourthEmails.get(0).getAccountId(), accountId);
+        Assert.assertEquals(fourthEmails.get(0).getEmail(), email2);
+    }
+}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmailNotifications.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmailNotifications.java
new file mode 100644
index 0000000..9982032
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmailNotifications.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.ning.billing.jaxrs.json.AccountJson;
+import com.ning.billing.jaxrs.json.InvoiceEmailJson;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.http.client.Response;
+
+import static org.testng.Assert.assertEquals;
+
+public class TestAccountEmailNotifications extends TestJaxrsBase {
+    @Test(groups = "slow")
+    public void testSetAndUnsetEmailNotifications() throws Exception {
+        final AccountJson input = createAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        final String accountId = input.getAccountId();
+
+        final InvoiceEmailJson invoiceEmailJsonWithNotifications = new InvoiceEmailJson(accountId, true);
+        final InvoiceEmailJson invoiceEmailJsonWithoutNotifications = new InvoiceEmailJson(accountId, false);
+        final String baseUri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAIL_NOTIFICATIONS;
+
+        // Verify the initial state
+        final Response firstResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(firstResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final InvoiceEmailJson firstInvoiceEmailJson = mapper.readValue(firstResponse.getResponseBody(), new TypeReference<InvoiceEmailJson>() {});
+        Assert.assertEquals(firstInvoiceEmailJson.getAccountId(), accountId);
+        Assert.assertFalse(firstInvoiceEmailJson.isNotifiedForInvoices());
+
+        // Enable email notifications
+        final String firstEmailString = mapper.writeValueAsString(invoiceEmailJsonWithNotifications);
+        final Response secondResponse = doPut(baseUri, firstEmailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(secondResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+
+        // Verify we can retrieve it
+        final Response thirdResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(thirdResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final InvoiceEmailJson secondInvoiceEmailJson = mapper.readValue(thirdResponse.getResponseBody(), new TypeReference<InvoiceEmailJson>() {});
+        Assert.assertEquals(secondInvoiceEmailJson.getAccountId(), accountId);
+        Assert.assertTrue(secondInvoiceEmailJson.isNotifiedForInvoices());
+
+        // Disable email notifications
+        final String secondEmailString = mapper.writeValueAsString(invoiceEmailJsonWithoutNotifications);
+        final Response fourthResponse = doPut(baseUri, secondEmailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(fourthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+
+        // Verify we can retrieve it
+        final Response fifthResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(fifthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final InvoiceEmailJson thirdInvoiceEmailJson = mapper.readValue(fifthResponse.getResponseBody(), new TypeReference<InvoiceEmailJson>() {});
+        Assert.assertEquals(thirdInvoiceEmailJson.getAccountId(), accountId);
+        Assert.assertFalse(thirdInvoiceEmailJson.isNotifiedForInvoices());
+    }
+}
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 b15c8ea..2f169f9 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
@@ -15,14 +15,13 @@
  */
 package com.ning.billing.jaxrs;
 
+import javax.ws.rs.core.Response.Status;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import javax.ws.rs.core.Response.Status;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
@@ -36,81 +35,80 @@ import com.ning.http.client.Response;
 
 public class TestBundle extends TestJaxrsBase {
 
-	private static final Logger log = LoggerFactory.getLogger(TestBundle.class);
-
-
-	
-	@Test(groups="slow", enabled=true)
-	public void testBundleOk() throws Exception {
-
-		AccountJson accountJson = createAccount("xlxl", "shdgfhkkl", "xlxl@yahoo.com");
-		BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "12345");
-		
-		// Retrieves by external key
-		Map<String, String> queryParams = new HashMap<String, String>();
-		queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "12345");
-		Response response = doGet(JaxrsResource.BUNDLES_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-		String baseJson = response.getResponseBody();
-		BundleJsonNoSubscriptions objFromJson = mapper.readValue(baseJson, BundleJsonNoSubscriptions.class);
-		Assert.assertTrue(objFromJson.equals(bundleJson));
-	}
-	
-	
-	@Test(groups="slow", enabled=true)
-	public void testBundleFromAccount() throws Exception {
-
-		AccountJson accountJson = createAccount("xaxa", "saagfhkkl", "xaxa@yahoo.com");
-		BundleJsonNoSubscriptions bundleJson1 = createBundle(accountJson.getAccountId(), "156567");
-		BundleJsonNoSubscriptions bundleJson2 = createBundle(accountJson.getAccountId(), "265658");
-
-		String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId().toString() + "/" + JaxrsResource.BUNDLES;
-		Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-		String baseJson = response.getResponseBody();
-		List<BundleJsonNoSubscriptions> objFromJson = mapper.readValue(baseJson, new TypeReference<List<BundleJsonNoSubscriptions>>() {});
-		
-		Collections.sort(objFromJson, new Comparator<BundleJsonNoSubscriptions>() {
-			@Override
-			public int compare(BundleJsonNoSubscriptions o1, BundleJsonNoSubscriptions o2) {
-				return o1.getExternalKey().compareTo(o2.getExternalKey());
-			}
-		});
-		Assert.assertEquals(objFromJson.get(0), bundleJson1);
-		Assert.assertEquals(objFromJson.get(1), bundleJson2);		
-	}
-	
-	@Test(groups="slow", enabled=true)
-	public void testBundleNonExistent() throws Exception {
-		AccountJson accountJson = createAccount("dfdf", "dfdfgfhkkl", "dfdf@yahoo.com");	
-		
-		String uri = JaxrsResource.BUNDLES_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
-		Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-		
-		
-		// Retrieves by external key
-		Map<String, String> queryParams = new HashMap<String, String>();
-		queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "56566");
-		response = doGet(JaxrsResource.BUNDLES_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-		
-		
-		uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId().toString() + "/" + JaxrsResource.BUNDLES;
-		response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-		String baseJson = response.getResponseBody();
-		List<BundleJsonNoSubscriptions> objFromJson = mapper.readValue(baseJson, new TypeReference<List<BundleJsonNoSubscriptions>>() {});
-		Assert.assertNotNull(objFromJson);
-		Assert.assertEquals(objFromJson.size(), 0);
-	}
-
-	@Test(groups="slow", enabled=true)
-	public void testAppNonExistent() throws Exception {
-		String uri = JaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747/" + JaxrsResource.BUNDLES;
-		Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());	
-	}
-	
-	
+    private static final Logger log = LoggerFactory.getLogger(TestBundle.class);
+
+
+    @Test(groups = "slow", enabled = true)
+    public void testBundleOk() throws Exception {
+
+        final AccountJson accountJson = createAccount("xlxl", "shdgfhkkl", "xlxl@yahoo.com");
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "12345");
+
+        // Retrieves by external key
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "12345");
+        final Response response = doGet(JaxrsResource.BUNDLES_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+        final BundleJsonNoSubscriptions objFromJson = mapper.readValue(baseJson, BundleJsonNoSubscriptions.class);
+        Assert.assertTrue(objFromJson.equals(bundleJson));
+    }
+
+
+    @Test(groups = "slow", enabled = true)
+    public void testBundleFromAccount() throws Exception {
+
+        final AccountJson accountJson = createAccount("xaxa", "saagfhkkl", "xaxa@yahoo.com");
+        final BundleJsonNoSubscriptions bundleJson1 = createBundle(accountJson.getAccountId(), "156567");
+        final BundleJsonNoSubscriptions bundleJson2 = createBundle(accountJson.getAccountId(), "265658");
+
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId().toString() + "/" + JaxrsResource.BUNDLES;
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+        final List<BundleJsonNoSubscriptions> objFromJson = mapper.readValue(baseJson, new TypeReference<List<BundleJsonNoSubscriptions>>() {});
+
+        Collections.sort(objFromJson, new Comparator<BundleJsonNoSubscriptions>() {
+            @Override
+            public int compare(final BundleJsonNoSubscriptions o1, final BundleJsonNoSubscriptions o2) {
+                return o1.getExternalKey().compareTo(o2.getExternalKey());
+            }
+        });
+        Assert.assertEquals(objFromJson.get(0), bundleJson1);
+        Assert.assertEquals(objFromJson.get(1), bundleJson2);
+    }
+
+    @Test(groups = "slow", enabled = true)
+    public void testBundleNonExistent() throws Exception {
+        final AccountJson accountJson = createAccount("dfdf", "dfdfgfhkkl", "dfdf@yahoo.com");
+
+        String uri = JaxrsResource.BUNDLES_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
+        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+
+
+        // Retrieves by external key
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "56566");
+        response = doGet(JaxrsResource.BUNDLES_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+
+
+        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId().toString() + "/" + JaxrsResource.BUNDLES;
+        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+        final List<BundleJsonNoSubscriptions> objFromJson = mapper.readValue(baseJson, new TypeReference<List<BundleJsonNoSubscriptions>>() {});
+        Assert.assertNotNull(objFromJson);
+        Assert.assertEquals(objFromJson.size(), 0);
+    }
+
+    @Test(groups = "slow", enabled = true)
+    public void testAppNonExistent() throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747/" + JaxrsResource.BUNDLES;
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+    }
+
+
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java b/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java
new file mode 100644
index 0000000..c785643
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java
@@ -0,0 +1,41 @@
+/* 
+ * Copyright 2010-2011 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;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.jaxrs.json.CatalogJsonSimple;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.http.client.Response;
+
+public class TestCatalog extends TestJaxrsBase {
+
+    private static final Logger log = LoggerFactory.getLogger(TestAccount.class);
+
+    @Test(groups = "slow", enabled = true)
+    public void testCatalogSimple() throws Exception {
+        Response response = doGet(JaxrsResource.CATALOG_PATH + "/simpleCatalog", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        String body = response.getResponseBody();
+        CatalogJsonSimple objFromJson = mapper.readValue(body, CatalogJsonSimple.class);
+        log.info("Yeaahh...");
+    }
+}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java b/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
index 1751d2b..9dc8d51 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
@@ -18,41 +18,42 @@ package com.ning.billing.jaxrs;
 
 import java.io.IOException;
 import java.math.BigDecimal;
+import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import com.ning.billing.invoice.api.InvoicePayment;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.collect.ImmutableMap;
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.jaxrs.json.AccountJson;
+import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
 import com.ning.billing.jaxrs.json.ChargebackCollectionJson;
 import com.ning.billing.jaxrs.json.ChargebackJson;
+import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
+import com.ning.billing.jaxrs.json.PaymentJsonSimple;
+import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
 
 public class TestChargeback extends TestJaxrsBase {
-    private final String accountId = UUID.randomUUID().toString();
-    private InvoicePayment invoicePayment;
-
-    @BeforeMethod(groups = "slow")
-    public void setUp() throws Exception {
-        invoicePayment = createInvoicePayment();
-    }
-
-    @Test(groups = "slow", enabled = false)
+    @Test(groups = "slow")
     public void testAddChargeback() throws Exception {
-        final ChargebackJson input = new ChargebackJson(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC),
-                                                        BigDecimal.TEN, UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        final PaymentJsonSimple payment = createInvoicePayment();
+        final ChargebackJson input = new ChargebackJson(null, null, BigDecimal.TEN, payment.getPaymentId(), null);
         final String jsonInput = mapper.writeValueAsString(input);
 
         // Create the chargeback
         Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode(), response.getResponseBody());
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.CREATED.getStatusCode(), response.getResponseBody());
 
         // Find the chargeback by location
         final String location = response.getHeader("Location");
@@ -61,11 +62,11 @@ public class TestChargeback extends TestJaxrsBase {
         verifySingleChargebackResponse(response, input);
 
         // Find the chargeback by account
-        response = doGet(JaxrsResource.CHARGEBACKS_PATH + "/accounts/" + accountId, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        response = doGet(JaxrsResource.CHARGEBACKS_PATH + "/accounts/" + payment.getAccountId(), DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         verifyCollectionChargebackResponse(response, input);
 
         // Find the chargeback by payment
-        response = doGet(JaxrsResource.CHARGEBACKS_PATH + "/payments/" + input.getPaymentId(), DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        response = doGet(JaxrsResource.CHARGEBACKS_PATH + "/payments/" + payment.getPaymentId(), DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         verifyCollectionChargebackResponse(response, input);
     }
 
@@ -73,13 +74,13 @@ public class TestChargeback extends TestJaxrsBase {
         assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
         final ChargebackCollectionJson objFromJson = mapper.readValue(response.getResponseBody(), ChargebackCollectionJson.class);
         assertEquals(objFromJson.getChargebacks().size(), 1);
-        assertEquals(objFromJson.getChargebacks().get(0), input);
+        assertTrue(objFromJson.getChargebacks().get(0).getChargebackAmount().compareTo(input.getChargebackAmount()) == 0);
     }
 
     private void verifySingleChargebackResponse(final Response response, final ChargebackJson input) throws IOException {
         assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
         final ChargebackJson objFromJson = mapper.readValue(response.getResponseBody(), ChargebackJson.class);
-        assertEquals(objFromJson, input);
+        assertTrue(objFromJson.getChargebackAmount().compareTo(input.getChargebackAmount()) == 0);
     }
 
     @Test(groups = "slow")
@@ -123,8 +124,50 @@ public class TestChargeback extends TestJaxrsBase {
         //assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.getResponseBody());
     }
 
-    private InvoicePayment createInvoicePayment() {
-        // TODO - blocked on payment resource
-        return null;
+    private PaymentJsonSimple createInvoicePayment() throws Exception {
+        final InvoiceJsonSimple invoice = createInvoice();
+        return getPayment(invoice);
+    }
+
+    private InvoiceJsonSimple createInvoice() throws Exception {
+        // Create account
+        final AccountJson accountJson = createAccountWithDefaultPaymentMethod(UUID.randomUUID().toString(), UUID.randomUUID().toString(), "nohup@yahoo.com");
+
+        // Create bundle
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), UUID.randomUUID().toString());
+        assertNotNull(bundleJson);
+
+        // Create subscription
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        assertNotNull(subscriptionJson);
+
+        // Move after the trial period to trigger an invoice with a non-zero invoice item
+        clock.addDays(32);
+        crappyWaitForLackOfProperSynchonization();
+
+        // Retrieve the invoice
+        final Response response = doGet(JaxrsResource.INVOICES_PATH, ImmutableMap.<String, String>of(JaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId()), DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+        final List<InvoiceJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
+        assertNotNull(objFromJson);
+        // We should have two invoices, one for the trial (zero dollar amount) and one for the first month
+        assertEquals(objFromJson.size(), 2);
+        assertTrue(objFromJson.get(1).getAmount().doubleValue() > 0);
+
+        return objFromJson.get(1);
+    }
+
+    private PaymentJsonSimple getPayment(final InvoiceJsonSimple invoice) throws IOException {
+        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoice.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+        Assert.assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+        final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+        assertNotNull(objFromJson);
+        assertEquals(objFromJson.size(), 1);
+
+        return objFromJson.get(0);
     }
 }
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 5636796..36f7b53 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
@@ -15,22 +15,14 @@
  */
 package com.ning.billing.jaxrs;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
+import javax.ws.rs.core.Response.Status;
 import java.math.BigDecimal;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import javax.ws.rs.core.Response.Status;
-
-import com.ning.billing.jaxrs.resources.JaxrsResource;
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
-import org.joda.time.format.DateTimeFormatter;
-import org.joda.time.format.ISODateTimeFormat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
@@ -44,40 +36,38 @@ import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
 import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
 import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
-public class TestInvoice extends TestJaxrsBase  {
-
-    private final DateTimeFormatter DATE_TIME_FORMATTER = ISODateTimeFormat.dateTime();
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
 
+public class TestInvoice extends TestJaxrsBase {
     private static final Logger log = LoggerFactory.getLogger(TestInvoice.class);
 
-
-    @Test(groups="slow", enabled=true)
+    @Test(groups = "slow")
     public void testInvoiceOk() throws Exception {
-
-        DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
+        final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
 
-
-        AccountJson accountJson = createAccount("poupou", "qhddffrwe", "poupou@yahoo.com");
+        final AccountJson accountJson = createAccount("poupou", "qhddffrwe", "poupou@yahoo.com");
         assertNotNull(accountJson);
 
-        BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "9967599");
-
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "9967599");
         assertNotNull(bundleJson);
 
-        SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
         assertNotNull(subscriptionJson);
 
         // MOVE AFTER TRIAL
-        Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(3).plusDays(1));
+        final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(3).plusDays(1));
         clock.addDeltaFromReality(it.toDurationMillis());
 
         crappyWaitForLackOfProperSynchonization();
 
         String uri = JaxrsResource.INVOICES_PATH;
-        Map<String, String> queryParams = new HashMap<String, String>();
+        final Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId());
 
         Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -91,22 +81,22 @@ public class TestInvoice extends TestJaxrsBase  {
         // Check we can retrieve an individual invoice
         uri = JaxrsResource.INVOICES_PATH + "/" + objFromJson.get(0).getInvoiceId();
         response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());        
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         baseJson = response.getResponseBody();
-        InvoiceJsonSimple firstInvoiceJson = mapper.readValue(baseJson, InvoiceJsonSimple.class);
-        assertNotNull(objFromJson);    
+        final InvoiceJsonSimple firstInvoiceJson = mapper.readValue(baseJson, InvoiceJsonSimple.class);
+        assertNotNull(objFromJson);
         assertEquals(firstInvoiceJson, objFromJson.get(0));
 
         // Then create a dryRun Invoice
-        DateTime futureDate = clock.getUTCNow().plusMonths(1).plusDays(3);
+        final DateTime futureDate = clock.getUTCNow().plusMonths(1).plusDays(3);
         uri = JaxrsResource.INVOICES_PATH;
         queryParams.put(JaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
         queryParams.put(JaxrsResource.QUERY_DRY_RUN, "true");
         response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode()); 
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         baseJson = response.getResponseBody();
-        InvoiceJsonSimple futureInvoice = mapper.readValue(baseJson, InvoiceJsonSimple.class);
-        assertNotNull(futureInvoice);    
+        final InvoiceJsonSimple futureInvoice = mapper.readValue(baseJson, InvoiceJsonSimple.class);
+        assertNotNull(futureInvoice);
         log.info(baseJson);
 
         // The one more time with no DryRun
@@ -114,7 +104,7 @@ public class TestInvoice extends TestJaxrsBase  {
         response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        String location = response.getHeader("Location");
+        final String location = response.getHeader("Location");
         Assert.assertNotNull(location);
 
         // Check again # invoices, should be 5 this time
@@ -128,18 +118,17 @@ public class TestInvoice extends TestJaxrsBase  {
         assertEquals(objFromJson.size(), 5);
     }
 
-    @Test(groups="slow", enabled=true)
+    @Test(groups = "slow")
     public void testInvoicePayments() throws Exception {
-
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
-        AccountJson accountJson = createAccountWithDefaultPaymentMethod("nohup", "shtergyhwF", "nohup@yahoo.com");
+        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("nohup", "shtergyhwF", "nohup@yahoo.com");
         assertNotNull(accountJson);
 
-        BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "391193");
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "391193");
         assertNotNull(bundleJson);
 
-        SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
         assertNotNull(subscriptionJson);
 
         // MOVE AFTER TRIAL
@@ -147,26 +136,25 @@ public class TestInvoice extends TestJaxrsBase  {
 
         crappyWaitForLackOfProperSynchonization();
 
-        Map<String, String> queryParams = new HashMap<String, String>();
+        final Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId());
         String uri = JaxrsResource.INVOICES_PATH;
         Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         String baseJson = response.getResponseBody();
-        List<InvoiceJsonSimple> invoices = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
+        final List<InvoiceJsonSimple> invoices = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
         assertNotNull(invoices);
         log.info(baseJson);
         assertEquals(invoices.size(), 4);
 
+        for (final InvoiceJsonSimple cur : invoices) {
 
-        for (InvoiceJsonSimple cur : invoices) {
-
-            uri = JaxrsResource.INVOICES_PATH + "/" + cur.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;    
+            uri = JaxrsResource.INVOICES_PATH + "/" + cur.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
             response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
 
             Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
             baseJson = response.getResponseBody();
-            List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+            final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
             assertNotNull(objFromJson);
             log.info(cur.getAmount().toString());
             if (cur.getAmount().compareTo(BigDecimal.ZERO) == 0) {
@@ -178,24 +166,19 @@ public class TestInvoice extends TestJaxrsBase  {
         }
     }
 
-
-
-    @Test(groups="slow", enabled=true)
+    @Test(groups = "slow")
     public void testInvoiceCreatePayment() throws Exception {
-
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
-        AccountJson accountJson = createAccountWithDefaultPaymentMethod("nohup", "shtergyhwF", "nohup@yahoo.com");
+        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("nohup", "shtergyhwF", "nohup@yahoo.com");
         assertNotNull(accountJson);
 
-
         // STEPH MISSING SET ACCOUNT AUTO_PAY_OFF
 
-
-        BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "391193");
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "391193");
         assertNotNull(bundleJson);
 
-        SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
         assertNotNull(subscriptionJson);
 
         // MOVE AFTER TRIAL
@@ -203,35 +186,34 @@ public class TestInvoice extends TestJaxrsBase  {
 
         crappyWaitForLackOfProperSynchonization();
 
-        Map<String, String> queryParams = new HashMap<String, String>();
+        final Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId());
         String uri = JaxrsResource.INVOICES_PATH;
         Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         String baseJson = response.getResponseBody();
-        List<InvoiceJsonSimple> invoices = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
+        final List<InvoiceJsonSimple> invoices = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
         assertNotNull(invoices);
         log.info(baseJson);
         assertEquals(invoices.size(), 2);
 
-
-        for (InvoiceJsonSimple cur : invoices) {
+        for (final InvoiceJsonSimple cur : invoices) {
             if (cur.getAmount().compareTo(BigDecimal.ZERO) == 0) {
                 continue;
             }
 
             // CREATE INSTA PAYMENT
-            PaymentJsonSimple payment = new PaymentJsonSimple(cur.getAmount(), BigDecimal.ZERO, accountJson.getAccountId(), cur.getInvoiceId(), null, null, null, 0, null, null);
-            String postJson = mapper.writeValueAsString(payment);
-            
-            uri = JaxrsResource.INVOICES_PATH + "/" + cur.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;    
-            response = doPost(uri, postJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+            final PaymentJsonSimple payment = new PaymentJsonSimple(cur.getAmount(), BigDecimal.ZERO, accountJson.getAccountId(), cur.getInvoiceId(), null, null, null, 0, null, null);
+            final String postJson = mapper.writeValueAsString(payment);
+
+            uri = JaxrsResource.INVOICES_PATH + "/" + cur.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
+            doPost(uri, postJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
 
             response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
 
             Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
             baseJson = response.getResponseBody();
-            List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+            final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
             assertNotNull(objFromJson);
             log.info(cur.getAmount().toString());
             assertEquals(objFromJson.size(), 1);
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java
new file mode 100644
index 0000000..370ce77
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.collect.ImmutableMap;
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.jaxrs.json.AccountJson;
+import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
+import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
+import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.http.client.Response;
+
+public class TestInvoiceNotification extends TestJaxrsBase {
+    @Test(groups = "slow")
+    public void testTriggerNotification() throws Exception {
+        final AccountJson accountJson = createScenarioWithOneInvoice();
+
+        final String uri = JaxrsResource.INVOICES_PATH;
+        final Response response = doGet(uri, ImmutableMap.<String, String>of(JaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId()), DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+        final List<InvoiceJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
+        Assert.assertEquals(objFromJson.size(), 1);
+
+        final InvoiceJsonSimple invoice = objFromJson.get(0);
+        final Response triggerResponse = doPost(uri + "/" + invoice.getInvoiceId() + "/" + JaxrsResource.EMAIL_NOTIFICATIONS,
+                                                null, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(triggerResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+    }
+
+    private AccountJson createScenarioWithOneInvoice() throws Exception {
+        final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
+        clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
+
+        final AccountJson accountJson = createAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        Assert.assertNotNull(accountJson);
+
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), UUID.randomUUID().toString());
+        Assert.assertNotNull(bundleJson);
+
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        Assert.assertNotNull(subscriptionJson);
+
+        return accountJson;
+    }
+}
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 d7f9f27..1b7008a 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -15,12 +15,12 @@
  */
 package com.ning.billing.jaxrs;
 
-import static org.testng.Assert.assertNotNull;
-
+import javax.annotation.Nullable;
+import javax.ws.rs.core.Response.Status;
 import java.io.IOException;
+import java.lang.reflect.Method;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.EventListener;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -30,20 +30,13 @@ import java.util.Map.Entry;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
-import javax.ws.rs.core.Response.Status;
-
-import com.google.common.io.Resources;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.billing.util.email.EmailModule;
-import com.ning.billing.util.email.templates.TemplateModule;
-import com.ning.billing.util.glue.GlobalLockerModule;
-import org.apache.commons.io.IOUtils;
 import org.eclipse.jetty.servlet.FilterHolder;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
 import org.testng.annotations.AfterSuite;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
@@ -52,7 +45,6 @@ import org.testng.annotations.BeforeSuite;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.datatype.joda.JodaModule;
-
 import com.google.inject.Module;
 import com.ning.billing.account.glue.AccountModule;
 import com.ning.billing.analytics.setup.AnalyticsModule;
@@ -66,13 +58,16 @@ import com.ning.billing.dbi.DBIProvider;
 import com.ning.billing.dbi.DbiConfig;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
+import com.ning.billing.invoice.api.InvoiceNotifier;
 import com.ning.billing.invoice.glue.DefaultInvoiceModule;
+import com.ning.billing.invoice.notification.NullInvoiceNotifier;
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
 import com.ning.billing.jaxrs.json.PaymentMethodJson;
 import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodPluginDetailJson;
 import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodProperties;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.billing.junction.glue.DefaultJunctionModule;
 import com.ning.billing.payment.glue.PaymentModule;
 import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
@@ -80,11 +75,15 @@ import com.ning.billing.server.listeners.KillbillGuiceListener;
 import com.ning.billing.server.modules.KillbillServerModule;
 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.BusModule;
 import com.ning.billing.util.glue.CallContextModule;
 import com.ning.billing.util.glue.CustomFieldModule;
+import com.ning.billing.util.glue.GlobalLockerModule;
 import com.ning.billing.util.glue.NotificationQueueModule;
 import com.ning.billing.util.glue.TagStoreModule;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.http.client.AsyncCompletionHandler;
 import com.ning.http.client.AsyncHttpClient;
 import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
@@ -94,12 +93,13 @@ import com.ning.http.client.Response;
 import com.ning.jetty.core.CoreConfig;
 import com.ning.jetty.core.server.HttpServer;
 
-public class TestJaxrsBase {
+import static org.testng.Assert.assertNotNull;
 
-    protected final static String PLUGIN_NAME = "noop";
+public class TestJaxrsBase {
+    protected static final String PLUGIN_NAME = "noop";
 
     // STEPH
-    protected static final int DEFAULT_HTTP_TIMEOUT_SEC =  6000; // 5;
+    protected static final int DEFAULT_HTTP_TIMEOUT_SEC = 6000; // 5;
 
     protected static final Map<String, String> DEFAULT_EMPTY_QUERY = new HashMap<String, String>();
 
@@ -109,13 +109,12 @@ public class TestJaxrsBase {
     public static final String CONTENT_TYPE = "application/json";
 
     private static TestKillbillGuiceListener listener;
-    
-    
+
     private MysqlTestingHelper helper;
     private HttpServer server;
 
     protected CoreConfig config;
-    protected AsyncHttpClient httpClient;	
+    protected AsyncHttpClient httpClient;
     protected ObjectMapper mapper;
     protected ClockMock clock;
     protected TestApiListener busHandler;
@@ -123,8 +122,8 @@ public class TestJaxrsBase {
     // Context information to be passed around
     private static final String createdBy = "Toto";
     private static final String reason = "i am god";
-    private static final String comment = "no comment";    
-    
+    private static final String comment = "no comment";
+
     public static void loadSystemPropertiesFromClasspath(final String resource) {
         final URL url = TestJaxrsBase.class.getResource(resource);
         assertNotNull(url);
@@ -133,32 +132,23 @@ public class TestJaxrsBase {
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
-
-        // Use the full path for the catalog
-        final String catalogURI = System.getProperty("killbill.catalog.uri");
-        if (catalogURI != null) {
-            try {
-                System.setProperty("killbill.catalog.uri", Resources.getResource(catalogURI).toExternalForm());
-            } catch (IllegalArgumentException ignored) {
-            }
-        }
     }
 
     public static class TestKillbillGuiceListener extends KillbillGuiceListener {
-        
         private final MysqlTestingHelper helper;
         private final Clock clock;
-        
+
         public TestKillbillGuiceListener(final MysqlTestingHelper helper, final Clock clock) {
             super();
             this.helper = helper;
             this.clock = clock;
         }
+
         @Override
         protected Module getModule() {
             return new TestKillbillServerModule(helper, clock);
         }
-        
+
         //
         // Listener is created once before Suite and keeps pointer to helper and clock so they can get
         // reset for each test Class-- needed in order to ONLY start Jetty once across all the test classes
@@ -167,37 +157,42 @@ public class TestJaxrsBase {
         public MysqlTestingHelper getMysqlTestingHelper() {
             return helper;
         }
-        
+
         public Clock getClock() {
             return clock;
         }
     }
 
-    public static class TestKillbillServerModule extends KillbillServerModule {
+    public static class InvoiceModuleWithMockSender extends DefaultInvoiceModule {
+        @Override
+        protected void installInvoiceNotifier() {
+            bind(InvoiceNotifier.class).to(NullInvoiceNotifier.class).asEagerSingleton();
+        }
+    }
 
+    public static class TestKillbillServerModule extends KillbillServerModule {
         private final MysqlTestingHelper helper;
         private final Clock clock;
-        
+
         public TestKillbillServerModule(final MysqlTestingHelper helper, final Clock clock) {
             super();
             this.helper = helper;
             this.clock = clock;
         }
-        
+
         @Override
         protected void installClock() {
             bind(Clock.class).toInstance(clock);
         }
 
-
         private static final class PaymentMockModule extends PaymentModule {
             @Override
-            protected void installPaymentProviderPlugins(PaymentConfig config) {
+            protected void installPaymentProviderPlugins(final PaymentConfig config) {
                 install(new MockPaymentProviderPluginModule(PLUGIN_NAME));
             }
         }
 
-        protected void installKillbillModules(){
+        protected void installKillbillModules() {
 
             /*
              * For a lack of getting module override working, copy all install modules from parent class...
@@ -214,7 +209,7 @@ public class TestJaxrsBase {
             install(new NotificationQueueModule());
             install(new CallContextModule());
             install(new AccountModule());
-            install(new DefaultInvoiceModule());
+            install(new InvoiceModuleWithMockSender());
             install(new TemplateModule());
             install(new DefaultEntitlementModule());
             install(new AnalyticsModule());
@@ -238,13 +233,24 @@ public class TestJaxrsBase {
         }
     }
 
-    @BeforeMethod(groups="slow")
-    public void cleanupBeforeMethod() {
+    @BeforeMethod(groups = "slow")
+    public void cleanupBeforeMethod(final Method method) {
+        log.info("***************************************************************************************************");
+        log.info("*** Starting test {}:{}", method.getDeclaringClass().getName(), method.getName());
+        log.info("***************************************************************************************************");
+
         busHandler.reset();
         helper.cleanupAllTables();
     }
 
-    @BeforeClass(groups="slow")
+    @AfterMethod(groups = "slow")
+    public void endTest(final Method method) throws Exception {
+        log.info("***************************************************************************************************");
+        log.info("***   Ending test {}:{}", method.getDeclaringClass().getName(), method.getName());
+        log.info("***************************************************************************************************");
+    }
+
+    @BeforeClass(groups = "slow")
     public void setupClass() throws IOException {
         loadConfig();
         httpClient = new AsyncHttpClient(new AsyncHttpClientConfig.Builder().setRequestTimeoutInMs(DEFAULT_HTTP_TIMEOUT_SEC * 1000).build());
@@ -256,17 +262,17 @@ public class TestJaxrsBase {
 
         busHandler = new TestApiListener(null);
         this.helper = listener.getMysqlTestingHelper();
-        this.clock =  (ClockMock) listener.getClock();
+        this.clock = (ClockMock) listener.getClock();
     }
-    
+
     private void setupMySQL() throws IOException {
         final String accountDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
         final String entitlementDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
         final String invoiceDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
         final String paymentDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/payment/ddl.sql"));
         final String utilDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
-        final String analyticsDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/analytics/ddl.sql"));        
-        final String junctionDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/junction/ddl.sql"));        
+        final String analyticsDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/analytics/ddl.sql"));
+        final String junctionDdl = IOUtils.toString(TestIntegration.class.getResourceAsStream("/com/ning/billing/junction/ddl.sql"));
 
         helper.startMysql();
 
@@ -275,10 +281,9 @@ public class TestJaxrsBase {
         helper.initDb(invoiceDdl);
         helper.initDb(paymentDdl);
         helper.initDb(utilDdl);
-        helper.initDb(analyticsDdl);        
-        helper.initDb(junctionDdl);        
-   }
-
+        helper.initDb(analyticsDdl);
+        helper.initDb(junctionDdl);
+    }
 
     private void loadConfig() {
         if (config == null) {
@@ -286,12 +291,12 @@ public class TestJaxrsBase {
         }
     }
 
-    @BeforeSuite(groups="slow")
+    @BeforeSuite(groups = "slow")
     public void setup() throws Exception {
 
         loadSystemPropertiesFromClasspath("/killbill.properties");
         loadConfig();
-        
+
         this.helper = new MysqlTestingHelper();
         this.clock = new ClockMock();
         listener = new TestKillbillGuiceListener(helper, clock);
@@ -300,7 +305,7 @@ public class TestJaxrsBase {
         final Iterable<EventListener> eventListeners = new Iterable<EventListener>() {
             @Override
             public Iterator<EventListener> iterator() {
-                ArrayList<EventListener> array = new ArrayList<EventListener>();
+                final ArrayList<EventListener> array = new ArrayList<EventListener>();
                 array.add(listener);
                 return array.iterator();
             }
@@ -313,82 +318,81 @@ public class TestJaxrsBase {
         server.start();
     }
 
-    @AfterSuite(groups="slow")
+    @AfterSuite(groups = "slow")
     public void tearDown() {
         try {
             server.stop();
-        } catch (Exception e) {
-
+        } catch (Exception ignored) {
         }
+
         if (helper != null) {
             helper.stopMysql();
         }
     }
 
-    
     protected List<PaymentMethodProperties> getPaymentMethodCCProperties() {
-        List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>();
+        final List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>();
         properties.add(new PaymentMethodProperties("type", "CreditCard", false));
         properties.add(new PaymentMethodProperties("cardType", "Visa", false));
         properties.add(new PaymentMethodProperties("cardHolderName", "Mr Sniff", false));
-        properties.add(new PaymentMethodProperties("expirationDate", "2015-08", false));        
+        properties.add(new PaymentMethodProperties("expirationDate", "2015-08", false));
         properties.add(new PaymentMethodProperties("maskNumber", "3451", false));
         properties.add(new PaymentMethodProperties("address1", "23, rue des cerisiers", false));
         properties.add(new PaymentMethodProperties("address2", "", false));
-        properties.add(new PaymentMethodProperties("city", "Toulouse", false));        
+        properties.add(new PaymentMethodProperties("city", "Toulouse", false));
         properties.add(new PaymentMethodProperties("country", "France", false));
         properties.add(new PaymentMethodProperties("postalCode", "31320", false));
         properties.add(new PaymentMethodProperties("state", "Midi-Pyrenees", false));
         return properties;
     }
-    
-    
-  protected List<PaymentMethodProperties> getPaymentMethodPaypalProperties() {
-        List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>();
+
+
+    protected List<PaymentMethodProperties> getPaymentMethodPaypalProperties() {
+        final List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>();
         properties.add(new PaymentMethodProperties("type", "CreditCard", false));
         properties.add(new PaymentMethodProperties("email", "zouzou@laposte.fr", false));
         properties.add(new PaymentMethodProperties("baid", "23-8787d-R", false));
         return properties;
     }
-    
-    
-    protected PaymentMethodJson getPaymentMethodJson(String accountId, List<PaymentMethodProperties> properties) {
-        PaymentMethodPluginDetailJson info = new PaymentMethodPluginDetailJson(null, properties);
+
+
+    protected PaymentMethodJson getPaymentMethodJson(final String accountId, final List<PaymentMethodProperties> properties) {
+        final PaymentMethodPluginDetailJson info = new PaymentMethodPluginDetailJson(null, properties);
         return new PaymentMethodJson(null, accountId, true, PLUGIN_NAME, info);
     }
-    
-    protected AccountJson createAccountWithDefaultPaymentMethod(String name, String key, String email) throws Exception {
-        
-        AccountJson input = createAccount(name, key, email);
-        
+
+    protected AccountJson createAccountWithDefaultPaymentMethod(final String name, final String key, final String email) throws Exception {
+
+        final AccountJson input = createAccount(name, key, email);
+
         final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
-        PaymentMethodJson paymentMethodJson = getPaymentMethodJson(input.getAccountId(), null);
+        final PaymentMethodJson paymentMethodJson = getPaymentMethodJson(input.getAccountId(), null);
         String baseJson = mapper.writeValueAsString(paymentMethodJson);
         Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_PAYMENT_METHOD_IS_DEFAULT, "true");
-        
+
         Response response = doPost(uri, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        
+
         queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, input.getExternalKey());
         response = doGet(JaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         baseJson = response.getResponseBody();
-        AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
+        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
         Assert.assertNotNull(objFromJson);
         Assert.assertNotNull(objFromJson.getPaymentMethodId());
         return objFromJson;
     }
-    
-    protected AccountJson createAccount(String name, String key, String email) throws Exception {
-        AccountJson input = getAccountJson(name, key, email);
+
+    protected AccountJson createAccount(final String name, final String key, final String email) throws Exception {
+        final AccountJson input = getAccountJson(name, key, email);
         String baseJson = mapper.writeValueAsString(input);
         Response response = doPost(JaxrsResource.ACCOUNTS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        String location = response.getHeader("Location");
+        final String location = response.getHeader("Location");
         Assert.assertNotNull(location);
 
         // Retrieves by Id based on Location returned
@@ -396,20 +400,19 @@ public class TestJaxrsBase {
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
 
         baseJson = response.getResponseBody();
-        AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
+        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
         Assert.assertNotNull(objFromJson);
         return objFromJson;
     }
 
 
-
-    protected BundleJsonNoSubscriptions createBundle(String accountId, String key) throws Exception {
-        BundleJsonNoSubscriptions input = new BundleJsonNoSubscriptions(null, accountId, key, null);
+    protected BundleJsonNoSubscriptions createBundle(final String accountId, final String key) throws Exception {
+        final BundleJsonNoSubscriptions input = new BundleJsonNoSubscriptions(null, accountId, key, 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());
 
-        String location = response.getHeader("Location");
+        final String location = response.getHeader("Location");
         Assert.assertNotNull(location);
 
         // Retrieves by Id based on Location returned
@@ -417,22 +420,22 @@ public class TestJaxrsBase {
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
 
         baseJson = response.getResponseBody();
-        BundleJsonNoSubscriptions objFromJson = mapper.readValue(baseJson, BundleJsonNoSubscriptions.class);
+        final BundleJsonNoSubscriptions objFromJson = mapper.readValue(baseJson, BundleJsonNoSubscriptions.class);
         Assert.assertTrue(objFromJson.equalsNoId(input));
         return objFromJson;
     }
 
     protected SubscriptionJsonNoEvents createSubscription(final String bundleId, final String productName, final String productCategory, final String billingPeriod, final boolean waitCompletion) throws Exception {
 
-        SubscriptionJsonNoEvents input = new SubscriptionJsonNoEvents(null, bundleId, null, productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+        final SubscriptionJsonNoEvents input = new SubscriptionJsonNoEvents(null, bundleId, null, productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
         String baseJson = mapper.writeValueAsString(input);
 
 
-        Map<String, String> queryParams = waitCompletion ? getQueryParamsForCallCompletion("5") : DEFAULT_EMPTY_QUERY;
+        final Map<String, String> queryParams = waitCompletion ? getQueryParamsForCallCompletion("5") : DEFAULT_EMPTY_QUERY;
         Response response = doPost(JaxrsResource.SUBSCRIPTIONS_PATH, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        String location = response.getHeader("Location");
+        final String location = response.getHeader("Location");
         Assert.assertNotNull(location);
 
         // Retrieves by Id based on Location returned
@@ -441,13 +444,13 @@ public class TestJaxrsBase {
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
 
         baseJson = response.getResponseBody();
-        SubscriptionJsonNoEvents objFromJson = mapper.readValue(baseJson, SubscriptionJsonNoEvents.class);
+        final SubscriptionJsonNoEvents objFromJson = mapper.readValue(baseJson, SubscriptionJsonNoEvents.class);
         Assert.assertTrue(objFromJson.equalsNoSubscriptionIdNoStartDateNoCTD(input));
         return objFromJson;
     }
 
     protected Map<String, String> getQueryParamsForCallCompletion(final String timeoutSec) {
-        Map<String, String> queryParams = new HashMap<String, String>();
+        final Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_CALL_COMPLETION, "true");
         queryParams.put(JaxrsResource.QUERY_CALL_TIMEOUT, timeoutSec);
         return queryParams;
@@ -456,8 +459,8 @@ public class TestJaxrsBase {
     //
     // HTTP CLIENT HELPERS
     //
-    protected Response doPost(final String uri, final String body, final Map<String, String> queryParams, final int timeoutSec) {
-        BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("POST", getUrlFromUri(uri), queryParams);
+    protected Response doPost(final String uri, @Nullable final String body, final Map<String, String> queryParams, final int timeoutSec) {
+        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("POST", getUrlFromUri(uri), queryParams);
         if (body != null) {
             builder.setBody(body);
         } else {
@@ -468,7 +471,7 @@ public class TestJaxrsBase {
 
     protected Response doPut(final String uri, final String body, final Map<String, String> queryParams, final int timeoutSec) {
         final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-        BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("PUT", url, queryParams);
+        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("PUT", url, queryParams);
         if (body != null) {
             builder.setBody(body);
         } else {
@@ -479,7 +482,7 @@ public class TestJaxrsBase {
 
     protected Response doDelete(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
         final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-        BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("DELETE", url, queryParams);
+        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("DELETE", url, queryParams);
         return executeAndWait(builder, timeoutSec, true);
     }
 
@@ -489,30 +492,30 @@ public class TestJaxrsBase {
     }
 
     protected Response doGetWithUrl(final String url, final Map<String, String> queryParams, final int timeoutSec) {
-        BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("GET", url, queryParams);
+        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("GET", url, queryParams);
         return executeAndWait(builder, timeoutSec, false);
     }
 
     private Response executeAndWait(final BoundRequestBuilder builder, final int timeoutSec, final boolean addContextHeader) {
-        
+
         if (addContextHeader) {
             builder.addHeader(JaxrsResource.HDR_CREATED_BY, createdBy);
             builder.addHeader(JaxrsResource.HDR_REASON, reason);
             builder.addHeader(JaxrsResource.HDR_COMMENT, comment);
         }
-        
+
         Response response = null;
         try {
-            ListenableFuture<Response> futureStatus = 
-                builder.execute(new AsyncCompletionHandler<Response>() {
-                    @Override
-                    public Response onCompleted(Response response) throws Exception {
-                        return response;
-                    }
-                });
+            final ListenableFuture<Response> futureStatus =
+                    builder.execute(new AsyncCompletionHandler<Response>() {
+                        @Override
+                        public Response onCompleted(final Response response) throws Exception {
+                            return response;
+                        }
+                    });
             response = futureStatus.get(timeoutSec, TimeUnit.SECONDS);
         } catch (Exception e) {
-            Assert.fail(e.getMessage());			
+            Assert.fail(e.getMessage());
         }
         Assert.assertNotNull(response);
         return response;
@@ -529,43 +532,43 @@ public class TestJaxrsBase {
         } else if (verb.equals("POST")) {
             builder = httpClient.preparePost(url);
         } else if (verb.equals("PUT")) {
-            builder = httpClient.preparePut(url);			
+            builder = httpClient.preparePut(url);
         } else if (verb.equals("DELETE")) {
-            builder = httpClient.prepareDelete(url);			
+            builder = httpClient.prepareDelete(url);
+        } else {
+            Assert.fail("Unknown verb " + verb);
         }
+
         builder.addHeader(HEADER_CONTENT_TYPE, CONTENT_TYPE);
-        for (Entry<String, String> q : queryParams.entrySet()) {
+        for (final Entry<String, String> q : queryParams.entrySet()) {
             builder.addQueryParameter(q.getKey(), q.getValue());
         }
-        
 
         return builder;
     }
 
     public AccountJson getAccountJson(final String name, final String externalKey, final String email) {
-        String accountId = UUID.randomUUID().toString();
-        int length = 4;
-        int billCycleDay = 12;
-        String currency = "USD";
-        String timeZone = "UTC";
-        String address1 = "12 rue des ecoles";
-        String address2 = "Poitier";
-        String company = "Renault";
-        String state = "Poitou";
-        String country = "France";
-        String phone = "81 53 26 56";
-
-        AccountJson accountJson = new AccountJson(accountId, name, length, externalKey, email, billCycleDay, currency, null, timeZone, address1, address2, company, state, country, phone);
-        return accountJson;
+        final String accountId = UUID.randomUUID().toString();
+        final int length = 4;
+        final int billCycleDay = 12;
+        final String currency = "USD";
+        final String timeZone = "UTC";
+        final String address1 = "12 rue des ecoles";
+        final String address2 = "Poitier";
+        final String company = "Renault";
+        final String state = "Poitou";
+        final String country = "France";
+        final String phone = "81 53 26 56";
+
+        // Note: the accountId payload is ignored on account creation
+        return new AccountJson(accountId, name, length, externalKey, email, billCycleDay, currency, null, timeZone, address1, address2, company, state, country, phone);
     }
-    
+
     /**
-     * 
      * We could implement a ClockResource in jaxrs with the ability to sync on user token
      * but until we have a strong need for it, this is in the TODO list...
      */
     protected void crappyWaitForLackOfProperSynchonization() throws Exception {
         Thread.sleep(5000);
     }
-
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java b/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
index e0a951e..dff76bd 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
@@ -15,15 +15,10 @@
  */
 package com.ning.billing.jaxrs;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
+import javax.ws.rs.core.Response.Status;
 import java.util.Map;
 import java.util.UUID;
 
-import javax.ws.rs.core.Response.Status;
-
-import com.ning.billing.jaxrs.resources.JaxrsResource;
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
 import org.slf4j.Logger;
@@ -37,54 +32,58 @@ import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
 public class TestSubscription extends TestJaxrsBase {
 
     private static final Logger log = LoggerFactory.getLogger(TestSubscription.class);
 
     private static final String CALL_COMPLETION_TIMEOUT_SEC = "5";
-    
 
-    @Test(groups="slow", enabled=true)
+
+    @Test(groups = "slow", enabled = true)
     public void testSubscriptionInTrialOk() throws Exception {
 
-        DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
+        final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
-        
-        AccountJson accountJson = createAccount("xil", "shdxilhkkl", "xil@yahoo.com");
-        BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "99999");
 
-        String productName = "Shotgun";
-        BillingPeriod term = BillingPeriod.MONTHLY;
+        final AccountJson accountJson = createAccount("xil", "shdxilhkkl", "xil@yahoo.com");
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "99999");
+
+        final String productName = "Shotgun";
+        final BillingPeriod term = BillingPeriod.MONTHLY;
 
-        SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), productName, ProductCategory.BASE.toString(), term.toString(), true);
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), productName, ProductCategory.BASE.toString(), term.toString(), true);
         Assert.assertNotNull(subscriptionJson.getChargedThroughDate());
-        Assert.assertEquals(subscriptionJson.getChargedThroughDate(), subscriptionJson.getStartDate().plusDays(30));        
-        
+        Assert.assertEquals(subscriptionJson.getChargedThroughDate(), subscriptionJson.getStartDate().plusDays(30));
+
         String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + subscriptionJson.getSubscriptionId().toString();
- 
-        
+
+
         // Retrieves with GET
-        Response response =  doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         String baseJson = response.getResponseBody();
         SubscriptionJsonNoEvents objFromJson = mapper.readValue(baseJson, SubscriptionJsonNoEvents.class);
         Assert.assertTrue(objFromJson.equals(subscriptionJson));
-        
+
         // Change plan IMM
-        String newProductName = "Assault-Rifle";
-
-        SubscriptionJsonNoEvents newInput = new SubscriptionJsonNoEvents(subscriptionJson.getSubscriptionId(),
-                subscriptionJson.getBundleId(),
-                null,
-                newProductName,
-                subscriptionJson.getProductCategory(), 
-                subscriptionJson.getBillingPeriod(), 
-                subscriptionJson.getPriceList(), null);
+        final String newProductName = "Assault-Rifle";
+
+        final SubscriptionJsonNoEvents newInput = new SubscriptionJsonNoEvents(subscriptionJson.getSubscriptionId(),
+                                                                         subscriptionJson.getBundleId(),
+                                                                         null,
+                                                                         newProductName,
+                                                                         subscriptionJson.getProductCategory(),
+                                                                         subscriptionJson.getBillingPeriod(),
+                                                                         subscriptionJson.getPriceList(), null);
         baseJson = mapper.writeValueAsString(newInput);
 
-        Map<String, String> queryParams = getQueryParamsForCallCompletion(CALL_COMPLETION_TIMEOUT_SEC);
+        final Map<String, String> queryParams = getQueryParamsForCallCompletion(CALL_COMPLETION_TIMEOUT_SEC);
         response = doPut(uri, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         baseJson = response.getResponseBody();
@@ -92,7 +91,7 @@ public class TestSubscription extends TestJaxrsBase {
         assertTrue(objFromJson.equalsNoSubscriptionIdNoStartDateNoCTD(newInput));
 
         // MOVE AFTER TRIAL
-        Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(3).plusDays(1));
+        final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(3).plusDays(1));
         clock.addDeltaFromReality(it.toDurationMillis());
 
         crappyWaitForLackOfProperSynchonization();
@@ -108,24 +107,24 @@ public class TestSubscription extends TestJaxrsBase {
         response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
     }
-    
-    @Test(groups="slow", enabled=true)
+
+    @Test(groups = "slow", enabled = true)
     public void testWithNonExistentSubscription() throws Exception {
-        String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + UUID.randomUUID().toString();
-        SubscriptionJsonNoEvents subscriptionJson = new SubscriptionJsonNoEvents(null, UUID.randomUUID().toString(), null, "Pistol", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), PriceListSet.DEFAULT_PRICELIST_NAME, null);
-        String baseJson = mapper.writeValueAsString(subscriptionJson);
-        
+        final String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + UUID.randomUUID().toString();
+        final SubscriptionJsonNoEvents subscriptionJson = new SubscriptionJsonNoEvents(null, UUID.randomUUID().toString(), null, "Pistol", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), PriceListSet.DEFAULT_PRICELIST_NAME, null);
+        final String baseJson = mapper.writeValueAsString(subscriptionJson);
+
         Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
         String body = response.getResponseBody();
         Assert.assertEquals(body, "");
-        
+
         response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
         body = response.getResponseBody();
         Assert.assertEquals(body, "");
-        
-        response =  doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
     }
 
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
index 6248357..a4f0002 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
@@ -15,30 +15,29 @@
  */
 package com.ning.billing.jaxrs;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
-import java.util.List;
-
 import javax.ws.rs.core.Response.Status;
+import java.util.List;
 
-import com.ning.billing.jaxrs.resources.JaxrsResource;
 import org.testng.annotations.Test;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.ning.billing.jaxrs.json.TagDefinitionJson;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.http.client.Response;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
 public class TestTag extends TestJaxrsBase {
-    @Test(groups="slow", enabled=true)
+    @Test(groups = "slow", enabled = true)
     public void testTagDefinitionOk() throws Exception {
-    
-        TagDefinitionJson input = new TagDefinitionJson("blue", "relaxing color");
+
+        final TagDefinitionJson input = new TagDefinitionJson("blue", "relaxing color");
         String baseJson = mapper.writeValueAsString(input);
         Response response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
-        String location = response.getHeader("Location");
+        final String location = response.getHeader("Location");
         assertNotNull(location);
 
         // Retrieves by Id based on Location returned
@@ -46,21 +45,21 @@ public class TestTag extends TestJaxrsBase {
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
 
         baseJson = response.getResponseBody();
-        TagDefinitionJson objFromJson = mapper.readValue(baseJson, TagDefinitionJson.class);
+        final TagDefinitionJson objFromJson = mapper.readValue(baseJson, TagDefinitionJson.class);
         assertNotNull(objFromJson);
         assertEquals(objFromJson, input);
     }
-    
-    @Test(groups="slow", enabled=true)
+
+    @Test(groups = "slow", enabled = true)
     public void testMultipleTagDefinitionOk() throws Exception {
-    
+
         Response response = doGet(JaxrsResource.TAG_DEFINITIONS_PATH, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         String baseJson = response.getResponseBody();
-        
+
         List<TagDefinitionJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
-        int sizeSystemTag = (objFromJson == null || objFromJson.size() == 0) ? 0 : objFromJson.size();
-        
+        final int sizeSystemTag = (objFromJson == null || objFromJson.size() == 0) ? 0 : objFromJson.size();
+
         TagDefinitionJson input = new TagDefinitionJson("blue", "relaxing color");
         baseJson = mapper.writeValueAsString(input);
         response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -84,13 +83,13 @@ public class TestTag extends TestJaxrsBase {
         response = doGet(JaxrsResource.TAG_DEFINITIONS_PATH, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         baseJson = response.getResponseBody();
-        
+
         objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
         assertNotNull(objFromJson);
         assertEquals(objFromJson.size(), 4 + sizeSystemTag);
 
         // STEPH currently broken Tag API does not work as expected...
-        
+
         /*
         String uri = JaxrsResource.TAG_DEFINITIONS_PATH + "/green";
         response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -105,5 +104,5 @@ public class TestTag extends TestJaxrsBase {
         assertEquals(objFromJson.size(), 3 + sizeSystemTag);
         */
     }
-    
+
 }

util/pom.xml 25(+11 -14)

diff --git a/util/pom.xml b/util/pom.xml
index 2031104..2d0ebc2 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.13-SNAPSHOT</version>
+        <version>0.1.20-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-util</artifactId>
@@ -33,6 +33,11 @@
             <artifactId>jdbi</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <scope>test</scope>
@@ -60,6 +65,11 @@
             <artifactId>joda-time</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.testng</groupId>
             <artifactId>testng</artifactId>
             <scope>test</scope>
@@ -69,15 +79,6 @@
             <artifactId>commons-email</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.directory.studio</groupId>
-            <artifactId>org.apache.commons.io</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>
@@ -96,10 +97,6 @@
             <artifactId>jmustache</artifactId>
         </dependency>
         <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-        </dependency>
-        <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-core</artifactId>
         </dependency>
diff --git a/util/src/main/java/com/ning/billing/util/bus/dao/BusEventEntry.java b/util/src/main/java/com/ning/billing/util/bus/dao/BusEventEntry.java
index 8e98211..8d8080a 100644
--- a/util/src/main/java/com/ning/billing/util/bus/dao/BusEventEntry.java
+++ b/util/src/main/java/com/ning/billing/util/bus/dao/BusEventEntry.java
@@ -19,8 +19,8 @@ import org.joda.time.DateTime;
 
 import com.ning.billing.util.queue.PersistentQueueEntryLifecycle;
 
-public class BusEventEntry implements PersistentQueueEntryLifecycle  {
-    
+public class BusEventEntry implements PersistentQueueEntryLifecycle {
+
     private final long id;
     private final String owner;
     private final String createdOwner;
@@ -29,7 +29,7 @@ public class BusEventEntry implements PersistentQueueEntryLifecycle  {
     private final String busEventClass;
     private final String busEventJson;
 
-    public BusEventEntry(final long id, final String createdOwner, final String owner, final DateTime nextAvailable, PersistentQueueEntryLifecycleState processingState, final String busEventClass, final String busEventJson) {
+    public BusEventEntry(final long id, final String createdOwner, final String owner, final DateTime nextAvailable, final PersistentQueueEntryLifecycleState processingState, final String busEventClass, final String busEventJson) {
         this.id = id;
         this.createdOwner = createdOwner;
         this.owner = owner;
@@ -43,7 +43,6 @@ public class BusEventEntry implements PersistentQueueEntryLifecycle  {
         this(0, createdOwner, null, null, null, busEventClass, busEventJson);
     }
 
-    
 
     public long getId() {
         return id;
@@ -78,20 +77,20 @@ public class BusEventEntry implements PersistentQueueEntryLifecycle  {
     }
 
     @Override
-    public boolean isAvailableForProcessing(DateTime now) {
-        switch(processingState) {
-        case AVAILABLE:
-            break;
-        case IN_PROCESSING:
-            // Somebody already got the event, not available yet
-            if (nextAvailable.isAfter(now)) {
+    public boolean isAvailableForProcessing(final DateTime now) {
+        switch (processingState) {
+            case AVAILABLE:
+                break;
+            case IN_PROCESSING:
+                // Somebody already got the event, not available yet
+                if (nextAvailable.isAfter(now)) {
+                    return false;
+                }
+                break;
+            case PROCESSED:
                 return false;
-            }
-            break;
-        case PROCESSED:
-            return false;
-        default:
-            throw new RuntimeException(String.format("Unkwnon IEvent processing state %s", processingState));
+            default:
+                throw new RuntimeException(String.format("Unkwnon IEvent processing state %s", processingState));
         }
         return true;
     }
diff --git a/util/src/main/java/com/ning/billing/util/bus/dao/PersistentBusSqlDao.java b/util/src/main/java/com/ning/billing/util/bus/dao/PersistentBusSqlDao.java
index ca98098..3543c24 100644
--- a/util/src/main/java/com/ning/billing/util/bus/dao/PersistentBusSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/bus/dao/PersistentBusSqlDao.java
@@ -39,11 +39,11 @@ import com.ning.billing.util.queue.PersistentQueueEntryLifecycle.PersistentQueue
 @ExternalizedSqlViaStringTemplate3()
 public interface PersistentBusSqlDao extends Transactional<PersistentBusSqlDao>, CloseMe {
 
-    
+
     @SqlQuery
     @Mapper(PersistentBusSqlMapper.class)
     public BusEventEntry getNextBusEventEntry(@Bind("max") int max, @Bind("owner") String owner, @Bind("now") Date now);
-    
+
     @SqlUpdate
     public int claimBusEvent(@Bind("owner") String owner, @Bind("nextAvailable") Date nextAvailable,
                              @Bind("recordId") Long id, @Bind("now") Date now);
@@ -53,7 +53,7 @@ public interface PersistentBusSqlDao extends Transactional<PersistentBusSqlDao>,
 
     @SqlUpdate
     public void removeBusEventsById(@Bind("recordId") Long id);
-    
+
     @SqlUpdate
     public void insertBusEvent(@Bind(binder = PersistentBusSqlBinder.class) BusEventEntry evt);
 
@@ -61,11 +61,11 @@ public interface PersistentBusSqlDao extends Transactional<PersistentBusSqlDao>,
     public void insertClaimedHistory(@Bind("ownerId") String owner, @Bind("claimedDate") Date claimedDate,
                                      @Bind("busEventId") long id);
 
-    
+
     public static class PersistentBusSqlBinder extends BinderBase implements Binder<Bind, BusEventEntry> {
 
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, BusEventEntry evt) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final BusEventEntry evt) {
             stmt.bind("className", evt.getBusEventClass());
             stmt.bind("eventJson", evt.getBusEventJson());
             stmt.bind("createdDate", getDate(new DateTime()));
@@ -75,21 +75,21 @@ public interface PersistentBusSqlDao extends Transactional<PersistentBusSqlDao>,
             stmt.bind("processingState", PersistentQueueEntryLifecycleState.AVAILABLE.toString());
         }
     }
-    
+
     public static class PersistentBusSqlMapper extends MapperBase implements ResultSetMapper<BusEventEntry> {
 
         @Override
-        public BusEventEntry map(int index, ResultSet r, StatementContext ctx)
+        public BusEventEntry map(final int index, final ResultSet r, final StatementContext ctx)
                 throws SQLException {
 
             final Long recordId = r.getLong("record_id");
-            final String className = r.getString("class_name"); 
+            final String className = r.getString("class_name");
             final String createdOwner = r.getString("creating_owner");
-            final String eventJson = r.getString("event_json"); 
+            final String eventJson = r.getString("event_json");
             final DateTime nextAvailableDate = getDate(r, "processing_available_date");
             final String processingOwner = r.getString("processing_owner");
             final PersistentQueueEntryLifecycleState processingState = PersistentQueueEntryLifecycleState.valueOf(r.getString("processing_state"));
-            
+
             return new BusEventEntry(recordId, createdOwner, processingOwner, nextAvailableDate, processingState, className, eventJson);
         }
     }
diff --git a/util/src/main/java/com/ning/billing/util/bus/DefaultBusService.java b/util/src/main/java/com/ning/billing/util/bus/DefaultBusService.java
index ad287e4..d4fc1d3 100644
--- a/util/src/main/java/com/ning/billing/util/bus/DefaultBusService.java
+++ b/util/src/main/java/com/ning/billing/util/bus/DefaultBusService.java
@@ -22,17 +22,17 @@ import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
 
 public class DefaultBusService implements BusService {
 
-    
-    public final static String EVENT_BUS_GROUP_NAME = "bus-grp";
-    public final static String EVENT_BUS_TH_NAME = "bus-th";
-    
-    public final static String EVENT_BUS_SERVICE = "bus-service";
-    public final static String EVENT_BUS_IDENTIFIER = EVENT_BUS_SERVICE;
-    
+
+    public static final String EVENT_BUS_GROUP_NAME = "bus-grp";
+    public static final String EVENT_BUS_TH_NAME = "bus-th";
+
+    public static final String EVENT_BUS_SERVICE = "bus-service";
+    public static final String EVENT_BUS_IDENTIFIER = EVENT_BUS_SERVICE;
+
     private final Bus eventBus;
 
     @Inject
-    public DefaultBusService(Bus eventBus) {
+    public DefaultBusService(final Bus eventBus) {
         this.eventBus = eventBus;
     }
 
diff --git a/util/src/main/java/com/ning/billing/util/bus/InMemoryBus.java b/util/src/main/java/com/ning/billing/util/bus/InMemoryBus.java
index 5974bfd..1e082b1 100644
--- a/util/src/main/java/com/ning/billing/util/bus/InMemoryBus.java
+++ b/util/src/main/java/com/ning/billing/util/bus/InMemoryBus.java
@@ -16,19 +16,19 @@
 
 package com.ning.billing.util.bus;
 
-import com.google.common.eventbus.AsyncEventBus;
-import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.eventbus.AsyncEventBus;
+
 public class InMemoryBus implements Bus {
 
- 
 
     private static final Logger log = LoggerFactory.getLogger(InMemoryBus.class);
 
@@ -40,7 +40,7 @@ public class InMemoryBus implements Bus {
         private final Executor executor;
         private final ThreadGroup grp;
 
-        public EventBusDelegate(String name, ThreadGroup grp, Executor executor) {
+        public EventBusDelegate(final String name, final ThreadGroup grp, final Executor executor) {
             super(name, executor);
             this.executor = executor;
             this.grp = grp;
@@ -63,9 +63,9 @@ public class InMemoryBus implements Bus {
     public InMemoryBus() {
 
         final ThreadGroup group = new ThreadGroup(DefaultBusService.EVENT_BUS_GROUP_NAME);
-        Executor executor = Executors.newCachedThreadPool(new ThreadFactory() {
+        final Executor executor = Executors.newCachedThreadPool(new ThreadFactory() {
             @Override
-            public Thread newThread(Runnable r) {
+            public Thread newThread(final Runnable r) {
                 return new Thread(group, r, DefaultBusService.EVENT_BUS_TH_NAME);
             }
         });
@@ -75,25 +75,25 @@ public class InMemoryBus implements Bus {
     }
 
     @Override
-    public void register(Object handlerInstance) throws EventBusException {
+    public void register(final Object handlerInstance) throws EventBusException {
         checkInitialized("register");
         delegate.register(handlerInstance);
     }
 
     @Override
-    public void unregister(Object handlerInstance) throws EventBusException {
+    public void unregister(final Object handlerInstance) throws EventBusException {
         checkInitialized("unregister");
         delegate.unregister(handlerInstance);
     }
 
     @Override
-    public void post(BusEvent event) throws EventBusException {
+    public void post(final BusEvent event) throws EventBusException {
         checkInitialized("post");
         delegate.post(event);
     }
 
     @Override
-    public void postFromTransaction(BusEvent event, Transmogrifier dao) throws EventBusException {
+    public void postFromTransaction(final BusEvent event, final Transmogrifier dao) throws EventBusException {
         checkInitialized("postFromTransaction");
         delegate.post(event);
     }
@@ -106,12 +106,13 @@ public class InMemoryBus implements Bus {
         }
     }
 
-    private void checkInitialized(String operation) throws EventBusException {
+    private void checkInitialized(final String operation) throws EventBusException {
         if (!isInitialized.get()) {
             throw new EventBusException(String.format("Attempting operation %s on an non initialized bus",
-                    operation));
+                                                      operation));
         }
     }
+
     @Override
     public void stop() {
         if (isInitialized.compareAndSet(true, false)) {
diff --git a/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java b/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java
index a609c80..b315e79 100644
--- a/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java
+++ b/util/src/main/java/com/ning/billing/util/bus/PersistentBus.java
@@ -39,20 +39,20 @@ import com.ning.billing.util.queue.PersistentQueueBase;
 
 public class PersistentBus extends PersistentQueueBase implements Bus {
 
-    private final static long DELTA_IN_PROCESSING_TIME_MS = 1000L * 60L * 5L; // 5 minutes
-    private final static int MAX_BUS_EVENTS = 1;
-    
+    private static final long DELTA_IN_PROCESSING_TIME_MS = 1000L * 60L * 5L; // 5 minutes
+    private static final int MAX_BUS_EVENTS = 1;
+
     private static final Logger log = LoggerFactory.getLogger(PersistentBus.class);
-    
+
     private final PersistentBusSqlDao dao;
-    
-    private final ObjectMapper objectMapper = new ObjectMapper();
+
+
     private final EventBusDelegate eventBusDelegate;
     private final Clock clock;
     private final String hostname;
 
     private static final class EventBusDelegate extends EventBus {
-        public EventBusDelegate(String busName) {
+        public EventBusDelegate(final String busName) {
             super(busName);
         }
 
@@ -70,16 +70,16 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
           }
           */
     }
-    
+
     @Inject
     public PersistentBus(final IDBI dbi, final Clock clock, final PersistentBusConfig config) {
-        
+
         super("Bus", Executors.newFixedThreadPool(config.getNbThreads(), new ThreadFactory() {
             @Override
-            public Thread newThread(Runnable r) {
+            public Thread newThread(final Runnable r) {
                 return new Thread(new ThreadGroup(DefaultBusService.EVENT_BUS_GROUP_NAME),
-                        r,
-                        DefaultBusService.EVENT_BUS_TH_NAME);
+                                  r,
+                                  DefaultBusService.EVENT_BUS_TH_NAME);
             }
         }), config.getNbThreads(), config);
         this.dao = dbi.onDemand(PersistentBusSqlDao.class);
@@ -87,7 +87,7 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
         this.eventBusDelegate = new EventBusDelegate("Killbill EventBus");
         this.hostname = Hostname.get();
     }
-    
+
     @Override
     public void start() {
         startQueue();
@@ -101,14 +101,14 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
     @Override
     public int doProcessEvents() {
 
-        List<BusEventEntry> events = getNextBusEvent();
+        final List<BusEventEntry> events = getNextBusEvent();
         if (events.size() == 0) {
             return 0;
         }
 
         int result = 0;
         for (final BusEventEntry cur : events) {
-            BusEvent evt = deserializeBusEvent(cur.getBusEventClass(), cur.getBusEventJson());
+            final BusEvent evt = deserializeEvent(cur.getBusEventClass(), cur.getBusEventJson());
             result++;
             // STEPH exception handling is done by GUAVA-- logged a bug Issue-780
             eventBusDelegate.post(evt);
@@ -117,27 +117,17 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
         return result;
     }
 
-    private BusEvent deserializeBusEvent(final String className, final String json) {
-        try {
-            Class<?> claz = Class.forName(className);
-            return (BusEvent) objectMapper.readValue(json, claz);
-        } catch (Exception e) {
-            log.error(String.format("Failed to deserialize json object %s for class %s", json, className), e);
-            return null;
-        }
-    }
 
-    
     private List<BusEventEntry> getNextBusEvent() {
 
         final Date now = clock.getUTCNow().toDate();
         final Date nextAvailable = clock.getUTCNow().plus(DELTA_IN_PROCESSING_TIME_MS).toDate();
 
-        BusEventEntry input = dao.getNextBusEventEntry(MAX_BUS_EVENTS, hostname, now);
+        final BusEventEntry input = dao.getNextBusEventEntry(MAX_BUS_EVENTS, hostname, now);
         if (input == null) {
             return Collections.emptyList();
         }
-        
+
         final boolean claimed = (dao.claimBusEvent(hostname, nextAvailable, input.getId(), now) == 1);
         if (claimed) {
             dao.insertClaimedHistory(hostname, now, input.getId());
@@ -147,12 +137,12 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
     }
 
     @Override
-    public void register(Object handlerInstance) throws EventBusException {
+    public void register(final Object handlerInstance) throws EventBusException {
         eventBusDelegate.register(handlerInstance);
     }
 
     @Override
-    public void unregister(Object handlerInstance) throws EventBusException {
+    public void unregister(final Object handlerInstance) throws EventBusException {
         eventBusDelegate.unregister(handlerInstance);
     }
 
@@ -160,8 +150,8 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
     public void post(final BusEvent event) throws EventBusException {
         dao.inTransaction(new Transaction<Void, PersistentBusSqlDao>() {
             @Override
-            public Void inTransaction(PersistentBusSqlDao transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final PersistentBusSqlDao transactional,
+                                      final TransactionStatus status) throws Exception {
                 postFromTransaction(event, transactional);
                 return null;
             }
@@ -169,16 +159,16 @@ public class PersistentBus extends PersistentQueueBase implements Bus {
     }
 
     @Override
-    public void postFromTransaction(final BusEvent event, Transmogrifier transmogrifier)
+    public void postFromTransaction(final BusEvent event, final Transmogrifier transmogrifier)
             throws EventBusException {
-        PersistentBusSqlDao transactional = transmogrifier.become(PersistentBusSqlDao.class);
+        final PersistentBusSqlDao transactional = transmogrifier.become(PersistentBusSqlDao.class);
         postFromTransaction(event, transactional);
     }
-    
-    private void postFromTransaction(BusEvent event, PersistentBusSqlDao transactional) {
+
+    private void postFromTransaction(final BusEvent event, final PersistentBusSqlDao transactional) {
         try {
-            String json = objectMapper.writeValueAsString(event);
-            BusEventEntry entry  =  new BusEventEntry(hostname, event.getClass().getName(), json);
+            final String json = objectMapper.writeValueAsString(event);
+            final BusEventEntry entry = new BusEventEntry(hostname, event.getClass().getName(), json);
             transactional.insertBusEvent(entry);
         } catch (Exception e) {
             log.error("Failed to post BusEvent " + event.toString(), e);
diff --git a/util/src/main/java/com/ning/billing/util/bus/PersistentBusConfig.java b/util/src/main/java/com/ning/billing/util/bus/PersistentBusConfig.java
index a2e9879..b0a1c5a 100644
--- a/util/src/main/java/com/ning/billing/util/bus/PersistentBusConfig.java
+++ b/util/src/main/java/com/ning/billing/util/bus/PersistentBusConfig.java
@@ -26,7 +26,7 @@ public interface PersistentBusConfig extends PersistentQueueConfig {
     @Config("killbill.billing.util.persistent.bus.sleep")
     @Default("500")
     public long getSleepTimeMs();
-    
+
     @Config("killbill.billing.util.persistent.bus.nbThreads")
     @Default("3")
     public int getNbThreads();
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java b/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java
index c36bc6c..40d7ef5 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/CallContextBase.java
@@ -19,23 +19,23 @@ package com.ning.billing.util.callcontext;
 import java.util.UUID;
 
 public abstract class CallContextBase implements CallContext {
-	private final UUID userToken;
+    private final UUID userToken;
     private final String userName;
     private final CallOrigin callOrigin;
     private final UserType userType;
     private final String reasonCode;
     private final String comment;
 
-    public CallContextBase(String userName, CallOrigin callOrigin, UserType userType) {
-    	this(userName, callOrigin, userType, null);
+    public CallContextBase(final String userName, final CallOrigin callOrigin, final UserType userType) {
+        this(userName, callOrigin, userType, null);
     }
 
-    public CallContextBase(String userName, CallOrigin callOrigin, UserType userType, UUID userToken) {
+    public CallContextBase(final String userName, final CallOrigin callOrigin, final UserType userType, final UUID userToken) {
         this(userName, callOrigin, userType, null, null, userToken);
     }
 
-    public CallContextBase(String userName, CallOrigin callOrigin, UserType userType,
-                           String reasonCode, String comment, UUID userToken) {
+    public CallContextBase(final String userName, final CallOrigin callOrigin, final UserType userType,
+                           final String reasonCode, final String comment, final UUID userToken) {
         this.userName = userName;
         this.callOrigin = callOrigin;
         this.userType = userType;
@@ -68,9 +68,9 @@ public abstract class CallContextBase implements CallContext {
     public String getComment() {
         return comment;
     }
-    
+
     @Override
     public UUID getUserToken() {
-    	return userToken;
+        return userToken;
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/CallContextBinder.java b/util/src/main/java/com/ning/billing/util/callcontext/CallContextBinder.java
index 36a8d42..63dfd71 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/CallContextBinder.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/CallContextBinder.java
@@ -16,35 +16,35 @@
 
 package com.ning.billing.util.callcontext;
 
-import org.skife.jdbi.v2.SQLStatement;
-import org.skife.jdbi.v2.sqlobject.Binder;
-import org.skife.jdbi.v2.sqlobject.BinderFactory;
-import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
 @BindingAnnotation(CallContextBinder.CallContextBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface CallContextBinder {
     public static class CallContextBinderFactory implements BinderFactory {
         @Override
-        public Binder build(Annotation annotation) {
+        public Binder build(final Annotation annotation) {
             return new Binder<CallContextBinder, CallContext>() {
                 @Override
-                public void bind(SQLStatement q, CallContextBinder bind, CallContext callContext) {
-                	q.bind("userName", callContext.getUserName());
+                public void bind(final SQLStatement q, final CallContextBinder bind, final CallContext callContext) {
+                    q.bind("userName", callContext.getUserName());
                     q.bind("createdDate", callContext.getCreatedDate().toDate());
                     q.bind("updatedDate", callContext.getUpdatedDate().toDate());
                     q.bind("reasonCode", callContext.getReasonCode());
                     q.bind("comment", callContext.getComment());
-                	q.bind("userToken", (callContext.getUserToken() != null) ? callContext.getUserToken().toString() : null);                	
+                    q.bind("userToken", (callContext.getUserToken() != null) ? callContext.getUserToken().toString() : null);
                 }
             };
         }
     }
-}
\ No newline at end of file
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java b/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java
index 3194c02..53b2cfa 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/CallContextFactory.java
@@ -26,7 +26,7 @@ public interface CallContextFactory {
     CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType,
                                   String reasonCode, String comment, UUID userToken);
 
-    CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType);    
+    CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType);
 
     CallContext createMigrationCallContext(String userName, CallOrigin callOrigin, UserType userType, DateTime createdDate, DateTime updatedDate);
 
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java
index 4bb7c24..081cd7e 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContext.java
@@ -18,9 +18,10 @@ package com.ning.billing.util.callcontext;
 
 import java.util.UUID;
 
-import com.ning.billing.util.clock.Clock;
 import org.joda.time.DateTime;
 
+import com.ning.billing.util.clock.Clock;
+
 public class DefaultCallContext extends CallContextBase {
     private final Clock clock;
 
@@ -36,8 +37,8 @@ public class DefaultCallContext extends CallContextBase {
         this.clock = clock;
     }
 
-    public DefaultCallContext(String userName, CallOrigin callOrigin, UserType userType, Clock clock) {
-    	this(userName, callOrigin, userType, null, clock);
+    public DefaultCallContext(final String userName, final CallOrigin callOrigin, final UserType userType, final Clock clock) {
+        this(userName, callOrigin, userType, null, clock);
     }
 
     @Override
@@ -49,4 +50,4 @@ public class DefaultCallContext extends CallContextBase {
     public DateTime getUpdatedDate() {
         return clock.getUTCNow();
     }
-}
\ No newline at end of file
+}
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java
index 53b5ba1..afd72bd 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/DefaultCallContextFactory.java
@@ -16,46 +16,46 @@
 
 package com.ning.billing.util.callcontext;
 
+import javax.annotation.Nullable;
 import java.util.UUID;
 
-import com.google.inject.Inject;
-import com.ning.billing.util.clock.Clock;
 import org.joda.time.DateTime;
 
-import javax.annotation.Nullable;
+import com.google.inject.Inject;
+import com.ning.billing.util.clock.Clock;
 
 public class DefaultCallContextFactory implements CallContextFactory {
     private final Clock clock;
 
     @Inject
-    public DefaultCallContextFactory(Clock clock) {
+    public DefaultCallContextFactory(final Clock clock) {
         this.clock = clock;
     }
 
     @Override
-    public CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType,
-                                         @Nullable UUID userToken) {
+    public CallContext createCallContext(final String userName, final CallOrigin callOrigin, final UserType userType,
+                                         @Nullable final UUID userToken) {
         return new DefaultCallContext(userName, callOrigin, userType, userToken, clock);
     }
 
     @Override
-    public CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType,
-                                         String reasonCode, String comment, UUID userToken) {
+    public CallContext createCallContext(final String userName, final CallOrigin callOrigin, final UserType userType,
+                                         final String reasonCode, final String comment, final UUID userToken) {
         return new DefaultCallContext(userName, callOrigin, userType, reasonCode, comment, userToken, clock);
     }
 
     @Override
-    public CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType) {
-    	return createCallContext(userName, callOrigin, userType, null);
+    public CallContext createCallContext(final String userName, final CallOrigin callOrigin, final UserType userType) {
+        return createCallContext(userName, callOrigin, userType, null);
     }
 
     @Override
-    public CallContext createMigrationCallContext(String userName, CallOrigin callOrigin, UserType userType, DateTime createdDate, DateTime updatedDate) {
+    public CallContext createMigrationCallContext(final String userName, final CallOrigin callOrigin, final UserType userType, final DateTime createdDate, final DateTime updatedDate) {
         return new MigrationCallContext(userName, callOrigin, userType, createdDate, updatedDate);
     }
 
     @Override
-    public CallContext toMigrationCallContext(CallContext callContext, DateTime createdDate, DateTime updatedDate) {
+    public CallContext toMigrationCallContext(final CallContext callContext, final DateTime createdDate, final DateTime updatedDate) {
         return new MigrationCallContext(callContext, createdDate, updatedDate);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java b/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java
index 9d7fc58..4ab9e66 100644
--- a/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java
+++ b/util/src/main/java/com/ning/billing/util/callcontext/MigrationCallContext.java
@@ -22,13 +22,13 @@ public class MigrationCallContext extends CallContextBase {
     private final DateTime createdDate;
     private final DateTime updatedDate;
 
-    public MigrationCallContext(String userName, CallOrigin callOrigin, UserType userType, DateTime createdDate, DateTime updatedDate) {
+    public MigrationCallContext(final String userName, final CallOrigin callOrigin, final UserType userType, final DateTime createdDate, final DateTime updatedDate) {
         super(userName, callOrigin, userType);
         this.createdDate = createdDate;
         this.updatedDate = updatedDate;
     }
 
-    public MigrationCallContext(CallContext context, DateTime createdDate, DateTime updatedDate) {
+    public MigrationCallContext(final CallContext context, final DateTime createdDate, final DateTime updatedDate) {
         super(context.getUserName(), context.getCallOrigin(), context.getUserType());
         this.createdDate = createdDate;
         this.updatedDate = updatedDate;
diff --git a/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java b/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java
index 057a58c..b05d120 100644
--- a/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java
+++ b/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java
@@ -16,19 +16,20 @@
 
 package com.ning.billing.util.clock;
 
-import com.ning.billing.catalog.api.Duration;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
-import java.util.ArrayList;
-import java.util.List;
+import com.ning.billing.catalog.api.Duration;
 
 public class DefaultClock implements Clock {
 
     @Override
-    public DateTime getNow(DateTimeZone tz) {
-       DateTime result = new DateTime(tz);
-       return truncateMs(result);
+    public DateTime getNow(final DateTimeZone tz) {
+        final DateTime result = new DateTime(tz);
+        return truncateMs(result);
     }
 
     @Override
@@ -36,58 +37,58 @@ public class DefaultClock implements Clock {
         return getNow(DateTimeZone.UTC);
     }
 
-    public static DateTime toUTCDateTime(DateTime input) {
+    public static DateTime toUTCDateTime(final DateTime input) {
         if (input == null) {
             return null;
         }
-        DateTime result = input.toDateTime(DateTimeZone.UTC);
+        final DateTime result = input.toDateTime(DateTimeZone.UTC);
         return truncateMs(result);
     }
 
-    public static DateTime truncateMs(DateTime input) {
+    public static DateTime truncateMs(final DateTime input) {
         return input.minus(input.getMillisOfSecond());
     }
 
 
-    public static DateTime addOrRemoveDuration(DateTime input, List<Duration> durations, boolean add) {
+    public static DateTime addOrRemoveDuration(final DateTime input, final List<Duration> durations, final boolean add) {
         DateTime result = input;
-        for (Duration cur : durations) {
+        for (final Duration cur : durations) {
             switch (cur.getUnit()) {
-            case DAYS:
-                result = add ? result.plusDays(cur.getNumber()) : result.minusDays(cur.getNumber());
-                break;
-
-            case MONTHS:
-                result = add ? result.plusMonths(cur.getNumber()) : result.minusMonths(cur.getNumber());
-                break;
-
-            case YEARS:
-                result = add ? result.plusYears(cur.getNumber()) : result.minusYears(cur.getNumber());
-                break;
-            case UNLIMITED:
-            default:
-                throw new RuntimeException("Trying to move to unlimited time period");
+                case DAYS:
+                    result = add ? result.plusDays(cur.getNumber()) : result.minusDays(cur.getNumber());
+                    break;
+
+                case MONTHS:
+                    result = add ? result.plusMonths(cur.getNumber()) : result.minusMonths(cur.getNumber());
+                    break;
+
+                case YEARS:
+                    result = add ? result.plusYears(cur.getNumber()) : result.minusYears(cur.getNumber());
+                    break;
+                case UNLIMITED:
+                default:
+                    throw new RuntimeException("Trying to move to unlimited time period");
             }
         }
         return result;
     }
 
-    public static DateTime addDuration(DateTime input, List<Duration> durations) {
+    public static DateTime addDuration(final DateTime input, final List<Duration> durations) {
         return addOrRemoveDuration(input, durations, true);
     }
 
-    public static DateTime removeDuration(DateTime input, List<Duration> durations) {
+    public static DateTime removeDuration(final DateTime input, final List<Duration> durations) {
         return addOrRemoveDuration(input, durations, false);
     }
 
-    public static DateTime addDuration(DateTime input, Duration duration) {
-        List<Duration> list = new ArrayList<Duration>();
+    public static DateTime addDuration(final DateTime input, final Duration duration) {
+        final List<Duration> list = new ArrayList<Duration>();
         list.add(duration);
         return addOrRemoveDuration(input, list, true);
     }
 
-    public static DateTime removeDuration(DateTime input, Duration duration) {
-        List<Duration> list = new ArrayList<Duration>();
+    public static DateTime removeDuration(final DateTime input, final Duration duration) {
+        final List<Duration> list = new ArrayList<Duration>();
         list.add(duration);
         return addOrRemoveDuration(input, list, false);
     }
diff --git a/util/src/main/java/com/ning/billing/util/config/UriAccessor.java b/util/src/main/java/com/ning/billing/util/config/UriAccessor.java
index e931837..fabd6da 100644
--- a/util/src/main/java/com/ning/billing/util/config/UriAccessor.java
+++ b/util/src/main/java/com/ning/billing/util/config/UriAccessor.java
@@ -24,33 +24,43 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Scanner;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.Resources;
+
 public class UriAccessor {
-	private static final String URI_SCHEME_FOR_CLASSPATH = "jar";
-	private static final String URI_SCHEME_FOR_FILE = "file";
-
-	public static InputStream accessUri(String uri)  throws IOException, URISyntaxException {
-		return accessUri(new URI(uri));
-	}
-	
-	public static InputStream accessUri(URI uri) throws IOException {
-		String scheme = uri.getScheme();
+
+    private final static Logger log = LoggerFactory.getLogger(UriAccessor.class);
+
+    private static final String URI_SCHEME_FOR_CLASSPATH = "jar";
+    private static final String URI_SCHEME_FOR_FILE = "file";
+
+    public static InputStream accessUri(String uri)  throws IOException, URISyntaxException {
+        return accessUri(new URI(uri));
+    }
+
+    public static InputStream accessUri(URI uri) throws IOException, URISyntaxException {
+        String scheme = uri.getScheme();
         URL url = null;
-        if (scheme.equals(URI_SCHEME_FOR_CLASSPATH)) {
-        	return UriAccessor.class.getResourceAsStream(uri.getPath());
+        if (scheme == null) {
+            uri = new URI(Resources.getResource(uri.toString()).toExternalForm());
+        } else if (scheme.equals(URI_SCHEME_FOR_CLASSPATH)) {
+            return UriAccessor.class.getResourceAsStream(uri.getPath());
         } else if (scheme.equals(URI_SCHEME_FOR_FILE) &&
-        	!uri.getSchemeSpecificPart().startsWith("/")) { // interpret URIs of this form as relative path uris
-        	url = new File(uri.getSchemeSpecificPart()).toURI().toURL();
+                !uri.getSchemeSpecificPart().startsWith("/")) { // interpret URIs of this form as relative path uris
+            url = new File(uri.getSchemeSpecificPart()).toURI().toURL();
         }
         url = uri.toURL();
-    	return url.openConnection().getInputStream();
-	}
-	
-	public static String accessUriAsString(String uri)  throws IOException, URISyntaxException {
-		return accessUriAsString(new URI(uri));
-	}
-	
-	public static String accessUriAsString(URI uri) throws IOException {
-		InputStream stream = accessUri(uri);
-		return new Scanner(stream).useDelimiter("\\A").next();
-	}
+        return url.openConnection().getInputStream();
+    }
+
+    public static String accessUriAsString(String uri)  throws IOException, URISyntaxException {
+        return accessUriAsString(new URI(uri));
+    }
+
+    public static String accessUriAsString(URI uri) throws IOException,  URISyntaxException {
+        InputStream stream = accessUri(uri);
+        return new Scanner(stream).useDelimiter("\\A").next();
+    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java b/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java
index 34c2adc..ae772a6 100644
--- a/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java
+++ b/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java
@@ -17,28 +17,28 @@
 package com.ning.billing.util.config;
 
 
-import java.net.URI;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
+import java.net.URI;
 
 @XmlAccessorType(XmlAccessType.NONE)
 public abstract class ValidatingConfig<Context> {
-	/**
-	 * All must implement validation
-	 * 
-	 * @param root
-	 * @param errors
-	 * @return
-	 */
-	public abstract ValidationErrors validate(Context root, ValidationErrors errors);
-	
-	
-	/**
-	 * Override  to initialize
-	 * 
-	 * @param root
-	 */
-	public void initialize(Context root, URI uri){}
+    /**
+     * All must implement validation
+     *
+     * @param root
+     * @param errors
+     * @return
+     */
+    public abstract ValidationErrors validate(Context root, ValidationErrors errors);
+
+
+    /**
+     * Override  to initialize
+     *
+     * @param root
+     */
+    public void initialize(final Context root, final URI uri) {
+    }
 
 }
diff --git a/util/src/main/java/com/ning/billing/util/config/ValidationError.java b/util/src/main/java/com/ning/billing/util/config/ValidationError.java
index cd1ae4d..9ca9ed8 100644
--- a/util/src/main/java/com/ning/billing/util/config/ValidationError.java
+++ b/util/src/main/java/com/ning/billing/util/config/ValidationError.java
@@ -15,42 +15,47 @@
  */
 package com.ning.billing.util.config;
 
-import org.slf4j.Logger;
-
 import java.net.URI;
 
+import org.slf4j.Logger;
+
 
 public class ValidationError {
-	private final String description;
-	private final URI sourceURI;
-	private final Class<?> objectType;
-	private final String objectName;
-	public ValidationError(String description, URI sourceURI,
-			Class<?> objectType, String objectName) {
-		super();
-		this.description = description;
-		this.sourceURI = sourceURI;
-		this.objectType = objectType;
-		this.objectName = objectName;
-	}
-	public String getDescription() {
-		return description;
-	}
-	public URI getSourceURI() {
-		return sourceURI;
-	}
-	public Class<?> getObjectType() {
-		return objectType;
-	}
-	public String getObjectName() {
-		return objectName;
-	}
-	
-	public void log(Logger log) {
-		log.error(String.format("%s [%s] (%s:%s)", description, sourceURI, objectType, objectName));
-	}
-	
-	public String toString() {
-		return String.format("%s [%s] (%s:%s)\n", description, sourceURI, objectType, objectName);
-	}
+    private final String description;
+    private final URI sourceURI;
+    private final Class<?> objectType;
+    private final String objectName;
+
+    public ValidationError(final String description, final URI sourceURI,
+                           final Class<?> objectType, final String objectName) {
+        super();
+        this.description = description;
+        this.sourceURI = sourceURI;
+        this.objectType = objectType;
+        this.objectName = objectName;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public URI getSourceURI() {
+        return sourceURI;
+    }
+
+    public Class<?> getObjectType() {
+        return objectType;
+    }
+
+    public String getObjectName() {
+        return objectName;
+    }
+
+    public void log(final Logger log) {
+        log.error(String.format("%s [%s] (%s:%s)", description, sourceURI, objectType, objectName));
+    }
+
+    public String toString() {
+        return String.format("%s [%s] (%s:%s)\n", description, sourceURI, objectType, objectName);
+    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/config/ValidationErrors.java b/util/src/main/java/com/ning/billing/util/config/ValidationErrors.java
index c8145d2..2ad91fe 100644
--- a/util/src/main/java/com/ning/billing/util/config/ValidationErrors.java
+++ b/util/src/main/java/com/ning/billing/util/config/ValidationErrors.java
@@ -16,32 +16,32 @@
 
 package com.ning.billing.util.config;
 
-import org.slf4j.Logger;
-
 import java.net.URI;
 import java.util.ArrayList;
 
-public class ValidationErrors extends ArrayList<ValidationError>{
-	private static final long serialVersionUID = 1L;
-
-	public void add(String description, URI catalogURI,
-			Class<?> objectType, String objectName) {
-		add(new ValidationError(description, catalogURI, objectType, objectName));
-		
-	}
-
-	public void log(Logger log) {
-		for(ValidationError error : this) {
-			error.log(log);
-		}	
-	}
-	
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for(ValidationError error : this) {
-			builder.append(error.toString());
-		}	
-		return builder.toString();
-	}
-
-}
\ No newline at end of file
+import org.slf4j.Logger;
+
+public class ValidationErrors extends ArrayList<ValidationError> {
+    private static final long serialVersionUID = 1L;
+
+    public void add(final String description, final URI catalogURI,
+                    final Class<?> objectType, final String objectName) {
+        add(new ValidationError(description, catalogURI, objectType, objectName));
+
+    }
+
+    public void log(final Logger log) {
+        for (final ValidationError error : this) {
+            error.log(log);
+        }
+    }
+
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        for (final ValidationError error : this) {
+            builder.append(error.toString());
+        }
+        return builder.toString();
+    }
+
+}
diff --git a/util/src/main/java/com/ning/billing/util/config/ValidationException.java b/util/src/main/java/com/ning/billing/util/config/ValidationException.java
index 52e608d..b4a25f1 100644
--- a/util/src/main/java/com/ning/billing/util/config/ValidationException.java
+++ b/util/src/main/java/com/ning/billing/util/config/ValidationException.java
@@ -19,21 +19,22 @@ package com.ning.billing.util.config;
 import java.io.PrintStream;
 
 public class ValidationException extends Exception {
-	private final ValidationErrors errors;
-	
-	ValidationException(ValidationErrors errors) {
-		this.errors = errors;
-	}
-	public ValidationErrors getErrors() {
-		return errors;
-	}
-
-	@Override
-	public void printStackTrace(PrintStream arg0) {
-		arg0.print(errors.toString());
-		super.printStackTrace(arg0);
-	}
-
-	
+    private final ValidationErrors errors;
+
+    ValidationException(final ValidationErrors errors) {
+        this.errors = errors;
+    }
+
+    public ValidationErrors getErrors() {
+        return errors;
+    }
+
+    @Override
+    public void printStackTrace(final PrintStream arg0) {
+        arg0.print(errors.toString());
+        super.printStackTrace(arg0);
+    }
+
+
 }
 
diff --git a/util/src/main/java/com/ning/billing/util/config/XMLLoader.java b/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
index 304d215..b182b7c 100644
--- a/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
+++ b/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.util.config;
 
-import com.ning.billing.catalog.api.InvalidConfigException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
 import javax.xml.XMLConstants;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
@@ -33,80 +28,86 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+import com.ning.billing.catalog.api.InvalidConfigException;
+
 public class XMLLoader {
-	public static Logger log = LoggerFactory.getLogger(XMLLoader.class);
-
-	public static <T extends ValidatingConfig<T>> T getObjectFromString(String uri, Class<T> objectType) throws Exception {
-		if (uri == null) {
-			return null;
-		}
-		log.info("Initializing an object of class " + objectType.getName() + " from xml file at: " + uri);
-					
-		return getObjectFromStream(new URI(uri), UriAccessor.accessUri(uri), objectType);
-	}
-	
-	public static <T extends ValidatingConfig<T>> T getObjectFromUri(URI uri, Class<T> objectType) throws Exception {
-		if (uri == null) {
-			return null;
-		}
-		log.info("Initializing an object of class " + objectType.getName() + " from xml file at: " + uri);
-					
-		return getObjectFromStream(uri, UriAccessor.accessUri(uri), objectType);
-	}
-	
-	public static <T extends ValidatingConfig<T>> T getObjectFromStream(URI uri, InputStream stream, Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, ValidationException {
-	    if(stream == null) {
-	        return null;
-	    }
-	    
-	    Object o = unmarshaller(clazz).unmarshal(stream);
+    public static Logger log = LoggerFactory.getLogger(XMLLoader.class);
+
+    public static <T extends ValidatingConfig<T>> T getObjectFromString(final String uri, final Class<T> objectType) throws Exception {
+        if (uri == null) {
+            return null;
+        }
+        log.info("Initializing an object of class " + objectType.getName() + " from xml file at: " + uri);
+
+        return getObjectFromStream(new URI(uri), UriAccessor.accessUri(uri), objectType);
+    }
+
+    public static <T extends ValidatingConfig<T>> T getObjectFromUri(final URI uri, final Class<T> objectType) throws Exception {
+        if (uri == null) {
+            return null;
+        }
+        log.info("Initializing an object of class " + objectType.getName() + " from xml file at: " + uri);
+
+        return getObjectFromStream(uri, UriAccessor.accessUri(uri), objectType);
+    }
+
+    public static <T extends ValidatingConfig<T>> T getObjectFromStream(final URI uri, final InputStream stream, final Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, ValidationException {
+        if (stream == null) {
+            return null;
+        }
+
+        final Object o = unmarshaller(clazz).unmarshal(stream);
         if (clazz.isInstance(o)) {
-        	@SuppressWarnings("unchecked")
-			T castObject = (T)o;
-        	try {
-        		validate(uri,castObject);
-        	} catch (ValidationException e) {
-        		e.getErrors().log(log);
-        		System.err.println(e.getErrors().toString());
-        		throw e;
-        	}
+            @SuppressWarnings("unchecked") final
+            T castObject = (T) o;
+            try {
+                validate(uri, castObject);
+            } catch (ValidationException e) {
+                e.getErrors().log(log);
+                System.err.println(e.getErrors().toString());
+                throw e;
+            }
             return castObject;
         } else {
             return null;
         }
-    } 
-	
-	public static <T> T getObjectFromStreamNoValidation(InputStream stream, Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException {
-        Object o = unmarshaller(clazz).unmarshal(stream);
+    }
+
+    public static <T> T getObjectFromStreamNoValidation(final InputStream stream, final Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException {
+        final Object o = unmarshaller(clazz).unmarshal(stream);
         if (clazz.isInstance(o)) {
-        	@SuppressWarnings("unchecked")
-			T castObject = (T)o;
-        	return castObject;
+            @SuppressWarnings("unchecked") final
+            T castObject = (T) o;
+            return castObject;
         } else {
             return null;
         }
-    } 
+    }
 
 
-	public static <T extends ValidatingConfig<T>> void validate(URI uri, T c) throws ValidationException {
-            c.initialize(c, uri);
-            ValidationErrors errs = c.validate(c, new ValidationErrors());
-            log.info("Errors: " + errs.size() + " for " + uri);  
-            if(errs.size() > 0) {
-            	throw new ValidationException(errs);
-            }
+    public static <T extends ValidatingConfig<T>> void validate(final URI uri, final T c) throws ValidationException {
+        c.initialize(c, uri);
+        final ValidationErrors errs = c.validate(c, new ValidationErrors());
+        log.info("Errors: " + errs.size() + " for " + uri);
+        if (errs.size() > 0) {
+            throw new ValidationException(errs);
+        }
     }
-    
-    public static Unmarshaller unmarshaller(Class<?> clazz) throws JAXBException, SAXException, IOException, TransformerException {
-    	 JAXBContext context =JAXBContext.newInstance(clazz);
 
-         SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI );
-         Unmarshaller um = context.createUnmarshaller();
+    public static Unmarshaller unmarshaller(final Class<?> clazz) throws JAXBException, SAXException, IOException, TransformerException {
+        final JAXBContext context = JAXBContext.newInstance(clazz);
+
+        final SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+        final Unmarshaller um = context.createUnmarshaller();
 
-         Schema schema = factory.newSchema(new StreamSource(XMLSchemaGenerator.xmlSchema(clazz)));
-         um.setSchema(schema);
-         
-         return um;
+        final Schema schema = factory.newSchema(new StreamSource(XMLSchemaGenerator.xmlSchema(clazz)));
+        um.setSchema(schema);
+
+        return um;
     }
-	
+
 }
diff --git a/util/src/main/java/com/ning/billing/util/config/XMLSchemaGenerator.java b/util/src/main/java/com/ning/billing/util/config/XMLSchemaGenerator.java
index c816523..205d449 100644
--- a/util/src/main/java/com/ning/billing/util/config/XMLSchemaGenerator.java
+++ b/util/src/main/java/com/ning/billing/util/config/XMLSchemaGenerator.java
@@ -16,15 +16,6 @@
 
 package com.ning.billing.util.config;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.SchemaOutputResolver;
@@ -36,77 +27,83 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMResult;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.w3c.dom.Document;
 
 public class XMLSchemaGenerator {
-	final private static  int MAX_SCHEMA_SIZE_IN_BYTES = 100000;
-
-
-	//Note: this main method is called by the maven build to generate the schema for the jar
-	public static void main(String[] args) throws IOException, TransformerException, JAXBException, ClassNotFoundException {
-		if (args.length != 2) {
-			printUsage();
-			System.exit(0);
-		}
-		Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(args[1]);
-		
-		JAXBContext context =JAXBContext.newInstance(clazz);
-		String xsdFileName = "Schema.xsd";
-		if(args.length != 0) {
-			xsdFileName = args[0] + "/" + xsdFileName;
-		}
-		FileOutputStream s = new FileOutputStream(xsdFileName);
-		pojoToXSD(context, s);
-	}
-
-	private static void printUsage() {
-		System.out.println(XMLSchemaGenerator.class.getName() + " <file> <class1>");
-		
-	}
-	
-	public static String xmlSchemaAsString(Class<?> clazz) throws IOException, TransformerException, JAXBException {
-		ByteArrayOutputStream output = new ByteArrayOutputStream(MAX_SCHEMA_SIZE_IN_BYTES);
-		JAXBContext context =JAXBContext.newInstance(clazz);
-		pojoToXSD(context, output);
-		return new String(output.toByteArray());
-	}
-
-	public static InputStream xmlSchema(Class<?> clazz) throws IOException, TransformerException, JAXBException {
-		ByteArrayOutputStream output = new ByteArrayOutputStream(MAX_SCHEMA_SIZE_IN_BYTES);
-		JAXBContext context =JAXBContext.newInstance(clazz);
-		pojoToXSD(context, output);
-		return new ByteArrayInputStream(output.toByteArray());
-	}
-
-	public static void pojoToXSD(JAXBContext context, OutputStream out)
-		    throws IOException, TransformerException
-		{
-		    final List<DOMResult> results = new ArrayList<DOMResult>();
-
-		    context.generateSchema(new SchemaOutputResolver() {
-		        @Override
-		        public Result createOutput(String ns, String file)
-		                throws IOException {
-		            DOMResult result = new DOMResult();
-		            result.setSystemId(file);
-		            results.add(result);
-		            return result;
-		        }
-		    });
-
-		    DOMResult domResult = results.get(0);
-		    Document doc = (Document) domResult.getNode();
-
-		    // Use a Transformer for output
-		    TransformerFactory tFactory = TransformerFactory.newInstance();
-		    Transformer transformer = tFactory.newTransformer();
-
-		    DOMSource source = new DOMSource(doc);
-		    StreamResult result = new StreamResult(out);
-		    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-		    transformer.transform(source, result);
-		}
+    private static final int MAX_SCHEMA_SIZE_IN_BYTES = 100000;
+
+
+    //Note: this main method is called by the maven build to generate the schema for the jar
+    public static void main(final String[] args) throws IOException, TransformerException, JAXBException, ClassNotFoundException {
+        if (args.length != 2) {
+            printUsage();
+            System.exit(0);
+        }
+        final Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(args[1]);
+
+        final JAXBContext context = JAXBContext.newInstance(clazz);
+        String xsdFileName = "Schema.xsd";
+        if (args.length != 0) {
+            xsdFileName = args[0] + "/" + xsdFileName;
+        }
+        final FileOutputStream s = new FileOutputStream(xsdFileName);
+        pojoToXSD(context, s);
+    }
+
+    private static void printUsage() {
+        System.out.println(XMLSchemaGenerator.class.getName() + " <file> <class1>");
+
+    }
+
+    public static String xmlSchemaAsString(final Class<?> clazz) throws IOException, TransformerException, JAXBException {
+        final ByteArrayOutputStream output = new ByteArrayOutputStream(MAX_SCHEMA_SIZE_IN_BYTES);
+        final JAXBContext context = JAXBContext.newInstance(clazz);
+        pojoToXSD(context, output);
+        return new String(output.toByteArray());
+    }
+
+    public static InputStream xmlSchema(final Class<?> clazz) throws IOException, TransformerException, JAXBException {
+        final ByteArrayOutputStream output = new ByteArrayOutputStream(MAX_SCHEMA_SIZE_IN_BYTES);
+        final JAXBContext context = JAXBContext.newInstance(clazz);
+        pojoToXSD(context, output);
+        return new ByteArrayInputStream(output.toByteArray());
+    }
+
+    public static void pojoToXSD(final JAXBContext context, final OutputStream out)
+            throws IOException, TransformerException {
+        final List<DOMResult> results = new ArrayList<DOMResult>();
+
+        context.generateSchema(new SchemaOutputResolver() {
+            @Override
+            public Result createOutput(final String ns, final String file)
+                    throws IOException {
+                final DOMResult result = new DOMResult();
+                result.setSystemId(file);
+                results.add(result);
+                return result;
+            }
+        });
+
+        final DOMResult domResult = results.get(0);
+        final Document doc = (Document) domResult.getNode();
+
+        // Use a Transformer for output
+        final TransformerFactory tFactory = TransformerFactory.newInstance();
+        final Transformer transformer = tFactory.newTransformer();
+
+        final DOMSource source = new DOMSource(doc);
+        final StreamResult result = new StreamResult(out);
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        transformer.transform(source, result);
+    }
 
 }
diff --git a/util/src/main/java/com/ning/billing/util/config/XMLWriter.java b/util/src/main/java/com/ning/billing/util/config/XMLWriter.java
index 58e42dd..001b6c9 100644
--- a/util/src/main/java/com/ning/billing/util/config/XMLWriter.java
+++ b/util/src/main/java/com/ning/billing/util/config/XMLWriter.java
@@ -16,22 +16,21 @@
 
 package com.ning.billing.util.config;
 
-import java.io.ByteArrayOutputStream;
-
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Marshaller;
+import java.io.ByteArrayOutputStream;
 
 public class XMLWriter<T> {
-	final private static  int MAX_XML_SIZE_IN_BYTES = 100000;
-	
-	public static <T> String writeXML(T object, Class<T> type) throws Exception {
-   	 	JAXBContext context =JAXBContext.newInstance(type);
-        Marshaller marshaller = context.createMarshaller();
-        marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
-        ByteArrayOutputStream output = new ByteArrayOutputStream(MAX_XML_SIZE_IN_BYTES);
-        
+    private static final int MAX_XML_SIZE_IN_BYTES = 100000;
+
+    public static <T> String writeXML(final T object, final Class<T> type) throws Exception {
+        final JAXBContext context = JAXBContext.newInstance(type);
+        final Marshaller marshaller = context.createMarshaller();
+        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+        final ByteArrayOutputStream output = new ByteArrayOutputStream(MAX_XML_SIZE_IN_BYTES);
+
         marshaller.marshal(object, output);
-        
+
         return new String(output.toByteArray());
-   }
+    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java b/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java
index 029dbbc..1c09e90 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java
@@ -16,6 +16,10 @@
 
 package com.ning.billing.util.customfield.api;
 
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
 import com.google.inject.Inject;
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.callcontext.CallContext;
@@ -23,25 +27,21 @@ import com.ning.billing.util.customfield.CustomField;
 import com.ning.billing.util.customfield.dao.CustomFieldDao;
 import com.ning.billing.util.dao.ObjectType;
 
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
 public class DefaultCustomFieldUserApi implements CustomFieldUserApi {
     private final CustomFieldDao customFieldDao;
 
     @Inject
-    public DefaultCustomFieldUserApi(CustomFieldDao customFieldDao) {
+    public DefaultCustomFieldUserApi(final CustomFieldDao customFieldDao) {
         this.customFieldDao = customFieldDao;
     }
 
     @Override
-    public Map<String, CustomField> getCustomFields(UUID objectId, ObjectType objectType) {
+    public Map<String, CustomField> getCustomFields(final UUID objectId, final ObjectType objectType) {
         return customFieldDao.loadEntities(objectId, objectType);
     }
 
     @Override
-    public void saveCustomFields(UUID objectId, ObjectType objectType, List<CustomField> fields, CallContext context) {
+    public void saveCustomFields(final UUID objectId, final ObjectType objectType, final List<CustomField> fields, final CallContext context) {
         customFieldDao.saveEntities(objectId, objectType, fields, context);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java
index e5d5ad0..56326df 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/AuditedCustomFieldDao.java
@@ -39,12 +39,12 @@ public class AuditedCustomFieldDao extends AuditedCollectionDaoBase<CustomField,
     }
 
     @Override
-    protected String getEquivalenceObjectFor(CustomField obj) {
+    protected String getEquivalenceObjectFor(final CustomField obj) {
         return obj.getName();
     }
 
     @Override
-    protected UpdatableEntityCollectionSqlDao<CustomField> transmogrifyDao(Transmogrifier transactionalDao) {
+    protected UpdatableEntityCollectionSqlDao<CustomField> transmogrifyDao(final Transmogrifier transactionalDao) {
         return transactionalDao.become(CustomFieldSqlDao.class);
     }
 
@@ -54,7 +54,7 @@ public class AuditedCustomFieldDao extends AuditedCollectionDaoBase<CustomField,
     }
 
     @Override
-    protected String getKey(CustomField entity) {
+    protected String getKey(final CustomField entity) {
         return entity.getName();
     }
 
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldBinder.java b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldBinder.java
index c56ed40..6c20dd7 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldBinder.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldBinder.java
@@ -16,28 +16,29 @@
 
 package com.ning.billing.util.customfield.dao;
 
-import com.ning.billing.util.customfield.CustomField;
-import org.skife.jdbi.v2.SQLStatement;
-import org.skife.jdbi.v2.sqlobject.Binder;
-import org.skife.jdbi.v2.sqlobject.BinderFactory;
-import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import com.ning.billing.util.customfield.CustomField;
+
 @BindingAnnotation(CustomFieldBinder.CustomFieldBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface CustomFieldBinder {
     public static class CustomFieldBinderFactory implements BinderFactory {
         @Override
-        public Binder build(Annotation annotation) {
+        public Binder build(final Annotation annotation) {
             return new Binder<CustomFieldBinder, CustomField>() {
                 @Override
-                public void bind(SQLStatement q, CustomFieldBinder bind, CustomField customField) {
+                public void bind(final SQLStatement q, final CustomFieldBinder bind, final CustomField customField) {
                     q.bind("id", customField.getId().toString());
                     q.bind("fieldName", customField.getName());
                     q.bind("fieldValue", customField.getValue());
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldHistoryBinder.java b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldHistoryBinder.java
index 51a60e8..506017a 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldHistoryBinder.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldHistoryBinder.java
@@ -16,30 +16,30 @@
 
 package com.ning.billing.util.customfield.dao;
 
-import com.ning.billing.util.customfield.CustomField;
-import com.ning.billing.util.dao.EntityHistory;
-import com.ning.billing.util.dao.MappedEntity;
-import org.skife.jdbi.v2.SQLStatement;
-import org.skife.jdbi.v2.sqlobject.Binder;
-import org.skife.jdbi.v2.sqlobject.BinderFactory;
-import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.dao.EntityHistory;
+
 @BindingAnnotation(CustomFieldHistoryBinder.CustomFieldBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface CustomFieldHistoryBinder {
     public static class CustomFieldBinderFactory implements BinderFactory {
         @Override
-        public Binder build(Annotation annotation) {
+        public Binder build(final Annotation annotation) {
             return new Binder<CustomFieldHistoryBinder, EntityHistory<CustomField>>() {
                 @Override
-                public void bind(SQLStatement q, CustomFieldHistoryBinder bind, EntityHistory<CustomField> customFieldHistory) {
+                public void bind(final SQLStatement<?> q, final CustomFieldHistoryBinder bind, final EntityHistory<CustomField> customFieldHistory) {
                     q.bind("recordId", customFieldHistory.getValue());
                     q.bind("changeType", customFieldHistory.getChangeType().toString());
                     q.bind("id", customFieldHistory.getId().toString());
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldMapper.java b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldMapper.java
index 3f3c982..774367d 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldMapper.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldMapper.java
@@ -16,22 +16,23 @@
 
 package com.ning.billing.util.customfield.dao;
 
-import com.ning.billing.util.customfield.CustomField;
-import com.ning.billing.util.customfield.StringCustomField;
-import com.ning.billing.util.dao.MapperBase;
-import org.skife.jdbi.v2.StatementContext;
-import org.skife.jdbi.v2.tweak.ResultSetMapper;
-
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.UUID;
 
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.customfield.StringCustomField;
+import com.ning.billing.util.dao.MapperBase;
+
 public class CustomFieldMapper extends MapperBase implements ResultSetMapper<CustomField> {
     @Override
-    public CustomField map(int index, ResultSet result, StatementContext context) throws SQLException {
-        UUID id = UUID.fromString(result.getString("id"));
-        String fieldName = result.getString("field_name");
-        String fieldValue = result.getString("field_value");
+    public CustomField map(final int index, final ResultSet result, final StatementContext context) throws SQLException {
+        final UUID id = UUID.fromString(result.getString("id"));
+        final String fieldName = result.getString("field_name");
+        final String fieldValue = result.getString("field_value");
         return new StringCustomField(id, fieldName, fieldValue);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java
index 4da5a59..93fd002 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/dao/CustomFieldSqlDao.java
@@ -37,32 +37,32 @@ import com.ning.billing.util.entity.collection.dao.UpdatableEntityCollectionSqlD
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper(CustomFieldMapper.class)
 public interface CustomFieldSqlDao extends UpdatableEntityCollectionSqlDao<CustomField>,
-                                           Transactional<CustomFieldSqlDao>, Transmogrifier {
+        Transactional<CustomFieldSqlDao>, Transmogrifier {
     @Override
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void insertFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @CustomFieldBinder final Collection<CustomField> entities,
                                       @CallContextBinder final CallContext context);
 
     @Override
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void updateFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @CustomFieldBinder final Collection<CustomField> entities,
                                       @CallContextBinder final CallContext context);
 
     @Override
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void deleteFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @CustomFieldBinder final Collection<CustomField> entities,
                                       @CallContextBinder final CallContext context);
 
     @Override
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void addHistoryFromTransaction(@Bind("objectId") final String objectId,
-                                               @ObjectTypeBinder final ObjectType objectType,
-                                               @CustomFieldHistoryBinder final List<EntityHistory<CustomField>> entities,
-                                               @CallContextBinder final CallContext context);
+                                          @ObjectTypeBinder final ObjectType objectType,
+                                          @CustomFieldHistoryBinder final List<EntityHistory<CustomField>> entities,
+                                          @CallContextBinder final CallContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/customfield/DefaultFieldStore.java b/util/src/main/java/com/ning/billing/util/customfield/DefaultFieldStore.java
index 8698787..7460d13 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/DefaultFieldStore.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/DefaultFieldStore.java
@@ -22,20 +22,20 @@ import com.ning.billing.util.dao.ObjectType;
 import com.ning.billing.util.entity.collection.EntityCollectionBase;
 
 public class DefaultFieldStore extends EntityCollectionBase<CustomField> implements FieldStore {
-    public DefaultFieldStore(UUID objectId, ObjectType objectType) {
+    public DefaultFieldStore(final UUID objectId, final ObjectType objectType) {
         super(objectId, objectType);
     }
 
-    public static DefaultFieldStore create(UUID objectId, ObjectType objectType) {
+    public static DefaultFieldStore create(final UUID objectId, final ObjectType objectType) {
         return new DefaultFieldStore(objectId, objectType);
     }
 
     @Override
-    public String getEntityKey(CustomField entity) {
+    public String getEntityKey(final CustomField entity) {
         return entity.getName();
     }
 
-    public void setValue(String fieldName, String fieldValue) {
+    public void setValue(final String fieldName, final String fieldValue) {
         if (entities.containsKey(fieldName)) {
             entities.get(fieldName).setValue(fieldValue);
         } else {
@@ -43,11 +43,11 @@ public class DefaultFieldStore extends EntityCollectionBase<CustomField> impleme
         }
     }
 
-    public String getValue(String fieldName) {
+    public String getValue(final String fieldName) {
         if (entities.containsKey(fieldName)) {
             return entities.get(fieldName).getValue();
         } else {
             return null;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java b/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java
index 7b7268a..98257fa 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java
@@ -24,13 +24,13 @@ public class StringCustomField extends UpdatableEntityBase implements CustomFiel
     private final String name;
     private String value;
 
-    public StringCustomField(String name, String value) {
+    public StringCustomField(final String name, final String value) {
         super();
         this.name = name;
         this.value = value;
     }
 
-    public StringCustomField(UUID id, String name, String value) {
+    public StringCustomField(final UUID id, final String name, final String value) {
         super(id);
         this.name = name;
         this.value = value;
@@ -47,7 +47,7 @@ public class StringCustomField extends UpdatableEntityBase implements CustomFiel
     }
 
     @Override
-    public void setValue(String value) {
+    public void setValue(final String value) {
         this.value = value;
     }
 
@@ -66,26 +66,31 @@ public class StringCustomField extends UpdatableEntityBase implements CustomFiel
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals(final Object obj) {
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
-        StringCustomField other = (StringCustomField) obj;
+        }
+        final StringCustomField other = (StringCustomField) obj;
         if (name == null) {
-            if (other.name != null)
+            if (other.name != null) {
                 return false;
-        }
-        else if (!name.equals(other.name))
+            }
+        } else if (!name.equals(other.name)) {
             return false;
+        }
         if (value == null) {
-            if (other.value != null)
+            if (other.value != null) {
                 return false;
-        }
-        else if (!value.equals(other.value))
+            }
+        } else if (!value.equals(other.value)) {
             return false;
+        }
         return true;
     }
 
diff --git a/util/src/main/java/com/ning/billing/util/dao/AuditBinder.java b/util/src/main/java/com/ning/billing/util/dao/AuditBinder.java
index a518578..179a670 100644
--- a/util/src/main/java/com/ning/billing/util/dao/AuditBinder.java
+++ b/util/src/main/java/com/ning/billing/util/dao/AuditBinder.java
@@ -16,27 +16,27 @@
 
 package com.ning.billing.util.dao;
 
-import org.skife.jdbi.v2.SQLStatement;
-import org.skife.jdbi.v2.sqlobject.Binder;
-import org.skife.jdbi.v2.sqlobject.BinderFactory;
-import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
 @BindingAnnotation(AuditBinder.AuditBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface AuditBinder {
     public static class AuditBinderFactory implements BinderFactory {
         @Override
-        public Binder build(Annotation annotation) {
+        public Binder build(final Annotation annotation) {
             return new Binder<AuditBinder, EntityAudit>() {
                 @Override
-                public void bind(SQLStatement q, AuditBinder bind, EntityAudit audit) {
+                public void bind(final SQLStatement q, final AuditBinder bind, final EntityAudit audit) {
                     q.bind("tableName", audit.getTableName().toString());
                     q.bind("recordId", audit.getRecordId());
                     q.bind("changeType", audit.getChangeType().toString());
diff --git a/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDao.java b/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDao.java
index 98352b2..2577ff2 100644
--- a/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDao.java
@@ -16,14 +16,15 @@
 
 package com.ning.billing.util.dao;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.entity.Entity;
-import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
-
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.entity.Entity;
+
 public interface AuditedCollectionDao<T extends Entity> {
     void saveEntitiesFromTransaction(Transmogrifier transactionalDao, UUID objectId, ObjectType objectType,
                                      List<T> entities, CallContext context);
diff --git a/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDaoBase.java b/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDaoBase.java
index 3cf6620..f129496 100644
--- a/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDaoBase.java
+++ b/util/src/main/java/com/ning/billing/util/dao/AuditedCollectionDaoBase.java
@@ -47,144 +47,168 @@ public abstract class AuditedCollectionDaoBase<T extends Entity, V> implements A
      */
     protected abstract V getEquivalenceObjectFor(T obj);
 
+    /**
+     * Update all entities of given type objectType for the given objectId, e.g. if T is AccountEmail, objectId will
+     * represent an account id and objectType will be ACCOUNT_EMAIL.
+     * <p/>
+     * This will add and delete entities as needed.
+     *
+     * @param transactionalDao the current dao (in the transaction)
+     * @param objectId         the parent object id
+     * @param objectType       the entity object type
+     * @param newEntities      the final list of entities
+     * @param context          the current content
+     */
     @Override
-    public void saveEntitiesFromTransaction(Transmogrifier transactionalDao, UUID objectId, ObjectType objectType, List<T> newEntities, CallContext context) {
-        UpdatableEntityCollectionSqlDao<T> dao = transmogrifyDao(transactionalDao);
+    public void saveEntitiesFromTransaction(final Transmogrifier transactionalDao, final UUID objectId, final ObjectType objectType, final List<T> newEntities, final CallContext context) {
+        final UpdatableEntityCollectionSqlDao<T> dao = transmogrifyDao(transactionalDao);
 
-        // get list of existing entities
-        List<T> currentEntities = dao.load(objectId.toString(), objectType);
+        // Get list of all existing entities for this parent object, e.g. find all email addresses for this account
+        final List<T> currentEntities = dao.load(objectId.toString(), objectType);
 
-        Map<V, T> currentObjs = new HashMap<V, T>(currentEntities.size());
-        Map<V, T> updatedObjs = new HashMap<V, T>(newEntities.size());
+        // Compute the list of objects to add, remove and/or update
+        final Map<V, T> currentObjs = new HashMap<V, T>(currentEntities.size());
+        final Map<V, T> updatedObjs = new HashMap<V, T>(newEntities.size());
 
-        for (T currentObj : currentEntities) {
+        for (final T currentObj : currentEntities) {
             currentObjs.put(getEquivalenceObjectFor(currentObj), currentObj);
         }
-        for (T updatedObj : newEntities) {
+        for (final T updatedObj : newEntities) {
             updatedObjs.put(getEquivalenceObjectFor(updatedObj), updatedObj);
         }
 
-        Set<V> equivToRemove = Sets.difference(currentObjs.keySet(), updatedObjs.keySet());
-        Set<V> equivToAdd = Sets.difference(updatedObjs.keySet(), currentObjs.keySet());
-        Set<V> equivToCheckForUpdate = Sets.intersection(updatedObjs.keySet(), currentObjs.keySet());
+        final Set<V> equivToRemove = Sets.difference(currentObjs.keySet(), updatedObjs.keySet());
+        final Set<V> equivToAdd = Sets.difference(updatedObjs.keySet(), currentObjs.keySet());
+        final Set<V> equivToCheckForUpdate = Sets.intersection(updatedObjs.keySet(), currentObjs.keySet());
 
-        List<T> objsToAdd = new ArrayList<T>(equivToAdd.size());
-        List<T> objsToRemove = new ArrayList<T>(equivToRemove.size());
-        List<T> objsToUpdate = new ArrayList<T>(equivToCheckForUpdate.size());
+        final List<T> objsToAdd = new ArrayList<T>(equivToAdd.size());
+        final List<T> objsToRemove = new ArrayList<T>(equivToRemove.size());
+        final List<T> objsToUpdate = new ArrayList<T>(equivToCheckForUpdate.size());
 
-        for (V equiv : equivToAdd) {
+        for (final V equiv : equivToAdd) {
             objsToAdd.add(updatedObjs.get(equiv));
         }
-        for (V equiv : equivToRemove) {
+        for (final V equiv : equivToRemove) {
             objsToRemove.add(currentObjs.get(equiv));
         }
-        for (V equiv : equivToCheckForUpdate) {
-            T currentObj = currentObjs.get(equiv);
-            T updatedObj = updatedObjs.get(equiv);
+        for (final V equiv : equivToCheckForUpdate) {
+            final T currentObj = currentObjs.get(equiv);
+            final T updatedObj = updatedObjs.get(equiv);
             if (!currentObj.equals(updatedObj)) {
                 objsToUpdate.add(updatedObj);
             }
         }
 
+        // Perform the inserts
         if (objsToAdd.size() != 0) {
             dao.insertFromTransaction(objectId.toString(), objectType, objsToAdd, context);
         }
 
+        // Perform the updates
         if (objsToUpdate.size() != 0) {
             dao.updateFromTransaction(objectId.toString(), objectType, objsToUpdate, context);
         }
 
-        // get all custom entities (including those that are about to be deleted) from the database in order to get the record ids
-        List<Mapper<UUID, Long>> recordIds = dao.getRecordIds(objectId.toString(), objectType);
-        Map<UUID, Long> recordIdMap = convertToHistoryMap(recordIds);
+        // Find all pairs <entity id, record id> (including those that are about to be deleted) for this parent object
+        final List<Mapper<UUID, Long>> recordIds = dao.getRecordIds(objectId.toString(), objectType);
+        // Flip the map to look up the record id associated with an entity id
+        final Map<UUID, Long> recordIdMap = convertToHistoryMap(recordIds);
 
+        // Perform the deletes
         if (objsToRemove.size() != 0) {
             dao.deleteFromTransaction(objectId.toString(), objectType, objsToRemove, context);
         }
 
-        List<EntityHistory<T>> entityHistories = new ArrayList<EntityHistory<T>>();
+        // Create the history objects
+        final List<EntityHistory<T>> entityHistories = new ArrayList<EntityHistory<T>>();
         entityHistories.addAll(convertToHistory(objsToAdd, recordIdMap, ChangeType.INSERT));
         entityHistories.addAll(convertToHistory(objsToUpdate, recordIdMap, ChangeType.UPDATE));
         entityHistories.addAll(convertToHistory(objsToRemove, recordIdMap, ChangeType.DELETE));
 
-        Long maxHistoryRecordId = dao.getMaxHistoryRecordId();
+        final Long maxHistoryRecordId = dao.getMaxHistoryRecordId();
+        // Save the records in the history table
         dao.addHistoryFromTransaction(objectId.toString(), objectType, entityHistories, context);
 
-        // have to fetch history record ids to update audit log
-        List<Mapper<Long, Long>> historyRecordIds = dao.getHistoryRecordIds(maxHistoryRecordId);
-        Map<Long, Long> historyRecordIdMap = convertToAuditMap(historyRecordIds);
-        List<EntityAudit> entityAudits = convertToAudits(entityHistories, historyRecordIdMap);
+        // We have to fetch history record ids to update audit log
+        final List<Mapper<Long, Long>> historyRecordIds = dao.getHistoryRecordIds(maxHistoryRecordId);
+        final Map<Long, Long> historyRecordIdMap = convertToAuditMap(historyRecordIds);
+        final List<EntityAudit> entityAudits = convertToAudits(entityHistories, historyRecordIdMap);
 
+        // Save an entry in the audit log
         dao.insertAuditFromTransaction(entityAudits, context);
     }
 
     @Override
-    public void saveEntities(UUID objectId, ObjectType objectType, List<T> entities, CallContext context) {
+    public void saveEntities(final UUID objectId, final ObjectType objectType, final List<T> entities, final CallContext context) {
         this.saveEntitiesFromTransaction(getSqlDao(), objectId, objectType, entities, context);
     }
 
     @Override
     public Map<String, T> loadEntities(final UUID objectId, final ObjectType objectType) {
-        UpdatableEntityCollectionSqlDao<T> thisDao = getSqlDao();
+        final UpdatableEntityCollectionSqlDao<T> thisDao = getSqlDao();
         return getMap(thisDao, objectId, objectType);
     }
 
     @Override
     public Map<String, T> loadEntitiesFromTransaction(final Transmogrifier dao, final UUID objectId, final ObjectType objectType) {
-        UpdatableEntityCollectionSqlDao<T> thisDao = transmogrifyDao(dao);
+        final UpdatableEntityCollectionSqlDao<T> thisDao = transmogrifyDao(dao);
         return getMap(thisDao, objectId, objectType);
     }
 
     private Map<String, T> getMap(final UpdatableEntityCollectionSqlDao<T> dao, final UUID objectId, final ObjectType objectType) {
-        List<T> entities = dao.load(objectId.toString(), objectType);
-        Map<String, T> results = new HashMap<String, T>();
-        for (T entity : entities) {
+        final List<T> entities = dao.load(objectId.toString(), objectType);
+        final Map<String, T> results = new HashMap<String, T>();
+        for (final T entity : entities) {
             results.put(getKey(entity), entity);
         }
         return results;
     }
 
-    protected List<EntityHistory<T>> convertToHistory(Collection<T> entities, Map<UUID, Long> recordIds, ChangeType changeType) {
-        List<EntityHistory<T>> histories = new ArrayList<EntityHistory<T>>();
+    protected List<EntityHistory<T>> convertToHistory(final Collection<T> entities, final Map<UUID, Long> recordIds, final ChangeType changeType) {
+        final List<EntityHistory<T>> histories = new ArrayList<EntityHistory<T>>();
 
-        for (T entity : entities) {
-            UUID id = entity.getId();
+        for (final T entity : entities) {
+            final UUID id = entity.getId();
             histories.add(new EntityHistory<T>(id, recordIds.get(id), entity, changeType));
         }
 
         return histories;
     }
 
-    protected List<EntityAudit> convertToAudits(List<EntityHistory<T>> histories, Map<Long, Long> historyRecordIds) {
-        List<EntityAudit> audits = new ArrayList<EntityAudit>();
+    protected List<EntityAudit> convertToAudits(final List<EntityHistory<T>> histories, final Map<Long, Long> historyRecordIds) {
+        final List<EntityAudit> audits = new ArrayList<EntityAudit>();
 
-        for (EntityHistory<T> history : histories) {
-            Long recordId = history.getValue();
-            Long historyRecordId = historyRecordIds.get(recordId);
+        for (final EntityHistory<T> history : histories) {
+            final Long recordId = history.getValue();
+            final Long historyRecordId = historyRecordIds.get(recordId);
             audits.add(new EntityAudit(getTableName(), historyRecordId, history.getChangeType()));
         }
 
         return audits;
     }
 
-    protected Map<UUID, Long> convertToHistoryMap(List<Mapper<UUID, Long>> recordIds) {
-        Map<UUID, Long> recordIdMap = new HashMap<UUID, Long>();
-        for (Mapper<UUID, Long> recordId : recordIds) {
+    protected Map<UUID, Long> convertToHistoryMap(final List<Mapper<UUID, Long>> recordIds) {
+        final Map<UUID, Long> recordIdMap = new HashMap<UUID, Long>();
+        for (final Mapper<UUID, Long> recordId : recordIds) {
             recordIdMap.put(recordId.getKey(), recordId.getValue());
         }
+
         return recordIdMap;
     }
 
-    protected Map<Long, Long> convertToAuditMap(List<Mapper<Long, Long>> historyRecordIds) {
-        Map<Long, Long> historyRecordIdMap = new HashMap<Long, Long>();
-        for (Mapper<Long, Long> historyRecordId : historyRecordIds) {
+    protected Map<Long, Long> convertToAuditMap(final List<Mapper<Long, Long>> historyRecordIds) {
+        final Map<Long, Long> historyRecordIdMap = new HashMap<Long, Long>();
+        for (final Mapper<Long, Long> historyRecordId : historyRecordIds) {
             historyRecordIdMap.put(historyRecordId.getKey(), historyRecordId.getValue());
         }
         return historyRecordIdMap;
     }
 
     protected abstract TableName getTableName();
+
     protected abstract UpdatableEntityCollectionSqlDao<T> transmogrifyDao(Transmogrifier transactionalDao);
+
     protected abstract UpdatableEntityCollectionSqlDao<T> getSqlDao();
+
     protected abstract String getKey(T entity);
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/BinderBase.java b/util/src/main/java/com/ning/billing/util/dao/BinderBase.java
index df36442..7949fb7 100644
--- a/util/src/main/java/com/ning/billing/util/dao/BinderBase.java
+++ b/util/src/main/java/com/ning/billing/util/dao/BinderBase.java
@@ -16,17 +16,17 @@
 
 package com.ning.billing.util.dao;
 
-import org.joda.time.DateTime;
-
 import java.util.Date;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+
 public abstract class BinderBase {
-    protected Date getDate(DateTime dateTime) {
+    protected Date getDate(final DateTime dateTime) {
         return dateTime == null ? null : dateTime.toDate();
     }
 
-    protected String uuidToString(UUID uuid) {
+    protected String uuidToString(final UUID uuid) {
         if (uuid == null) {
             return null;
         } else {
diff --git a/util/src/main/java/com/ning/billing/util/dao/ChangeTypeBinder.java b/util/src/main/java/com/ning/billing/util/dao/ChangeTypeBinder.java
index 58ed27b..9a94e98 100644
--- a/util/src/main/java/com/ning/billing/util/dao/ChangeTypeBinder.java
+++ b/util/src/main/java/com/ning/billing/util/dao/ChangeTypeBinder.java
@@ -16,26 +16,27 @@
 
 package com.ning.billing.util.dao;
 
-import com.ning.billing.util.ChangeType;
-import org.skife.jdbi.v2.SQLStatement;
-import org.skife.jdbi.v2.sqlobject.Binder;
-import org.skife.jdbi.v2.sqlobject.BinderFactory;
-import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
+import com.ning.billing.util.ChangeType;
+
 @BindingAnnotation(ChangeTypeBinder.ChangeTypeBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface ChangeTypeBinder {
     public static class ChangeTypeBinderFactory implements BinderFactory {
-        public Binder build(Annotation annotation) {
+        public Binder build(final Annotation annotation) {
             return new Binder<ChangeTypeBinder, ChangeType>() {
-                public void bind(SQLStatement q, ChangeTypeBinder bind, ChangeType changeType) {
+                public void bind(final SQLStatement q, final ChangeTypeBinder bind, final ChangeType changeType) {
                     q.bind("changeType", changeType.toString());
                 }
             };
diff --git a/util/src/main/java/com/ning/billing/util/dao/CollectionHistorySqlDao.java b/util/src/main/java/com/ning/billing/util/dao/CollectionHistorySqlDao.java
index d3a01d5..2ab74f6 100644
--- a/util/src/main/java/com/ning/billing/util/dao/CollectionHistorySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/CollectionHistorySqlDao.java
@@ -16,19 +16,19 @@
 
 package com.ning.billing.util.dao;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.entity.Entity;
+import java.util.List;
+
 import org.skife.jdbi.v2.sqlobject.SqlBatch;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-import java.util.List;
-import java.util.UUID;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.entity.Entity;
 
 public interface CollectionHistorySqlDao<T extends Entity> {
-    @SqlBatch(transactional = false)
+    @SqlBatch
     public void addHistoryFromTransaction(String objectId, ObjectType objectType,
-                                           List<EntityHistory<T>> histories,
-                                           CallContext context);
+                                          List<EntityHistory<T>> histories,
+                                          CallContext context);
 
     @SqlUpdate
     public void addHistoryFromTransaction(String objectId, ObjectType objectType,
diff --git a/util/src/main/java/com/ning/billing/util/dao/EntityAudit.java b/util/src/main/java/com/ning/billing/util/dao/EntityAudit.java
index 15280fa..007ec93 100644
--- a/util/src/main/java/com/ning/billing/util/dao/EntityAudit.java
+++ b/util/src/main/java/com/ning/billing/util/dao/EntityAudit.java
@@ -23,7 +23,7 @@ public class EntityAudit {
     private final Long recordId;
     private final ChangeType changeType;
 
-    public EntityAudit(TableName tableName, Long recordId, ChangeType changeType) {
+    public EntityAudit(final TableName tableName, final Long recordId, final ChangeType changeType) {
         this.tableName = tableName;
         this.recordId = recordId;
         this.changeType = changeType;
diff --git a/util/src/main/java/com/ning/billing/util/dao/EntityHistory.java b/util/src/main/java/com/ning/billing/util/dao/EntityHistory.java
index 536de35..c1fe765 100644
--- a/util/src/main/java/com/ning/billing/util/dao/EntityHistory.java
+++ b/util/src/main/java/com/ning/billing/util/dao/EntityHistory.java
@@ -16,13 +16,13 @@
 
 package com.ning.billing.util.dao;
 
+import java.util.UUID;
+
 import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.entity.Entity;
 
-import java.util.UUID;
-
 public class EntityHistory<T extends Entity> extends MappedEntity<T, UUID, Long> {
-    public EntityHistory(UUID id, Long recordId, T entity, ChangeType changeType) {
+    public EntityHistory(final UUID id, final Long recordId, final T entity, final ChangeType changeType) {
         super(new Mapper<UUID, Long>(id, recordId), entity, changeType);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/HistoryRecordIdMapper.java b/util/src/main/java/com/ning/billing/util/dao/HistoryRecordIdMapper.java
index 3d6e3f5..83db044 100644
--- a/util/src/main/java/com/ning/billing/util/dao/HistoryRecordIdMapper.java
+++ b/util/src/main/java/com/ning/billing/util/dao/HistoryRecordIdMapper.java
@@ -16,18 +16,18 @@
 
 package com.ning.billing.util.dao;
 
-import org.skife.jdbi.v2.StatementContext;
-import org.skife.jdbi.v2.tweak.ResultSetMapper;
-
 import java.sql.ResultSet;
 import java.sql.SQLException;
 
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
 public class HistoryRecordIdMapper extends MapperBase implements ResultSetMapper<Mapper> {
     @Override
-    public Mapper<Long, Long> map(int index, ResultSet resultSet, StatementContext ctx) throws SQLException {
-        Long recordId = resultSet.getLong("record_id");
-        Long historyRecordId = resultSet.getLong("history_record_id");
+    public Mapper<Long, Long> map(final int index, final ResultSet resultSet, final StatementContext ctx) throws SQLException {
+        final Long recordId = resultSet.getLong("record_id");
+        final Long historyRecordId = resultSet.getLong("history_record_id");
 
         return new Mapper<Long, Long>(recordId, historyRecordId);
     }
-}
\ No newline at end of file
+}
diff --git a/util/src/main/java/com/ning/billing/util/dao/HistorySqlDao.java b/util/src/main/java/com/ning/billing/util/dao/HistorySqlDao.java
index d1327e1..19abc79 100644
--- a/util/src/main/java/com/ning/billing/util/dao/HistorySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/dao/HistorySqlDao.java
@@ -16,12 +16,13 @@
 
 package com.ning.billing.util.dao;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.entity.Entity;
+import java.util.List;
+
 import org.skife.jdbi.v2.sqlobject.SqlBatch;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-import java.util.List;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.entity.Entity;
 
 public interface HistorySqlDao<T extends Entity> {
     @SqlBatch(transactional = false)
diff --git a/util/src/main/java/com/ning/billing/util/dao/MappedEntity.java b/util/src/main/java/com/ning/billing/util/dao/MappedEntity.java
index 7bd8ad3..bad675f 100644
--- a/util/src/main/java/com/ning/billing/util/dao/MappedEntity.java
+++ b/util/src/main/java/com/ning/billing/util/dao/MappedEntity.java
@@ -16,17 +16,17 @@
 
 package com.ning.billing.util.dao;
 
+import java.util.UUID;
+
 import com.ning.billing.util.ChangeType;
 import com.ning.billing.util.entity.Entity;
 
-import java.util.UUID;
-
 public class MappedEntity<T extends Entity, K, V> {
     private final Mapper<K, V> mapper;
     private final T entity;
     private final ChangeType changeType;
 
-    public MappedEntity(Mapper<K, V> mapper, T entity, ChangeType changeType) {
+    public MappedEntity(final Mapper<K, V> mapper, final T entity, final ChangeType changeType) {
         this.mapper = mapper;
         this.entity = entity;
         this.changeType = changeType;
diff --git a/util/src/main/java/com/ning/billing/util/dao/Mapper.java b/util/src/main/java/com/ning/billing/util/dao/Mapper.java
index e4e178c..2afb901 100644
--- a/util/src/main/java/com/ning/billing/util/dao/Mapper.java
+++ b/util/src/main/java/com/ning/billing/util/dao/Mapper.java
@@ -20,7 +20,7 @@ public class Mapper<K, V> {
     private final K key;
     private final V value;
 
-    public Mapper(K key, V value) {
+    public Mapper(final K key, final V value) {
         this.key = key;
         this.value = value;
     }
diff --git a/util/src/main/java/com/ning/billing/util/dao/MapperBase.java b/util/src/main/java/com/ning/billing/util/dao/MapperBase.java
index 119b727..f688d66 100644
--- a/util/src/main/java/com/ning/billing/util/dao/MapperBase.java
+++ b/util/src/main/java/com/ning/billing/util/dao/MapperBase.java
@@ -16,22 +16,22 @@
 
 package com.ning.billing.util.dao;
 
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Timestamp;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
 public abstract class MapperBase {
-    protected DateTime getDate(ResultSet rs, String fieldName) throws SQLException {
+    protected DateTime getDate(final ResultSet rs, final String fieldName) throws SQLException {
         final Timestamp resultStamp = rs.getTimestamp(fieldName);
         return rs.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
     }
 
-    protected UUID getUUID(ResultSet resultSet, String fieldName) throws SQLException {
-        String result = resultSet.getString(fieldName);
+    protected UUID getUUID(final ResultSet resultSet, final String fieldName) throws SQLException {
+        final String result = resultSet.getString(fieldName);
         return result == null ? null : UUID.fromString(result);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/dao/ObjectTypeBinder.java b/util/src/main/java/com/ning/billing/util/dao/ObjectTypeBinder.java
index 18f0efc..74c5d80 100644
--- a/util/src/main/java/com/ning/billing/util/dao/ObjectTypeBinder.java
+++ b/util/src/main/java/com/ning/billing/util/dao/ObjectTypeBinder.java
@@ -16,25 +16,25 @@
 
 package com.ning.billing.util.dao;
 
-import org.skife.jdbi.v2.SQLStatement;
-import org.skife.jdbi.v2.sqlobject.Binder;
-import org.skife.jdbi.v2.sqlobject.BinderFactory;
-import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
 @BindingAnnotation(ObjectTypeBinder.ObjectTypeBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface ObjectTypeBinder {
     public static class ObjectTypeBinderFactory implements BinderFactory {
-        public Binder build(Annotation annotation) {
+        public Binder build(final Annotation annotation) {
             return new Binder<ObjectTypeBinder, ObjectType>() {
-                public void bind(SQLStatement q, ObjectTypeBinder bind, ObjectType objectType) {
+                public void bind(final SQLStatement q, final ObjectTypeBinder bind, final ObjectType objectType) {
                     q.bind("objectType", objectType.getObjectName());
                 }
             };
diff --git a/util/src/main/java/com/ning/billing/util/dao/RecordIdMapper.java b/util/src/main/java/com/ning/billing/util/dao/RecordIdMapper.java
index 35cdaf3..4b704ac 100644
--- a/util/src/main/java/com/ning/billing/util/dao/RecordIdMapper.java
+++ b/util/src/main/java/com/ning/billing/util/dao/RecordIdMapper.java
@@ -16,18 +16,18 @@
 
 package com.ning.billing.util.dao;
 
-import org.skife.jdbi.v2.StatementContext;
-import org.skife.jdbi.v2.tweak.ResultSetMapper;
-
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.UUID;
 
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
 public class RecordIdMapper extends MapperBase implements ResultSetMapper<Mapper> {
     @Override
-    public Mapper<UUID, Long> map(int index, ResultSet resultSet, StatementContext ctx) throws SQLException {
-        UUID id = getUUID(resultSet, "id");
-        Long recordId = resultSet.getLong("record_id");
+    public Mapper<UUID, Long> map(final int index, final ResultSet resultSet, final StatementContext ctx) throws SQLException {
+        final UUID id = getUUID(resultSet, "id");
+        final Long recordId = resultSet.getLong("record_id");
 
         return new Mapper<UUID, Long>(id, recordId);
     }
diff --git a/util/src/main/java/com/ning/billing/util/dao/TableName.java b/util/src/main/java/com/ning/billing/util/dao/TableName.java
index 98ec80d..1620b13 100644
--- a/util/src/main/java/com/ning/billing/util/dao/TableName.java
+++ b/util/src/main/java/com/ning/billing/util/dao/TableName.java
@@ -29,18 +29,18 @@ public enum TableName {
     PAYMENT_ATTEMPTS("payment_attempts"),
     PAYMENT_HISTORY("payment_history"),
     PAYMENTS("payments"),
-    PAYMENT_METHODS("payment_methods"),    
+    PAYMENT_METHODS("payment_methods"),
     RECURRING_INVOICE_ITEMS("recurring_invoice_items"),
     SUBSCRIPTIONS("subscriptions"),
     SUBSCRIPTION_EVENTS("subscription_events"),
     TAG_HISTORY("tag_history");
-    
+
     private final String tableName;
-    
-    TableName(String tableName) {
+
+    TableName(final String tableName) {
         this.tableName = tableName;
     }
-    
+
     public String getTableName() {
         return tableName;
     }
diff --git a/util/src/main/java/com/ning/billing/util/dao/TableNameBinder.java b/util/src/main/java/com/ning/billing/util/dao/TableNameBinder.java
index a93d915..545186c 100644
--- a/util/src/main/java/com/ning/billing/util/dao/TableNameBinder.java
+++ b/util/src/main/java/com/ning/billing/util/dao/TableNameBinder.java
@@ -16,28 +16,28 @@
 
 package com.ning.billing.util.dao;
 
-import org.skife.jdbi.v2.SQLStatement;
-import org.skife.jdbi.v2.sqlobject.Binder;
-import org.skife.jdbi.v2.sqlobject.BinderFactory;
-import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
-
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.skife.jdbi.v2.SQLStatement;
+import org.skife.jdbi.v2.sqlobject.Binder;
+import org.skife.jdbi.v2.sqlobject.BinderFactory;
+import org.skife.jdbi.v2.sqlobject.BindingAnnotation;
+
 @BindingAnnotation(TableNameBinder.TableNameBinderFactory.class)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER})
 public @interface TableNameBinder {
     public static class TableNameBinderFactory implements BinderFactory {
-        public Binder build(Annotation annotation) {
+        public Binder build(final Annotation annotation) {
             return new Binder<TableNameBinder, TableName>() {
-                public void bind(SQLStatement q, TableNameBinder bind, TableName tableName) {
+                public void bind(final SQLStatement q, final TableNameBinder bind, final TableName tableName) {
                     q.bind("tableName", tableName.getTableName());
                 }
             };
         }
     }
-}
\ No newline at end of file
+}
diff --git a/util/src/main/java/com/ning/billing/util/dao/UuidMapper.java b/util/src/main/java/com/ning/billing/util/dao/UuidMapper.java
index 2d6e5a6..104b8dc 100644
--- a/util/src/main/java/com/ning/billing/util/dao/UuidMapper.java
+++ b/util/src/main/java/com/ning/billing/util/dao/UuidMapper.java
@@ -16,16 +16,16 @@
 
 package com.ning.billing.util.dao;
 
-import org.skife.jdbi.v2.StatementContext;
-import org.skife.jdbi.v2.tweak.ResultSetMapper;
-
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.UUID;
 
+import org.skife.jdbi.v2.StatementContext;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
 public class UuidMapper implements ResultSetMapper<UUID> {
     @Override
-    public UUID map(final int index, ResultSet resultSet, StatementContext statementContext) throws SQLException {
+    public UUID map(final int index, final ResultSet resultSet, final StatementContext statementContext) throws SQLException {
         return UUID.fromString(resultSet.getString(1));
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/email/DefaultEmailSender.java b/util/src/main/java/com/ning/billing/util/email/DefaultEmailSender.java
index b4e3587..b89cdcb 100644
--- a/util/src/main/java/com/ning/billing/util/email/DefaultEmailSender.java
+++ b/util/src/main/java/com/ning/billing/util/email/DefaultEmailSender.java
@@ -24,45 +24,49 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
 
-public class DefaultEmailSender implements EmailSender { 
+public class DefaultEmailSender implements EmailSender {
     private final Logger log = LoggerFactory.getLogger(EmailSender.class);
     private final EmailConfig config;
 
     @Inject
-    public DefaultEmailSender(EmailConfig emailConfig) {
+    public DefaultEmailSender(final EmailConfig emailConfig) {
         this.config = emailConfig;
     }
 
     @Override
-    public void sendSecureEmail(List<String> to, List<String> cc, String subject, String htmlBody) throws EmailApiException {
-        HtmlEmail email;
+    public void sendSecureEmail(final List<String> to, final List<String> cc, final String subject, final String htmlBody) throws EmailApiException {
+        final HtmlEmail email;
         try {
             email = new HtmlEmail();
 
             email.setSmtpPort(config.getSmtpPort());
-            email.setAuthentication(config.getSmtpUserName(), config.getSmtpPassword());
+            if (config.useSmtpAuth()) {
+                email.setAuthentication(config.getSmtpUserName(), config.getSmtpPassword());
+            }
             email.setHostName(config.getSmtpServerName());
-            email.setFrom(config.getSmtpUserName());
+            email.setFrom(config.getDefaultFrom());
+
             email.setSubject(subject);
             email.setHtmlMsg(htmlBody);
 
             if (to != null) {
-                for (String recipient : to) {
+                for (final String recipient : to) {
                     email.addTo(recipient);
                 }
             }
 
             if (cc != null) {
-                for (String recipient : cc) {
+                for (final String recipient : cc) {
                     email.addCc(recipient);
                 }
             }
 
-            email.setSSL(true);
+            email.setSSL(config.useSSL());
             email.send();
-        } catch (EmailException ee)  {
-            log.warn("Failed to send e-mail", ee);
+        } catch (EmailException ee) {
+            throw new EmailApiException(ee, ErrorCode.EMAIL_SENDING_FAILED);
         }
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/email/EmailConfig.java b/util/src/main/java/com/ning/billing/util/email/EmailConfig.java
index bcbf5e5..2d9a583 100644
--- a/util/src/main/java/com/ning/billing/util/email/EmailConfig.java
+++ b/util/src/main/java/com/ning/billing/util/email/EmailConfig.java
@@ -16,26 +16,38 @@
 
 package com.ning.billing.util.email;
 
-import com.ning.billing.config.KillbillConfig;
 import org.skife.config.Config;
 import org.skife.config.Default;
+import org.skife.config.DefaultNull;
 
-import java.util.Locale;
+import com.ning.billing.config.KillbillConfig;
 
 public interface EmailConfig extends KillbillConfig {
-    @Config("mail.smtp.host")
-    @Default("smtp.gmail.com")
+    @Config("killbill.mail.smtp.host")
+    @DefaultNull
     public String getSmtpServerName();
 
-    @Config("mail.smtp.port")
-    @Default("465")
+    @Config("killbill.mail.smtp.port")
+    @DefaultNull
     public int getSmtpPort();
 
-    @Config("mail.smtp.user")
-    @Default("killbill.ning@gmail.com")
+    @Config("killbill.mail.smtp.auth")
+    @Default("false")
+    public boolean useSmtpAuth();
+
+    @Config("killbill.mail.smtp.user")
+    @DefaultNull
     public String getSmtpUserName();
 
-    @Config("mail.smtp.password")
-    @Default("killbill@ning!")
+    @Config("killbill.mail.smtp.password")
+    @DefaultNull
     public String getSmtpPassword();
+
+    @Config("killbill.mail.from")
+    @Default("support@example.com")
+    String getDefaultFrom();
+
+    @Config("killbill.mail.useSSL")
+    @Default("false")
+    boolean useSSL();
 }
diff --git a/util/src/main/java/com/ning/billing/util/email/EmailModule.java b/util/src/main/java/com/ning/billing/util/email/EmailModule.java
index 5bb252a..e8574cd 100644
--- a/util/src/main/java/com/ning/billing/util/email/EmailModule.java
+++ b/util/src/main/java/com/ning/billing/util/email/EmailModule.java
@@ -16,12 +16,13 @@
 
 package com.ning.billing.util.email;
 
-import com.google.inject.AbstractModule;
 import org.skife.config.ConfigurationObjectFactory;
 
+import com.google.inject.AbstractModule;
+
 public class EmailModule extends AbstractModule {
     protected void installEmailConfig() {
-        EmailConfig config = new ConfigurationObjectFactory(System.getProperties()).build(EmailConfig.class);
+        final EmailConfig config = new ConfigurationObjectFactory(System.getProperties()).build(EmailConfig.class);
         bind(EmailConfig.class).toInstance(config);
     }
 
diff --git a/util/src/main/java/com/ning/billing/util/email/templates/MustacheTemplateEngine.java b/util/src/main/java/com/ning/billing/util/email/templates/MustacheTemplateEngine.java
index dba8757..f6a76a3 100644
--- a/util/src/main/java/com/ning/billing/util/email/templates/MustacheTemplateEngine.java
+++ b/util/src/main/java/com/ning/billing/util/email/templates/MustacheTemplateEngine.java
@@ -16,27 +16,32 @@
 
 package com.ning.billing.util.email.templates;
 
-import com.samskivert.mustache.Mustache;
-import com.samskivert.mustache.Template;
-import org.apache.commons.io.IOUtils;
-
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.StringWriter;
+import java.net.URISyntaxException;
 import java.util.Map;
 
+import com.ning.billing.util.config.UriAccessor;
+import com.ning.billing.util.io.IOUtils;
+import com.samskivert.mustache.Mustache;
+import com.samskivert.mustache.Template;
+
 public class MustacheTemplateEngine implements TemplateEngine {
     @Override
-    public String executeTemplate(String templateName, Map<String, Object> data) throws IOException {
-        String templateText = getTemplateText(templateName);
-        Template template = Mustache.compiler().compile(templateText);
+    public String executeTemplate(final String templateName, final Map<String, Object> data) throws IOException {
+        final String templateText = getTemplateText(templateName);
+        final Template template = Mustache.compiler().compile(templateText);
         return template.execute(data);
     }
 
-    private String getTemplateText(String templateName) throws IOException {
-        InputStream templateStream = this.getClass().getResourceAsStream(templateName + ".mustache");
-        StringWriter writer = new StringWriter();
-        IOUtils.copy(templateStream, writer, "UTF-8");
-        return writer.toString();
+    private String getTemplateText(final String templateName) throws IOException {
+        final InputStream templateStream;
+        try {
+            templateStream = UriAccessor.accessUri(templateName);
+        } catch (URISyntaxException e) {
+            throw new IOException(e);
+        }
+
+        return IOUtils.toString(templateStream);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/email/templates/TemplateModule.java b/util/src/main/java/com/ning/billing/util/email/templates/TemplateModule.java
index 86a3124..0b0d63b 100644
--- a/util/src/main/java/com/ning/billing/util/email/templates/TemplateModule.java
+++ b/util/src/main/java/com/ning/billing/util/email/templates/TemplateModule.java
@@ -22,7 +22,7 @@ public class TemplateModule extends AbstractModule {
 
     @Override
     protected void configure() {
-        bind(TemplateEngine.class).to(MustacheTemplateEngine.class).asEagerSingleton();      
+        bind(TemplateEngine.class).to(MustacheTemplateEngine.class).asEagerSingleton();
     }
 
 }
diff --git a/util/src/main/java/com/ning/billing/util/entity/collection/dao/EntityCollectionSqlDao.java b/util/src/main/java/com/ning/billing/util/entity/collection/dao/EntityCollectionSqlDao.java
index e74a64a..2decb16 100644
--- a/util/src/main/java/com/ning/billing/util/entity/collection/dao/EntityCollectionSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/collection/dao/EntityCollectionSqlDao.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * 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
@@ -38,16 +38,17 @@ import com.ning.billing.util.entity.Entity;
 /**
  * provides consistent semantics for entity collections
  * note: this is intended to be extended by an interface which provides @ExternalizedSqlViaStringTemplate3 and mappers
+ *
  * @param <T>
  */
 public interface EntityCollectionSqlDao<T extends Entity> {
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void insertFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @BindBean final Collection<T> entities,
                                       @CallContextBinder final CallContext context);
 
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void deleteFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @BindBean final Collection<T> entities,
diff --git a/util/src/main/java/com/ning/billing/util/entity/collection/dao/UpdatableEntityCollectionSqlDao.java b/util/src/main/java/com/ning/billing/util/entity/collection/dao/UpdatableEntityCollectionSqlDao.java
index 0079008..554120f 100644
--- a/util/src/main/java/com/ning/billing/util/entity/collection/dao/UpdatableEntityCollectionSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/collection/dao/UpdatableEntityCollectionSqlDao.java
@@ -40,7 +40,7 @@ import com.ning.billing.util.entity.Entity;
 public interface UpdatableEntityCollectionSqlDao<T extends Entity> extends EntityCollectionSqlDao<T>,
         CollectionHistorySqlDao<T>,
         AuditSqlDao, CloseMe, Transmogrifier {
-    @SqlBatch(transactional=false)
+    @SqlBatch
     public void updateFromTransaction(@Bind("objectId") final String objectId,
                                       @ObjectTypeBinder final ObjectType objectType,
                                       @BindBean final Collection<T> entities,
diff --git a/util/src/main/java/com/ning/billing/util/entity/collection/EntityCollectionBase.java b/util/src/main/java/com/ning/billing/util/entity/collection/EntityCollectionBase.java
index 45a3bc8..c94e379 100644
--- a/util/src/main/java/com/ning/billing/util/entity/collection/EntityCollectionBase.java
+++ b/util/src/main/java/com/ning/billing/util/entity/collection/EntityCollectionBase.java
@@ -16,22 +16,22 @@
 
 package com.ning.billing.util.entity.collection;
 
-import com.ning.billing.util.dao.ObjectType;
-import com.ning.billing.util.entity.Entity;
-import com.ning.billing.util.entity.EntityCollection;
-
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import com.ning.billing.util.dao.ObjectType;
+import com.ning.billing.util.entity.Entity;
+import com.ning.billing.util.entity.EntityCollection;
+
 public abstract class EntityCollectionBase<T extends Entity> implements EntityCollection<T> {
     protected Map<String, T> entities = new HashMap<String, T>();
     protected final UUID objectId;
     protected final ObjectType objectType;
 
-    public EntityCollectionBase(UUID objectId, ObjectType objectType) {
+    public EntityCollectionBase(final UUID objectId, final ObjectType objectType) {
         this.objectId = objectId;
         this.objectType = objectType;
     }
@@ -45,19 +45,19 @@ public abstract class EntityCollectionBase<T extends Entity> implements EntityCo
     public abstract String getEntityKey(T entity);
 
     @Override
-    public void add(T entity) {
+    public void add(final T entity) {
         entities.put(getEntityKey(entity), entity);
     }
 
     @Override
-    public void add(List<T> entities) {
-        for (T entity : entities) {
+    public void add(final List<T> entities) {
+        for (final T entity : entities) {
             add(entity);
         }
     }
 
     @Override
-    public void remove(T entity) {
+    public void remove(final T entity) {
         entities.remove(getEntityKey(entity));
     }
 
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
index 780a34f..a6a5f92 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDao.java
@@ -16,16 +16,17 @@
 
 package com.ning.billing.util.entity.dao;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallContextBinder;
-import com.ning.billing.util.entity.Entity;
-import com.ning.billing.util.entity.EntityPersistenceException;
+import java.util.List;
+
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.BindBean;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
-import java.util.List;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextBinder;
+import com.ning.billing.util.entity.Entity;
+import com.ning.billing.util.entity.EntityPersistenceException;
 
 public interface EntitySqlDao<T extends Entity> {
     @SqlUpdate
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntitySqlDao.java b/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntitySqlDao.java
index 59bc69e..e8a2f2e 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntitySqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntitySqlDao.java
@@ -16,11 +16,12 @@
 
 package com.ning.billing.util.entity.dao;
 
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.dao.AuditSqlDao;
 import com.ning.billing.util.dao.EntityHistory;
 import com.ning.billing.util.entity.Entity;
-import org.skife.jdbi.v2.sqlobject.SqlUpdate;
 
 // this interface needs to be extended by an interface that provides (externalized) sql and object binders and mappers
 public interface UpdatableEntitySqlDao<T extends Entity> extends EntitySqlDao<T>, AuditSqlDao {
@@ -29,5 +30,5 @@ public interface UpdatableEntitySqlDao<T extends Entity> extends EntitySqlDao<T>
 
     @SqlUpdate
     public void insertHistoryFromTransaction(final EntityHistory<T> account,
-                                            final CallContext context);
+                                             final CallContext context);
 }
diff --git a/util/src/main/java/com/ning/billing/util/entity/EntityBase.java b/util/src/main/java/com/ning/billing/util/entity/EntityBase.java
index 6a03828..3cf0be4 100644
--- a/util/src/main/java/com/ning/billing/util/entity/EntityBase.java
+++ b/util/src/main/java/com/ning/billing/util/entity/EntityBase.java
@@ -16,15 +16,13 @@
 
 package com.ning.billing.util.entity;
 
-import org.joda.time.DateTime;
-
 import java.util.UUID;
 
 public abstract class EntityBase implements Entity {
     protected final UUID id;
 
     // used to hydrate objects
-    public EntityBase(UUID id) {
+    public EntityBase(final UUID id) {
         this.id = id;
     }
 
@@ -37,4 +35,4 @@ public abstract class EntityBase implements Entity {
     public UUID getId() {
         return id;
     }
-}
\ No newline at end of file
+}
diff --git a/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityBase.java b/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityBase.java
index 625aaec..963a0d3 100644
--- a/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityBase.java
+++ b/util/src/main/java/com/ning/billing/util/entity/UpdatableEntityBase.java
@@ -23,7 +23,7 @@ public abstract class UpdatableEntityBase extends EntityBase implements Updatabl
         super();
     }
 
-    public UpdatableEntityBase(UUID id) {
+    public UpdatableEntityBase(final UUID id) {
         super(id);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/globallocker/GlobalLock.java b/util/src/main/java/com/ning/billing/util/globallocker/GlobalLock.java
index 12ebc0d..8b0e461 100644
--- a/util/src/main/java/com/ning/billing/util/globallocker/GlobalLock.java
+++ b/util/src/main/java/com/ning/billing/util/globallocker/GlobalLock.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.util.globallocker;
 
-public interface GlobalLock
-{
+public interface GlobalLock {
     public void release();
-}
\ No newline at end of file
+}
diff --git a/util/src/main/java/com/ning/billing/util/globallocker/GlobalLocker.java b/util/src/main/java/com/ning/billing/util/globallocker/GlobalLocker.java
index 8e30d52..daddf1a 100644
--- a/util/src/main/java/com/ning/billing/util/globallocker/GlobalLocker.java
+++ b/util/src/main/java/com/ning/billing/util/globallocker/GlobalLocker.java
@@ -19,16 +19,17 @@ package com.ning.billing.util.globallocker;
 public interface GlobalLocker {
 
     GlobalLock lockWithNumberOfTries(final LockerService service, final String lockKey, final int retry);
+
     Boolean isFree(final LockerService service, final String lockKey);
 
     public enum LockerService {
 
         INVOICE("invoice"),
-        PAYMENT("payment");        
+        PAYMENT("payment");
 
         private final String svcName;
 
-        LockerService(String svcName) {
+        LockerService(final String svcName) {
             this.svcName = svcName;
         }
 
@@ -37,4 +38,4 @@ public interface GlobalLocker {
             return svcName;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/util/src/main/java/com/ning/billing/util/globallocker/LockFailedException.java b/util/src/main/java/com/ning/billing/util/globallocker/LockFailedException.java
index 67f83a4..3d37fa7 100644
--- a/util/src/main/java/com/ning/billing/util/globallocker/LockFailedException.java
+++ b/util/src/main/java/com/ning/billing/util/globallocker/LockFailedException.java
@@ -16,6 +16,5 @@
 
 package com.ning.billing.util.globallocker;
 
-public class LockFailedException extends RuntimeException
-{
+public class LockFailedException extends RuntimeException {
 }
diff --git a/util/src/main/java/com/ning/billing/util/globallocker/MySqlGlobalLocker.java b/util/src/main/java/com/ning/billing/util/globallocker/MySqlGlobalLocker.java
index f9de358..95e61bc 100644
--- a/util/src/main/java/com/ning/billing/util/globallocker/MySqlGlobalLocker.java
+++ b/util/src/main/java/com/ning/billing/util/globallocker/MySqlGlobalLocker.java
@@ -16,23 +16,24 @@
 
 package com.ning.billing.util.globallocker;
 
-import com.google.inject.Inject;
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.inject.Inject;
+
 public class MySqlGlobalLocker implements GlobalLocker {
 
-    private final static Logger logger = LoggerFactory.getLogger(MySqlGlobalLocker.class);
+    private static final Logger logger = LoggerFactory.getLogger(MySqlGlobalLocker.class);
 
-    private final static long DEFAULT_TIMEOUT = 3L; // 3 seconds
+    private static final long DEFAULT_TIMEOUT = 3L; // 3 seconds
 
     private final IDBI dbi;
     private long timeout;
 
     @Inject
-    public MySqlGlobalLocker(IDBI dbi) {
+    public MySqlGlobalLocker(final IDBI dbi) {
         this.dbi = dbi;
         this.timeout = DEFAULT_TIMEOUT;
     }
@@ -47,7 +48,7 @@ public class MySqlGlobalLocker implements GlobalLocker {
         final String lockName = getLockName(service, lockKey);
         int tries_left = retry;
         while (tries_left-- > 0) {
-            GlobalLock lock = lock(lockName);
+            final GlobalLock lock = lock(lockName);
             if (lock != null) {
                 return lock;
             }
@@ -68,8 +69,7 @@ public class MySqlGlobalLocker implements GlobalLocker {
                 public void release() {
                     try {
                         dao.releaseLock(lockName);
-                    }
-                    finally {
+                    } finally {
                         if (h != null) {
                             h.close();
                         }
@@ -97,10 +97,10 @@ public class MySqlGlobalLocker implements GlobalLocker {
     }
 
     private String getLockName(final LockerService service, final String lockKey) {
-        StringBuilder tmp = new StringBuilder()
-            .append(service.toString())
-            .append("-")
-            .append(lockKey);
+        final StringBuilder tmp = new StringBuilder()
+                .append(service.toString())
+                .append("-")
+                .append(lockKey);
         return tmp.toString();
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/globallocker/MySqlGlobalLockerDao.java b/util/src/main/java/com/ning/billing/util/globallocker/MySqlGlobalLockerDao.java
index 876f6e1..7a3eac3 100644
--- a/util/src/main/java/com/ning/billing/util/globallocker/MySqlGlobalLockerDao.java
+++ b/util/src/main/java/com/ning/billing/util/globallocker/MySqlGlobalLockerDao.java
@@ -16,15 +16,15 @@
 
 package com.ning.billing.util.globallocker;
 
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
 import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
 @RegisterMapper(MySqlGlobalLockerDao.LockMapper.class)
 public interface MySqlGlobalLockerDao {
 
@@ -38,9 +38,9 @@ public interface MySqlGlobalLockerDao {
     public Boolean isFree(@Bind("lockName") final String lockName);
 
     class LockMapper implements ResultSetMapper<Boolean> {
-         @Override
-         public Boolean map(int index, ResultSet r, StatementContext ctx) throws SQLException {
+        @Override
+        public Boolean map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
             return (r.getByte(1) == 1);
-         }
+        }
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/glue/BusModule.java b/util/src/main/java/com/ning/billing/util/glue/BusModule.java
index 2793208..f27e1c0 100644
--- a/util/src/main/java/com/ning/billing/util/glue/BusModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/BusModule.java
@@ -19,26 +19,23 @@ package com.ning.billing.util.glue;
 import org.skife.config.ConfigurationObjectFactory;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.name.Names;
-import com.ning.billing.config.EntitlementConfig;
-import com.ning.billing.config.PersistentQueueConfig;
-import com.ning.billing.util.bus.DefaultBusService;
 import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.bus.BusService;
-import com.ning.billing.util.bus.PersistentBusConfig;
+import com.ning.billing.util.bus.DefaultBusService;
 import com.ning.billing.util.bus.InMemoryBus;
 import com.ning.billing.util.bus.PersistentBus;
+import com.ning.billing.util.bus.PersistentBusConfig;
 
 public class BusModule extends AbstractModule {
 
     private final BusType type;
-    
+
     public BusModule() {
         super();
-        type = BusType.PERSISTENT;        
+        type = BusType.PERSISTENT;
     }
 
-    public BusModule(BusType type) {
+    public BusModule(final BusType type) {
         super();
         this.type = type;
     }
@@ -47,33 +44,33 @@ public class BusModule extends AbstractModule {
         MEMORY,
         PERSISTENT
     }
-    
+
     @Override
     protected void configure() {
         bind(BusService.class).to(DefaultBusService.class);
-        switch(type) {
-        case MEMORY:
-            configureInMemoryEventBus();
-            break;
-        case PERSISTENT:
-            configurePersistentEventBus();
-            break;
-        default:
-            new RuntimeException("Unrecognized EventBus type " + type);
+        switch (type) {
+            case MEMORY:
+                configureInMemoryEventBus();
+                break;
+            case PERSISTENT:
+                configurePersistentEventBus();
+                break;
+            default:
+                new RuntimeException("Unrecognized EventBus type " + type);
         }
-        
+
     }
 
     protected void configurePersistentBusConfig() {
         final PersistentBusConfig config = new ConfigurationObjectFactory(System.getProperties()).build(PersistentBusConfig.class);
         bind(PersistentBusConfig.class).toInstance(config);
     }
-    
+
     private void configurePersistentEventBus() {
-        configurePersistentBusConfig();        
+        configurePersistentBusConfig();
         bind(Bus.class).to(PersistentBus.class).asEagerSingleton();
     }
-    
+
     private void configureInMemoryEventBus() {
         bind(Bus.class).to(InMemoryBus.class).asEagerSingleton();
     }
diff --git a/util/src/main/java/com/ning/billing/util/glue/ClockModule.java b/util/src/main/java/com/ning/billing/util/glue/ClockModule.java
index e7c7c3f..187a500 100644
--- a/util/src/main/java/com/ning/billing/util/glue/ClockModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/ClockModule.java
@@ -22,8 +22,8 @@ import com.ning.billing.util.clock.DefaultClock;
 
 public class ClockModule extends AbstractModule {
 
-	@Override
-	protected void configure() {
-		bind(Clock.class).to(DefaultClock.class).asEagerSingleton();
-	}
+    @Override
+    protected void configure() {
+        bind(Clock.class).to(DefaultClock.class).asEagerSingleton();
+    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/glue/RealImplementation.java b/util/src/main/java/com/ning/billing/util/glue/RealImplementation.java
index d72a698..387114c 100644
--- a/util/src/main/java/com/ning/billing/util/glue/RealImplementation.java
+++ b/util/src/main/java/com/ning/billing/util/glue/RealImplementation.java
@@ -18,22 +18,24 @@ package com.ning.billing.util.glue;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
 
 import com.google.inject.BindingAnnotation;
 
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
 /**
  * This annotation is used to bing classes that are being intercepted in junction.
- * 
+ * <p/>
  * The real implementation of the class is bound in Guice with this parameter, the Blocking implementation
  * is left unannotated.
- *
  */
-@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD,LOCAL_VARIABLE }) @Retention(RUNTIME)
+@BindingAnnotation
+@Target({FIELD, PARAMETER, METHOD, LOCAL_VARIABLE})
+@Retention(RUNTIME)
 public @interface RealImplementation {
 
 }
diff --git a/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java b/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
index ce99a19..d1c763a 100644
--- a/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/TagStoreModule.java
@@ -24,16 +24,14 @@ import com.ning.billing.util.tag.dao.DefaultTagDefinitionDao;
 import com.ning.billing.util.tag.dao.TagDao;
 import com.ning.billing.util.tag.dao.TagDefinitionDao;
 
-public class TagStoreModule extends AbstractModule
-{
+public class TagStoreModule extends AbstractModule {
     protected void installDaos() {
         bind(TagDefinitionDao.class).to(DefaultTagDefinitionDao.class).asEagerSingleton();
         bind(TagDao.class).to(AuditedTagDao.class).asEagerSingleton();
     }
 
     @Override
-    protected void configure()
-    {
+    protected void configure() {
         installDaos();
         bind(TagUserApi.class).to(DefaultTagUserApi.class).asEagerSingleton();
     }
diff --git a/util/src/main/java/com/ning/billing/util/Hostname.java b/util/src/main/java/com/ning/billing/util/Hostname.java
index 4f3dd83..ac2eb6f 100644
--- a/util/src/main/java/com/ning/billing/util/Hostname.java
+++ b/util/src/main/java/com/ning/billing/util/Hostname.java
@@ -23,7 +23,7 @@ public class Hostname {
 
     public static String get() {
         try {
-            InetAddress addr = InetAddress.getLocalHost();
+            final InetAddress addr = InetAddress.getLocalHost();
             return addr.getHostName();
         } catch (UnknownHostException e) {
             e.printStackTrace();
diff --git a/util/src/main/java/com/ning/billing/util/io/IOUtils.java b/util/src/main/java/com/ning/billing/util/io/IOUtils.java
new file mode 100644
index 0000000..d8f0e31
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/io/IOUtils.java
@@ -0,0 +1,37 @@
+/*
+ * 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.util.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.CharStreams;
+import com.google.common.io.InputSupplier;
+
+public class IOUtils {
+    public static String toString(final InputStream stream) throws IOException {
+        final InputSupplier<InputStream> inputSupplier = new InputSupplier<InputStream>() {
+            @Override
+            public InputStream getInput() throws IOException {
+                return stream;
+            }
+        };
+
+        return CharStreams.toString(CharStreams.newReaderSupplier(inputSupplier, Charsets.UTF_8));
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java b/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
index cbfc564..dc3ee4d 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/dao/NotificationSqlDao.java
@@ -22,8 +22,6 @@ import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
-import com.ning.billing.util.dao.BinderBase;
-import com.ning.billing.util.dao.MapperBase;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
@@ -37,6 +35,8 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
+import com.ning.billing.util.dao.BinderBase;
+import com.ning.billing.util.dao.MapperBase;
 import com.ning.billing.util.notificationq.DefaultNotification;
 import com.ning.billing.util.notificationq.Notification;
 import com.ning.billing.util.queue.PersistentQueueEntryLifecycle.PersistentQueueEntryLifecycleState;
@@ -60,7 +60,7 @@ public interface NotificationSqlDao extends Transactional<NotificationSqlDao>, C
 
     @SqlUpdate
     public void removeNotificationsByKey(@Bind("notificationKey") String key);
-    
+
     @SqlUpdate
     public void insertNotification(@Bind(binder = NotificationSqlDaoBinder.class) Notification evt);
 
@@ -69,10 +69,11 @@ public interface NotificationSqlDao extends Transactional<NotificationSqlDao>, C
 
     public static class NotificationSqlDaoBinder extends BinderBase implements Binder<Bind, Notification> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, Notification evt) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final Notification evt) {
             stmt.bind("id", evt.getId().toString());
             stmt.bind("createdDate", getDate(new DateTime()));
-            stmt.bind("creatingOwner", evt.getCreatedOwner());            
+            stmt.bind("creatingOwner", evt.getCreatedOwner());
+            stmt.bind("className", evt.getNotificationKeyClass());            
             stmt.bind("notificationKey", evt.getNotificationKey());
             stmt.bind("effectiveDate", getDate(evt.getEffectiveDate()));
             stmt.bind("queueName", evt.getQueueName());
@@ -85,12 +86,13 @@ public interface NotificationSqlDao extends Transactional<NotificationSqlDao>, C
 
     public static class NotificationSqlMapper extends MapperBase implements ResultSetMapper<Notification> {
         @Override
-        public Notification map(int index, ResultSet r, StatementContext ctx)
-        throws SQLException {
+        public Notification map(final int index, final ResultSet r, final StatementContext ctx)
+                throws SQLException {
 
             final Long ordering = r.getLong("record_id");
             final UUID id = getUUID(r, "id");
-            final String createdOwner = r.getString("creating_owner");            
+            final String createdOwner = r.getString("creating_owner");
+            final String className = r.getString("class_name");            
             final String notificationKey = r.getString("notification_key");
             final String queueName = r.getString("queue_name");
             final DateTime effectiveDate = getDate(r, "effective_date");
@@ -99,7 +101,7 @@ public interface NotificationSqlDao extends Transactional<NotificationSqlDao>, C
             final PersistentQueueEntryLifecycleState processingState = PersistentQueueEntryLifecycleState.valueOf(r.getString("processing_state"));
 
             return new DefaultNotification(ordering, id, createdOwner, processingOwner, queueName, nextAvailableDate,
-                    processingState, notificationKey, effectiveDate);
+                                           processingState, className, notificationKey, effectiveDate);
 
         }
     }
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotification.java b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotification.java
index c71343d..1d74210 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotification.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotification.java
@@ -18,9 +18,10 @@ package com.ning.billing.util.notificationq;
 
 import java.util.UUID;
 
-import com.ning.billing.util.entity.EntityBase;
 import org.joda.time.DateTime;
 
+import com.ning.billing.util.entity.EntityBase;
+
 public class DefaultNotification extends EntityBase implements Notification {
     private final long ordering;
     private final String owner;
@@ -28,13 +29,14 @@ public class DefaultNotification extends EntityBase implements Notification {
     private final String queueName;
     private final DateTime nextAvailableDate;
     private final PersistentQueueEntryLifecycleState lifecycleState;
+    private final String notificationKeyClass;
     private final String notificationKey;
     private final DateTime effectiveDate;
 
 
-    public DefaultNotification(long ordering, UUID id, String createdOwner, String owner, String queueName, DateTime nextAvailableDate,
-            PersistentQueueEntryLifecycleState lifecycleState,
-            String notificationKey, DateTime effectiveDate) {
+    public DefaultNotification(final long ordering, final UUID id, final String createdOwner, final String owner, final String queueName, final DateTime nextAvailableDate,
+                               final PersistentQueueEntryLifecycleState lifecycleState,
+                               final String notificationKeyClass, final String notificationKey, final DateTime effectiveDate) {
         super(id);
         this.ordering = ordering;
         this.owner = owner;
@@ -42,13 +44,15 @@ public class DefaultNotification extends EntityBase implements Notification {
         this.queueName = queueName;
         this.nextAvailableDate = nextAvailableDate;
         this.lifecycleState = lifecycleState;
+        this.notificationKeyClass = notificationKeyClass;
         this.notificationKey = notificationKey;
         this.effectiveDate = effectiveDate;
     }
 
-    public DefaultNotification(String queueName, String createdOwner, String notificationKey, DateTime effectiveDate) {
-        this(-1L, UUID.randomUUID(), createdOwner, null, queueName, null, PersistentQueueEntryLifecycleState.AVAILABLE, notificationKey, effectiveDate);
+    public DefaultNotification(final String queueName, final String createdOwner, final String notificationKeyClass, final String notificationKey, final DateTime effectiveDate) {
+        this(-1L, UUID.randomUUID(), createdOwner, null, queueName, null, PersistentQueueEntryLifecycleState.AVAILABLE, notificationKeyClass, notificationKey, effectiveDate);
     }
+
     @Override
     public Long getOrdering() {
         return ordering;
@@ -70,25 +74,31 @@ public class DefaultNotification extends EntityBase implements Notification {
     }
 
     @Override
-    public boolean isAvailableForProcessing(DateTime now) {
-        switch(lifecycleState) {
-        case AVAILABLE:
-            break;
-        case IN_PROCESSING:
-            // Somebody already got the event, not available yet
-            if (nextAvailableDate.isAfter(now)) {
+    public boolean isAvailableForProcessing(final DateTime now) {
+        switch (lifecycleState) {
+            case AVAILABLE:
+                break;
+            case IN_PROCESSING:
+                // Somebody already got the event, not available yet
+                if (nextAvailableDate.isAfter(now)) {
+                    return false;
+                }
+                break;
+            case PROCESSED:
                 return false;
-            }
-            break;
-        case PROCESSED:
-            return false;
-        default:
-            throw new RuntimeException(String.format("Unkwnon IEvent processing state %s", lifecycleState));
+            default:
+                throw new RuntimeException(String.format("Unkwnon IEvent processing state %s", lifecycleState));
         }
         return effectiveDate.isBefore(now);
     }
 
     @Override
+    public String getNotificationKeyClass() {
+        return notificationKeyClass;
+    }
+
+    
+    @Override
     public String getNotificationKey() {
         return notificationKey;
     }
@@ -98,10 +108,10 @@ public class DefaultNotification extends EntityBase implements Notification {
         return effectiveDate;
     }
 
-	@Override
-	public String getQueueName() {
-		return queueName;
-	}
+    @Override
+    public String getQueueName() {
+        return queueName;
+    }
 
     @Override
     public String getCreatedOwner() {
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
index 2c6bb62..19923b3 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueue.java
@@ -16,16 +16,17 @@
 
 package com.ning.billing.util.notificationq;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
 import com.ning.billing.config.NotificationConfig;
+import com.ning.billing.util.bus.dao.BusEventEntry;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
@@ -34,7 +35,7 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
 
     protected final NotificationSqlDao dao;
 
-    public DefaultNotificationQueue(final IDBI dbi, final Clock clock,  final String svcName, final String queueName, final NotificationQueueHandler handler, final NotificationConfig config) {
+    public DefaultNotificationQueue(final IDBI dbi, final Clock clock, final String svcName, final String queueName, final NotificationQueueHandler handler, final NotificationConfig config) {
 
         super(clock, svcName, queueName, handler, config);
         this.dao = dbi.onDemand(NotificationSqlDao.class);
@@ -44,7 +45,7 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
     public int doProcessEvents() {
 
         logDebug("ENTER doProcessEvents");
-        List<Notification> notifications = getReadyNotifications();
+        final List<Notification> notifications = getReadyNotifications();
         if (notifications.size() == 0) {
             logDebug("EXIT doProcessEvents");
             return 0;
@@ -56,30 +57,35 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
         for (final Notification cur : notifications) {
             nbProcessedEvents.incrementAndGet();
             logDebug("handling notification %s, key = %s for time %s",
-                    cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate());
-            handler.handleReadyNotification(cur.getNotificationKey(), cur.getEffectiveDate());
+                     cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate());
+            NotificationKey key = deserializeEvent(cur.getNotificationKeyClass(), cur.getNotificationKey()); 
+            handler.handleReadyNotification(key, cur.getEffectiveDate());
             result++;
             clearNotification(cur);
             logDebug("done handling notification %s, key = %s for time %s",
-                    cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate());
+                     cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate());
         }
         return result;
     }
 
+
     @Override
-    public void recordFutureNotification(DateTime futureNotificationTime, NotificationKey notificationKey) {
-        Notification notification = new DefaultNotification(getFullQName(), hostname,  notificationKey.toString(), futureNotificationTime);
-        dao.insertNotification(notification);
+    public void recordFutureNotification(final DateTime futureNotificationTime, final NotificationKey notificationKey) throws IOException {
+        recordFutureNotificationInternal(futureNotificationTime, notificationKey, dao);
     }
 
     @Override
     public void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao,
-            final DateTime futureNotificationTime, final NotificationKey notificationKey) {
-        NotificationSqlDao transactionalNotificationDao =  transactionalDao.become(NotificationSqlDao.class);
-        Notification notification = new DefaultNotification(getFullQName(), hostname, notificationKey.toString(), futureNotificationTime);
-        transactionalNotificationDao.insertNotification(notification);
+                                                        final DateTime futureNotificationTime, final NotificationKey notificationKey) throws IOException {
+        final NotificationSqlDao transactionalNotificationDao = transactionalDao.become(NotificationSqlDao.class);
+        recordFutureNotificationInternal(futureNotificationTime, notificationKey, transactionalNotificationDao);
+    }
+    
+    private void recordFutureNotificationInternal(final DateTime futureNotificationTime, final NotificationKey notificationKey, final NotificationSqlDao thisDao) throws IOException {
+        final String json = objectMapper.writeValueAsString(notificationKey);
+        final Notification notification = new DefaultNotification(getFullQName(), hostname, notificationKey.getClass().getName(), json, futureNotificationTime);
+        thisDao.insertNotification(notification);
     }
-
 
     private void clearNotification(final Notification cleared) {
         dao.clearNotification(cleared.getId().toString(), hostname);
@@ -90,40 +96,40 @@ public class DefaultNotificationQueue extends NotificationQueueBase {
         final Date now = clock.getUTCNow().toDate();
         final Date nextAvailable = clock.getUTCNow().plus(CLAIM_TIME_MS).toDate();
 
-        List<Notification> input = dao.getReadyNotifications(now, hostname, CLAIM_TIME_MS, getFullQName());
+        final List<Notification> input = dao.getReadyNotifications(now, hostname, CLAIM_TIME_MS, getFullQName());
 
-        List<Notification> claimedNotifications = new ArrayList<Notification>();
-        for (Notification cur : input) {
+        final List<Notification> claimedNotifications = new ArrayList<Notification>();
+        for (final Notification cur : input) {
             logDebug("about to claim notification %s,  key = %s for time %s",
-                    cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate());
+                     cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate());
             final boolean claimed = (dao.claimNotification(hostname, nextAvailable, cur.getId().toString(), now) == 1);
             logDebug("claimed notification %s, key = %s for time %s result = %s",
-                    cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate(), Boolean.valueOf(claimed));
+                     cur.getId(), cur.getNotificationKey(), cur.getEffectiveDate(), Boolean.valueOf(claimed));
             if (claimed) {
                 claimedNotifications.add(cur);
                 dao.insertClaimedHistory(hostname, now, cur.getId().toString());
             }
         }
 
-        for (Notification cur : claimedNotifications) {
+        for (final Notification cur : claimedNotifications) {
             if (cur.getOwner() != null && !cur.getOwner().equals(hostname)) {
                 log.warn(String.format("NotificationQueue %s stealing notification %s from %s",
-                        getFullQName(), cur, cur.getOwner()));
+                                       getFullQName(), cur, cur.getOwner()));
             }
         }
         return claimedNotifications;
     }
 
-    private void logDebug(String format, Object...args) {
+    private void logDebug(final String format, final Object... args) {
         if (log.isDebugEnabled()) {
-            String realDebug = String.format(format, args);
+            final String realDebug = String.format(format, args);
             log.debug(String.format("Thread %d [queue = %s] %s", Thread.currentThread().getId(), getFullQName(), realDebug));
         }
     }
 
     @Override
-    public void removeNotificationsByKey(NotificationKey notificationKey) {
+    public void removeNotificationsByKey(final NotificationKey notificationKey) {
         dao.removeNotificationsByKey(notificationKey.toString());
-        
+
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java
index bf8652c..bfa2379 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/DefaultNotificationQueueService.java
@@ -17,6 +17,7 @@
 package com.ning.billing.util.notificationq;
 
 import org.skife.jdbi.v2.IDBI;
+
 import com.google.inject.Inject;
 import com.ning.billing.config.NotificationConfig;
 import com.ning.billing.util.clock.Clock;
@@ -32,9 +33,9 @@ public class DefaultNotificationQueueService extends NotificationQueueServiceBas
     }
 
     @Override
-    protected NotificationQueue createNotificationQueueInternal(String svcName,
-            String queueName, NotificationQueueHandler handler,
-            NotificationConfig config) {
+    protected NotificationQueue createNotificationQueueInternal(final String svcName,
+                                                                final String queueName, final NotificationQueueHandler handler,
+                                                                final NotificationConfig config) {
         return new DefaultNotificationQueue(dbi, clock, svcName, queueName, handler, config);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/DefaultUUIDNotificationKey.java b/util/src/main/java/com/ning/billing/util/notificationq/DefaultUUIDNotificationKey.java
new file mode 100644
index 0000000..2c1203d
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/notificationq/DefaultUUIDNotificationKey.java
@@ -0,0 +1,60 @@
+/* 
+ * Copyright 2010-2011 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.util.notificationq;
+
+import java.util.UUID;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class DefaultUUIDNotificationKey implements NotificationKey {
+
+    private final UUID uuidKey;
+    
+    @JsonCreator
+    public DefaultUUIDNotificationKey(@JsonProperty("uuidKey") final UUID uuidKey) {
+        this.uuidKey = uuidKey;
+    }
+
+    public UUID getUuidKey() {
+        return uuidKey;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((uuidKey == null) ? 0 : uuidKey.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        DefaultUUIDNotificationKey other = (DefaultUUIDNotificationKey) obj;
+        if (uuidKey == null) {
+            if (other.uuidKey != null)
+                return false;
+        } else if (!uuidKey.equals(other.uuidKey))
+            return false;
+        return true;
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/Notification.java b/util/src/main/java/com/ning/billing/util/notificationq/Notification.java
index 37caa4e..2ecea54 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/Notification.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/Notification.java
@@ -16,14 +16,16 @@
 
 package com.ning.billing.util.notificationq;
 
+import org.joda.time.DateTime;
+
 import com.ning.billing.util.entity.Entity;
 import com.ning.billing.util.queue.PersistentQueueEntryLifecycle;
 
-import org.joda.time.DateTime;
-
 public interface Notification extends PersistentQueueEntryLifecycle, Entity {
     public Long getOrdering();
 
+    public String getNotificationKeyClass();
+    
     public String getNotificationKey();
 
     public DateTime getEffectiveDate();
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationError.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationError.java
index 4e771ba..f3ff9fb 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationError.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationError.java
@@ -24,15 +24,15 @@ public class NotificationError extends Error {
         super();
     }
 
-    public NotificationError(String msg, Throwable arg1) {
+    public NotificationError(final String msg, final Throwable arg1) {
         super(msg, arg1);
     }
 
-    public NotificationError(String msg) {
+    public NotificationError(final String msg) {
         super(msg);
     }
 
-    public NotificationError(Throwable msg) {
+    public NotificationError(final Throwable msg) {
         super(msg);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationKey.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationKey.java
index bfe4aa9..534a99e 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationKey.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationKey.java
@@ -17,11 +17,8 @@
 package com.ning.billing.util.notificationq;
 
 /**
- *
  * The notification key associated with a given notification
  */
 public interface NotificationKey {
 
-    @Override
-    public String toString();
 }
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
index a04ff45..678da46 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueue.java
@@ -16,40 +16,39 @@
 
 package com.ning.billing.util.notificationq;
 
-import java.util.UUID;
+import java.io.IOException;
 
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
-import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 import com.ning.billing.util.queue.QueueLifecycle;
 
 public interface NotificationQueue extends QueueLifecycle {
 
     /**
-     *
      * Record the need to be called back when the notification is ready
      *
      * @param futureNotificationTime the time at which the notification is ready
-     * @param notificationKey the key for that notification
+     * @param notificationKey        the key for that notification
      */
-    public void recordFutureNotification(final DateTime futureNotificationTime, final NotificationKey notificationKey);
+    public void recordFutureNotification(final DateTime futureNotificationTime, final NotificationKey notificationKey)
+        throws IOException;
 
     /**
-     *
      * Record from within a transaction the need to be called back when the notification is ready
      *
-     * @param transactionalDao the transactionalDao
+     * @param transactionalDao       the transactionalDao
      * @param futureNotificationTime the time at which the notification is ready
-     * @param notificationKey the key for that notification
+     * @param notificationKey        the key for that notification
      */
     public void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao,
-            final DateTime futureNotificationTime, final NotificationKey notificationKey);
+                                                        final DateTime futureNotificationTime, final NotificationKey notificationKey)
+        throws IOException;
+
 
-  
     /**
-     * Remove all notifications associated with this key   
-     * 
+     * Remove all notifications associated with this key
+     *
      * @param key
      */
     public void removeNotificationsByKey(final NotificationKey notificationKey);
@@ -63,11 +62,10 @@ public interface NotificationQueue extends QueueLifecycle {
     public int processReadyNotification();
 
     /**
-     *
      * @return the name of that queue
      */
     public String getFullQName();
-    
+
     /**
      * @return the service name associated to that queue
      */
@@ -79,5 +77,4 @@ public interface NotificationQueue extends QueueLifecycle {
     public String getQueueName();
 
 
-
 }
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueBase.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueBase.java
index a335668..38b6e3c 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueBase.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueBase.java
@@ -33,17 +33,17 @@ import com.ning.billing.util.queue.PersistentQueueBase;
 
 public abstract class NotificationQueueBase extends PersistentQueueBase implements NotificationQueue {
 
-    protected final static Logger log = LoggerFactory.getLogger(NotificationQueueBase.class);
+    protected static final Logger log = LoggerFactory.getLogger(NotificationQueueBase.class);
+
+    public static final int CLAIM_TIME_MS = (5 * 60 * 1000); // 5 minutes
+
+    private static final String NOTIFICATION_THREAD_PREFIX = "Notification-";
+    private static final int NB_THREADS = 1;
 
-    public final static int CLAIM_TIME_MS = (5 * 60 * 1000); // 5 minutes
-    
-    private final static String NOTIFICATION_THREAD_PREFIX = "Notification-";
-    private final static int NB_THREADS = 1;
 
-    
     private final String svcName;
     private final String queueName;
-    
+
     protected final NotificationQueueHandler handler;
     protected final NotificationConfig config;
 
@@ -53,16 +53,16 @@ public abstract class NotificationQueueBase extends PersistentQueueBase implemen
     protected AtomicLong nbProcessedEvents;
 
     // Package visibility on purpose
-    NotificationQueueBase(final Clock clock,  final String svcName, final String queueName, final NotificationQueueHandler handler, final NotificationConfig config) {
+    NotificationQueueBase(final Clock clock, final String svcName, final String queueName, final NotificationQueueHandler handler, final NotificationConfig config) {
         super(svcName, Executors.newFixedThreadPool(1, new ThreadFactory() {
 
             @Override
-            public Thread newThread(Runnable r) {
-                Thread th = new Thread(r);
+            public Thread newThread(final Runnable r) {
+                final Thread th = new Thread(r);
                 th.setName(NOTIFICATION_THREAD_PREFIX + svcName + "-" + queueName);
                 th.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
                     @Override
-                    public void uncaughtException(Thread t, Throwable e) {
+                    public void uncaughtException(final Thread t, final Throwable e) {
                         log.error("Uncaught exception for thread " + t.getName(), e);
                     }
                 });
@@ -86,7 +86,7 @@ public abstract class NotificationQueueBase extends PersistentQueueBase implemen
         }
         super.startQueue();
     }
-    
+
     @Override
     public void stopQueue() {
         if (config.isNotificationProcessingOff()) {
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueService.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueService.java
index 6d05e3a..3b3d74d 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueService.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueService.java
@@ -29,13 +29,13 @@ public interface NotificationQueueService {
          *
          * @param notificationKey the notification key associated to that notification entry
          */
-        public void handleReadyNotification(String notificationKey, DateTime eventDateTime);
-     }
+        public void handleReadyNotification(NotificationKey notificationKey, DateTime eventDateTime);
+    }
 
     public static final class NotificationQueueAlreadyExists extends Exception {
         private static final long serialVersionUID = 1541281L;
 
-        public NotificationQueueAlreadyExists(String msg) {
+        public NotificationQueueAlreadyExists(final String msg) {
             super(msg);
         }
     }
@@ -43,7 +43,7 @@ public interface NotificationQueueService {
     public static final class NoSuchNotificationQueue extends Exception {
         private static final long serialVersionUID = 1541281L;
 
-        public NoSuchNotificationQueue(String msg) {
+        public NoSuchNotificationQueue(final String msg) {
             super(msg);
         }
     }
@@ -51,18 +51,16 @@ public interface NotificationQueueService {
     /**
      * Creates a new NotificationQueue for a given associated with the given service and queueName
      *
-     * @param svcName the name of the service using that queue
+     * @param svcName   the name of the service using that queue
      * @param queueName a name for that queue (unique per service)
-     * @param handler the handler required for notifying the caller of state change
-     * @param config the notification queue configuration
-     *
+     * @param handler   the handler required for notifying the caller of state change
+     * @param config    the notification queue configuration
      * @return a new NotificationQueue
-     *
-     * @throws com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists is the queue associated with that service and name already exits
-     *
+     * @throws com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists
+     *          is the queue associated with that service and name already exits
      */
     public NotificationQueue createNotificationQueue(final String svcName, final String queueName, final NotificationQueueHandler handler, final NotificationConfig config)
-        throws NotificationQueueAlreadyExists;
+            throws NotificationQueueAlreadyExists;
 
     /**
      * Retrieves an already created NotificationQueue by service and name if it exists
@@ -70,11 +68,10 @@ public interface NotificationQueueService {
      * @param svcName
      * @param queueName
      * @return
-     *
      * @throws NoSuchNotificationQueue if queue does not exist
      */
     public NotificationQueue getNotificationQueue(final String svcName, final String queueName)
-        throws NoSuchNotificationQueue;
+            throws NoSuchNotificationQueue;
 
     /**
      * Delete notificationQueue
@@ -82,17 +79,15 @@ public interface NotificationQueueService {
      * @param svcName
      * @param queueName
      * @return
-     *
      * @throws NoSuchNotificationQueue if queue does not exist
      */
     public void deleteNotificationQueue(final String svcName, final String queueName)
-    throws NoSuchNotificationQueue;
-            
+            throws NoSuchNotificationQueue;
+
 
     /**
-     *
      * @param services
      * @return the number of processed notifications
      */
-    public int triggerManualQueueProcessing(final String [] services, final Boolean keepRunning);
+    public int triggerManualQueueProcessing(final String[] services, final Boolean keepRunning);
 }
diff --git a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueServiceBase.java b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueServiceBase.java
index f782484..03aed2c 100644
--- a/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueServiceBase.java
+++ b/util/src/main/java/com/ning/billing/util/notificationq/NotificationQueueServiceBase.java
@@ -29,7 +29,6 @@ import com.google.common.base.Joiner;
 import com.google.inject.Inject;
 import com.ning.billing.config.NotificationConfig;
 import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.notificationq.NotificationQueueService.NoSuchNotificationQueue;
 
 public abstract class NotificationQueueServiceBase implements NotificationQueueService {
 
@@ -45,22 +44,22 @@ public abstract class NotificationQueueServiceBase implements NotificationQueueS
         this.queues = new TreeMap<String, NotificationQueue>();
     }
 
-    
+
     @Override
-    public NotificationQueue createNotificationQueue(String svcName,
-            String queueName, NotificationQueueHandler handler,
-            NotificationConfig config) throws NotificationQueueAlreadyExists {
+    public NotificationQueue createNotificationQueue(final String svcName,
+                                                     final String queueName, final NotificationQueueHandler handler,
+                                                     final NotificationConfig config) throws NotificationQueueAlreadyExists {
         if (svcName == null || queueName == null || handler == null || config == null) {
             throw new RuntimeException("Need to specify all parameters");
         }
 
-        String compositeName = getCompositeName(svcName, queueName);
+        final String compositeName = getCompositeName(svcName, queueName);
         NotificationQueue result = null;
-        synchronized(queues) {
+        synchronized (queues) {
             result = queues.get(compositeName);
             if (result != null) {
                 throw new NotificationQueueAlreadyExists(String.format("Queue for svc %s and name %s already exist",
-                        svcName, queueName));
+                                                                       svcName, queueName));
             }
             result = createNotificationQueueInternal(svcName, queueName, handler, config);
             queues.put(compositeName, result);
@@ -69,30 +68,30 @@ public abstract class NotificationQueueServiceBase implements NotificationQueueS
     }
 
     @Override
-    public NotificationQueue getNotificationQueue(String svcName,
-            String queueName) throws NoSuchNotificationQueue {
+    public NotificationQueue getNotificationQueue(final String svcName,
+                                                  final String queueName) throws NoSuchNotificationQueue {
 
         NotificationQueue result = null;
-        String compositeName = getCompositeName(svcName, queueName);
-        synchronized(queues) {
+        final String compositeName = getCompositeName(svcName, queueName);
+        synchronized (queues) {
             result = queues.get(compositeName);
             if (result == null) {
                 throw new NoSuchNotificationQueue(String.format("Queue for svc %s and name %s does not exist",
-                        svcName, queueName));
+                                                                svcName, queueName));
             }
         }
         return result;
     }
 
-    
+
     public void deleteNotificationQueue(final String svcName, final String queueName)
-        throws NoSuchNotificationQueue {
-        String compositeName = getCompositeName(svcName, queueName);
-        synchronized(queues) {
-            NotificationQueue result = queues.get(compositeName);
+            throws NoSuchNotificationQueue {
+        final String compositeName = getCompositeName(svcName, queueName);
+        synchronized (queues) {
+            final NotificationQueue result = queues.get(compositeName);
             if (result == null) {
                 throw new NoSuchNotificationQueue(String.format("Queue for svc %s and name %s does not exist",
-                        svcName, queueName));
+                                                                svcName, queueName));
             }
             queues.remove(compositeName);
         }
@@ -103,7 +102,7 @@ public abstract class NotificationQueueServiceBase implements NotificationQueueS
     // Test ONLY
     //
     @Override
-    public int triggerManualQueueProcessing(final String [] services, final Boolean keepRunning) {
+    public int triggerManualQueueProcessing(final String[] services, final Boolean keepRunning) {
 
         int result = 0;
 
@@ -111,30 +110,30 @@ public abstract class NotificationQueueServiceBase implements NotificationQueueS
         if (services == null) {
             manualQueues = new ArrayList<NotificationQueue>(queues.values());
         } else {
-            Joiner join = Joiner.on(",");
+            final Joiner join = Joiner.on(",");
             join.join(services);
 
             log.info("Trigger manual processing for services {} ", join.toString());
             manualQueues = new LinkedList<NotificationQueue>();
             synchronized (queues) {
-                for (String svc : services) {
+                for (final String svc : services) {
                     addQueuesForService(manualQueues, svc);
                 }
             }
         }
-        for (NotificationQueue cur : manualQueues) {
+        for (final NotificationQueue cur : manualQueues) {
             int processedNotifications = 0;
             do {
                 processedNotifications = cur.processReadyNotification();
                 log.info("Got {} results from queue {}", processedNotifications, cur.getFullQName());
                 result += processedNotifications;
-            } while(keepRunning && processedNotifications > 0);
+            } while (keepRunning && processedNotifications > 0);
         }
         return result;
     }
 
-    private final void addQueuesForService(final List<NotificationQueue> result, final String svcName) {
-        for (String cur : queues.keySet()) {
+    private void addQueuesForService(final List<NotificationQueue> result, final String svcName) {
+        for (final String cur : queues.keySet()) {
             if (cur.startsWith(svcName)) {
                 result.add(queues.get(cur));
             }
@@ -142,11 +141,11 @@ public abstract class NotificationQueueServiceBase implements NotificationQueueS
     }
 
     protected abstract NotificationQueue createNotificationQueueInternal(String svcName,
-            String queueName, NotificationQueueHandler handler,
-            NotificationConfig config);
+                                                                         String queueName, NotificationQueueHandler handler,
+                                                                         NotificationConfig config);
 
 
-    public static String getCompositeName(String svcName, String queueName) {
+    public static String getCompositeName(final String svcName, final String queueName) {
         return svcName + ":" + queueName;
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java b/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java
index 2a9e149..09bb1b5 100644
--- a/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java
+++ b/util/src/main/java/com/ning/billing/util/queue/PersistentQueueBase.java
@@ -22,64 +22,68 @@ import java.util.concurrent.TimeUnit;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 import com.ning.billing.config.PersistentQueueConfig;
+import com.ning.billing.util.jackson.ObjectMapper;
 
 
 public abstract class PersistentQueueBase implements QueueLifecycle {
 
     private static final Logger log = LoggerFactory.getLogger(PersistentQueueBase.class);
-    
+
     private static final long waitTimeoutMs = 15L * 1000L; // 15 seconds
-    
+
     private final int nbThreads;
     private final Executor executor;
     private final String svcName;
     private final long sleepTimeMs;
-
     private boolean isProcessingEvents;
     private int curActiveThreads;
+
+    protected final ObjectMapper objectMapper;
     
     public PersistentQueueBase(final String svcName, final Executor executor, final int nbThreads, final PersistentQueueConfig config) {
         this.executor = executor;
         this.nbThreads = nbThreads;
         this.svcName = svcName;
         this.sleepTimeMs = config.getSleepTimeMs();
+        this.objectMapper = new ObjectMapper();        
         this.isProcessingEvents = false;
         this.curActiveThreads = 0;
     }
-    
+
     @Override
     public void startQueue() {
-        
+
         isProcessingEvents = true;
         curActiveThreads = 0;
-        
+
         final PersistentQueueBase thePersistentQ = this;
         final CountDownLatch doneInitialization = new CountDownLatch(nbThreads);
 
         log.info(String.format("%s: Starting with %d threads",
-                svcName, nbThreads));
-        
+                               svcName, nbThreads));
+
         for (int i = 0; i < nbThreads; i++) {
             executor.execute(new Runnable() {
                 @Override
                 public void run() {
 
                     log.info(String.format("%s: Thread %s [%d] starting",
-                            svcName,
-                            Thread.currentThread().getName(),
-                            Thread.currentThread().getId()));
-                    
-                    synchronized(thePersistentQ) {
+                                           svcName,
+                                           Thread.currentThread().getName(),
+                                           Thread.currentThread().getId()));
+
+                    synchronized (thePersistentQ) {
                         curActiveThreads++;
                     }
 
                     doneInitialization.countDown();
-                    
+
                     try {
                         while (true) {
-                            
-                            synchronized(thePersistentQ) {
+
+                            synchronized (thePersistentQ) {
                                 if (!isProcessingEvents) {
                                     thePersistentQ.notify();
                                     break;
@@ -90,51 +94,51 @@ public abstract class PersistentQueueBase implements QueueLifecycle {
                                 doProcessEvents();
                             } catch (Exception e) {
                                 log.warn(String.format("%s: Thread  %s  [%d] got an exception, catching and moving on...",
-                                        svcName,
-                                        Thread.currentThread().getName(),
-                                        Thread.currentThread().getId()), e);
+                                                       svcName,
+                                                       Thread.currentThread().getName(),
+                                                       Thread.currentThread().getId()), e);
                             }
                             sleepALittle();
                         }
                     } catch (InterruptedException e) {
                         log.info(String.format("%s: Thread %s got interrupted, exting... ", svcName, Thread.currentThread().getName()));
                     } catch (Throwable e) {
-                        log.error(String.format("%s: Thread %s got an exception, exting... ", svcName, Thread.currentThread().getName()), e);                        
+                        log.error(String.format("%s: Thread %s got an exception, exting... ", svcName, Thread.currentThread().getName()), e);
                     } finally {
 
-                        log.info(String.format("%s: Thread %s has exited", svcName, Thread.currentThread().getName()));                                                
-                        synchronized(thePersistentQ) {
+                        log.info(String.format("%s: Thread %s has exited", svcName, Thread.currentThread().getName()));
+                        synchronized (thePersistentQ) {
                             curActiveThreads--;
                         }
                     }
                 }
-                
+
                 private void sleepALittle() throws InterruptedException {
                     Thread.sleep(sleepTimeMs);
                 }
             });
         }
         try {
-            boolean success = doneInitialization.await(waitTimeoutMs, TimeUnit.MILLISECONDS);
+            final boolean success = doneInitialization.await(waitTimeoutMs, TimeUnit.MILLISECONDS);
             if (!success) {
-                
+
                 log.warn(String.format("%s: Failed to wait for all threads to be started, got %d/%d", svcName, (nbThreads - doneInitialization.getCount()), nbThreads));
             } else {
-                log.info(String.format("%s: Done waiting for all threads to be started, got %d/%d", svcName, (nbThreads - doneInitialization.getCount()), nbThreads));                
+                log.info(String.format("%s: Done waiting for all threads to be started, got %d/%d", svcName, (nbThreads - doneInitialization.getCount()), nbThreads));
             }
         } catch (InterruptedException e) {
             log.warn(String.format("%s: Start sequence, got interrupted", svcName));
         }
     }
-    
-    
+
+
     @Override
     public void stopQueue() {
         int remaining = 0;
         try {
-            synchronized(this) {
+            synchronized (this) {
                 isProcessingEvents = false;
-                long ini = System.currentTimeMillis();
+                final long ini = System.currentTimeMillis();
                 long remainingWaitTimeMs = waitTimeoutMs;
                 while (curActiveThreads > 0 && remainingWaitTimeMs > 0) {
                     wait(1000);
@@ -142,20 +146,32 @@ public abstract class PersistentQueueBase implements QueueLifecycle {
                 }
                 remaining = curActiveThreads;
             }
-            
+
         } catch (InterruptedException ignore) {
             log.info(String.format("%s: Stop sequence has been interrupted, remaining active threads = %d", svcName, curActiveThreads));
         } finally {
             if (remaining > 0) {
                 log.error(String.format("%s: Stop sequence completed with %d active remaing threads", svcName, curActiveThreads));
             } else {
-                log.info(String.format("%s: Stop sequence completed with %d active remaing threads", svcName, curActiveThreads));                
+                log.info(String.format("%s: Stop sequence completed with %d active remaing threads", svcName, curActiveThreads));
             }
             curActiveThreads = 0;
         }
     }
     
-    
+    protected <T> T deserializeEvent(final String className, final String json) {
+        try {
+            final Class<?> claz = Class.forName(className);
+            return (T) objectMapper.readValue(json, claz);
+        } catch (Exception e) {
+            log.error(String.format("Failed to deserialize json object %s for class %s", json, className), e);
+            return null;
+        }
+    }
+
+
+
+
     @Override
     public abstract int doProcessEvents();
 }
diff --git a/util/src/main/java/com/ning/billing/util/queue/PersistentQueueEntryLifecycle.java b/util/src/main/java/com/ning/billing/util/queue/PersistentQueueEntryLifecycle.java
index c38dcb5..6382faa 100644
--- a/util/src/main/java/com/ning/billing/util/queue/PersistentQueueEntryLifecycle.java
+++ b/util/src/main/java/com/ning/billing/util/queue/PersistentQueueEntryLifecycle.java
@@ -29,7 +29,7 @@ public interface PersistentQueueEntryLifecycle {
     }
 
     public String getOwner();
-    
+
     public String getCreatedOwner();
 
     public DateTime getNextAvailableDate();
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java
index 3ffccf2..8db294a 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagDao.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.util.tag.dao;
 
-import java.util.List;
 import java.util.UUID;
 
 import com.ning.billing.util.api.TagApiException;
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagHistoryBinder.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagHistoryBinder.java
index 05d9414..b8cdded 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagHistoryBinder.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagHistoryBinder.java
@@ -39,7 +39,7 @@ public @interface TagHistoryBinder {
         public Binder build(final Annotation annotation) {
             return new Binder<TagHistoryBinder, EntityHistory<Tag>>() {
                 @Override
-                public void bind(final SQLStatement q, final TagHistoryBinder bind, final EntityHistory<Tag> tagHistory) {
+                public void bind(final SQLStatement<?> q, final TagHistoryBinder bind, final EntityHistory<Tag> tagHistory) {
                     q.bind("recordId", tagHistory.getValue());
                     q.bind("changeType", tagHistory.getChangeType().toString());
                     q.bind("id", tagHistory.getId().toString());
diff --git a/util/src/main/java/com/ning/billing/util/template/translation/DefaultCatalogTranslator.java b/util/src/main/java/com/ning/billing/util/template/translation/DefaultCatalogTranslator.java
index 933b24f..a6027f5 100644
--- a/util/src/main/java/com/ning/billing/util/template/translation/DefaultCatalogTranslator.java
+++ b/util/src/main/java/com/ning/billing/util/template/translation/DefaultCatalogTranslator.java
@@ -20,7 +20,7 @@ import com.google.inject.Inject;
 
 public class DefaultCatalogTranslator extends DefaultTranslatorBase {
     @Inject
-    public DefaultCatalogTranslator(TranslatorConfig config) {
+    public DefaultCatalogTranslator(final TranslatorConfig config) {
         super(config);
     }
 
diff --git a/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java b/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
index 4d1a7b6..2b3f62e 100644
--- a/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
+++ b/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
@@ -16,21 +16,27 @@
 
 package com.ning.billing.util.template.translation;
 
-import com.google.inject.Inject;
-import com.ning.billing.ErrorCode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
 import java.util.Locale;
 import java.util.MissingResourceException;
+import java.util.PropertyResourceBundle;
 import java.util.ResourceBundle;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
+import com.ning.billing.util.config.UriAccessor;
+
 public abstract class DefaultTranslatorBase implements Translator {
     protected final TranslatorConfig config;
     protected final Logger log = LoggerFactory.getLogger(DefaultTranslatorBase.class);
 
     @Inject
-    public DefaultTranslatorBase(TranslatorConfig config) {
+    public DefaultTranslatorBase(final TranslatorConfig config) {
         this.config = config;
     }
 
@@ -42,20 +48,16 @@ public abstract class DefaultTranslatorBase implements Translator {
     protected abstract String getTranslationType();
 
     @Override
-    public String getTranslation(Locale locale, String originalText) {
-        ResourceBundle bundle = null;
-        try {
-            bundle = ResourceBundle.getBundle(getBundlePath(), locale);
-        } catch (MissingResourceException mrex) {
-            log.warn(String.format(ErrorCode.MISSING_TRANSLATION_RESOURCE.toString(), getTranslationType()));
-        }
+    public String getTranslation(final Locale locale, final String originalText) {
+        final String bundlePath = getBundlePath();
+        ResourceBundle bundle = getBundle(locale, bundlePath);
 
         if ((bundle != null) && (bundle.containsKey(originalText))) {
             return bundle.getString(originalText);
         } else {
+            final Locale defaultLocale = new Locale(config.getDefaultLocale());
             try {
-                Locale defaultLocale = new Locale(config.getDefaultLocale());
-                bundle = ResourceBundle.getBundle(getBundlePath(), defaultLocale);
+                bundle = getBundle(defaultLocale, bundlePath);
 
                 if ((bundle != null) && (bundle.containsKey(originalText))) {
                     return bundle.getString(originalText);
@@ -68,4 +70,44 @@ public abstract class DefaultTranslatorBase implements Translator {
             }
         }
     }
+
+    private ResourceBundle getBundle(final Locale locale, final String bundlePath) {
+        try {
+            // Try to load the bundle from the classpath first
+            return ResourceBundle.getBundle(bundlePath, locale);
+        } catch (MissingResourceException ignored) {
+        }
+
+        // Try to load it from a properties file
+        final String propertiesFileNameWithCountry = bundlePath + "_" + locale.getLanguage() + "_" + locale.getCountry() + ".properties";
+        ResourceBundle bundle = getBundleFromPropertiesFile(propertiesFileNameWithCountry);
+        if (bundle != null) {
+            return bundle;
+        } else {
+            final String propertiesFileName = bundlePath + "_" + locale.getLanguage() + ".properties";
+            bundle = getBundleFromPropertiesFile(propertiesFileName);
+        }
+
+        if (bundle == null) {
+            log.warn(String.format(ErrorCode.MISSING_TRANSLATION_RESOURCE.toString(), getTranslationType()));
+        }
+        return bundle;
+    }
+
+    private ResourceBundle getBundleFromPropertiesFile(final String propertiesFileName) {
+        try {
+            final InputStream inputStream = UriAccessor.accessUri(propertiesFileName);
+            if (inputStream == null) {
+                return null;
+            } else {
+                return new PropertyResourceBundle(inputStream);
+            }
+        } catch (MissingResourceException mrex) {
+            return null;
+        } catch (URISyntaxException e) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java b/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java
index 03c643d..540a0ae 100644
--- a/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java
+++ b/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java
@@ -53,7 +53,7 @@ public abstract class CompletionUserRequestBase implements CompletionUserRequest
 
         this.timeoutMilliSec = timeoutMilliSec;
         initialTimeMilliSec = currentTimeMillis();
-        synchronized(this) {
+        synchronized (this) {
             long remainingTimeMillisSec = getRemainingTimeMillis();
             while (!isCompleted && remainingTimeMillisSec > 0) {
                 wait(remainingTimeMillisSec);
@@ -71,7 +71,7 @@ public abstract class CompletionUserRequestBase implements CompletionUserRequest
 
     @Override
     public void notifyForCompletion() {
-        synchronized(this) {
+        synchronized (this) {
             isCompleted = true;
             notify();
         }
@@ -86,39 +86,39 @@ public abstract class CompletionUserRequestBase implements CompletionUserRequest
     }
 
     @Override
-    public void onBusEvent(BusEvent curEvent) {
+    public void onBusEvent(final BusEvent curEvent) {
         // Check if this is for us..
         if (curEvent.getUserToken() == null ||
-                ! curEvent.getUserToken().equals(userToken)) {
+                !curEvent.getUserToken().equals(userToken)) {
             return;
         }
-        
+
         events.add(curEvent);
-        
-        switch(curEvent.getBusEventType()) {
-        case ACCOUNT_CREATE:
-            onAccountCreation((AccountCreationEvent) curEvent);
-            break;
-        case ACCOUNT_CHANGE:
-            onAccountChange((AccountChangeEvent) curEvent);
-            break;
-        case SUBSCRIPTION_TRANSITION:
-            onSubscriptionTransition((SubscriptionEvent) curEvent);
-            break;
-        case INVOICE_EMPTY:
-            onEmptyInvoice((EmptyInvoiceEvent) curEvent);
-            break;
-        case INVOICE_CREATION:
-            onInvoiceCreation((InvoiceCreationEvent) curEvent);
-            break;
-        case PAYMENT_INFO:
-            onPaymentInfo((PaymentInfoEvent) curEvent);
-            break;
-        case PAYMENT_ERROR:
-            onPaymentError((PaymentErrorEvent) curEvent);
-            break;
-        default:
-            throw new RuntimeException("Unexpected event type " + curEvent.getBusEventType());
+
+        switch (curEvent.getBusEventType()) {
+            case ACCOUNT_CREATE:
+                onAccountCreation((AccountCreationEvent) curEvent);
+                break;
+            case ACCOUNT_CHANGE:
+                onAccountChange((AccountChangeEvent) curEvent);
+                break;
+            case SUBSCRIPTION_TRANSITION:
+                onSubscriptionTransition((SubscriptionEvent) curEvent);
+                break;
+            case INVOICE_EMPTY:
+                onEmptyInvoice((EmptyInvoiceEvent) curEvent);
+                break;
+            case INVOICE_CREATION:
+                onInvoiceCreation((InvoiceCreationEvent) curEvent);
+                break;
+            case PAYMENT_INFO:
+                onPaymentInfo((PaymentInfoEvent) curEvent);
+                break;
+            case PAYMENT_ERROR:
+                onPaymentError((PaymentErrorEvent) curEvent);
+                break;
+            default:
+                throw new RuntimeException("Unexpected event type " + curEvent.getBusEventType());
         }
     }
 
@@ -141,7 +141,7 @@ public abstract class CompletionUserRequestBase implements CompletionUserRequest
     @Override
     public void onEmptyInvoice(final EmptyInvoiceEvent curEvent) {
     }
-    
+
     @Override
     public void onInvoiceCreation(final InvoiceCreationEvent curEvent) {
     }
diff --git a/util/src/main/java/com/ning/billing/util/validation/ColumnInfo.java b/util/src/main/java/com/ning/billing/util/validation/ColumnInfo.java
index 545425b..b32ff7a 100644
--- a/util/src/main/java/com/ning/billing/util/validation/ColumnInfo.java
+++ b/util/src/main/java/com/ning/billing/util/validation/ColumnInfo.java
@@ -25,8 +25,8 @@ public class ColumnInfo {
     private final int maximumLength;
     private final String dataType;
 
-    public ColumnInfo(String tableName, String columnName, int scale, int precision,
-                      boolean nullable, int maximumLength, String dataType) {
+    public ColumnInfo(final String tableName, final String columnName, final int scale, final int precision,
+                      final boolean nullable, final int maximumLength, final String dataType) {
         this.tableName = tableName;
         this.columnName = columnName;
         this.scale = scale;
@@ -63,4 +63,4 @@ public class ColumnInfo {
     public String getDataType() {
         return dataType;
     }
-}
\ No newline at end of file
+}
diff --git a/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaDao.java b/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaDao.java
index c5f88e3..9213b37 100644
--- a/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaDao.java
+++ b/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaDao.java
@@ -16,21 +16,22 @@
 
 package com.ning.billing.util.validation.dao;
 
-import com.google.inject.Inject;
-import com.ning.billing.util.validation.ColumnInfo;
+import java.util.List;
+
 import org.skife.jdbi.v2.IDBI;
 
-import java.util.List;
+import com.google.inject.Inject;
+import com.ning.billing.util.validation.ColumnInfo;
 
 public class DatabaseSchemaDao {
     private final DatabaseSchemaSqlDao dao;
 
     @Inject
-    public DatabaseSchemaDao(IDBI dbi) {
+    public DatabaseSchemaDao(final IDBI dbi) {
         this.dao = dbi.onDemand(DatabaseSchemaSqlDao.class);
     }
 
     public List<ColumnInfo> getColumnInfoList(final String schemaName) {
         return dao.getSchemaInfo(schemaName);
     }
-}
\ No newline at end of file
+}
diff --git a/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaSqlDao.java b/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaSqlDao.java
index 53fccf7..7a5b0cf 100644
--- a/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaSqlDao.java
+++ b/util/src/main/java/com/ning/billing/util/validation/dao/DatabaseSchemaSqlDao.java
@@ -16,7 +16,10 @@
 
 package com.ning.billing.util.validation.dao;
 
-import com.ning.billing.util.validation.ColumnInfo;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
@@ -24,9 +27,7 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTemplate3;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
+import com.ning.billing.util.validation.ColumnInfo;
 
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper(DatabaseSchemaSqlDao.ColumnInfoMapper.class)
@@ -36,7 +37,7 @@ public interface DatabaseSchemaSqlDao {
 
     class ColumnInfoMapper implements ResultSetMapper<ColumnInfo> {
         @Override
-        public ColumnInfo map(int index, ResultSet r, StatementContext ctx) throws SQLException {
+        public ColumnInfo map(final int index, final ResultSet r, final StatementContext ctx) throws SQLException {
             final String tableName = r.getString("table_name");
             final String columnName = r.getString("column_name");
             final Integer scale = r.getInt("numeric_scale");
diff --git a/util/src/main/java/com/ning/billing/util/validation/ValidationConfiguration.java b/util/src/main/java/com/ning/billing/util/validation/ValidationConfiguration.java
index 72f6337..9c27dfd 100644
--- a/util/src/main/java/com/ning/billing/util/validation/ValidationConfiguration.java
+++ b/util/src/main/java/com/ning/billing/util/validation/ValidationConfiguration.java
@@ -17,14 +17,13 @@
 package com.ning.billing.util.validation;
 
 import java.util.HashMap;
-import java.util.Map;
 
 public class ValidationConfiguration extends HashMap<String, ColumnInfo> {
-    public void addMapping(String propertyName, ColumnInfo columnInfo) {
+    public void addMapping(final String propertyName, final ColumnInfo columnInfo) {
         super.put(propertyName, columnInfo);
     }
 
-    public boolean hasMapping(String propertyName) {
+    public boolean hasMapping(final String propertyName) {
         return super.get(propertyName) != null;
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/validation/ValidationManager.java b/util/src/main/java/com/ning/billing/util/validation/ValidationManager.java
index cac7736..a1813b6 100644
--- a/util/src/main/java/com/ning/billing/util/validation/ValidationManager.java
+++ b/util/src/main/java/com/ning/billing/util/validation/ValidationManager.java
@@ -16,9 +16,6 @@
 
 package com.ning.billing.util.validation;
 
-import com.google.inject.Inject;
-import com.ning.billing.util.validation.dao.DatabaseSchemaDao;
-
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.util.Collection;
@@ -26,6 +23,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import com.google.inject.Inject;
+import com.ning.billing.util.validation.dao.DatabaseSchemaDao;
+
 public class ValidationManager {
     private final DatabaseSchemaDao dao;
 
@@ -34,7 +34,7 @@ public class ValidationManager {
     private final Map<Class, ValidationConfiguration> configurations = new HashMap<Class, ValidationConfiguration>();
 
     @Inject
-    public ValidationManager(DatabaseSchemaDao dao) {
+    public ValidationManager(final DatabaseSchemaDao dao) {
         this.dao = dao;
     }
 
@@ -43,8 +43,8 @@ public class ValidationManager {
         columnInfoMap.clear();
 
         // get schema information and map it to columnInfo
-        List<ColumnInfo> columnInfoList = dao.getColumnInfoList(schemaName);
-        for (ColumnInfo columnInfo : columnInfoList) {
+        final List<ColumnInfo> columnInfoList = dao.getColumnInfoList(schemaName);
+        for (final ColumnInfo columnInfo : columnInfoList) {
             final String tableName = columnInfo.getTableName();
 
             if (!columnInfoMap.containsKey(tableName)) {
@@ -63,33 +63,45 @@ public class ValidationManager {
         return (columnInfoMap.get(tableName) == null) ? null : columnInfoMap.get(tableName).get(columnName);
     }
 
-    public boolean validate(Object o) {
-        ValidationConfiguration configuration = getConfiguration(o.getClass());
+    public boolean validate(final Object o) {
+        final ValidationConfiguration configuration = getConfiguration(o.getClass());
 
         // if no configuration exists for this class, the object is valid
-        if (configuration == null) {return true;}
+        if (configuration == null) {
+            return true;
+        }
 
-        Class clazz = o.getClass();
-        for (String propertyName : configuration.keySet()) {
+        final Class clazz = o.getClass();
+        for (final String propertyName : configuration.keySet()) {
             try {
-                Field field = clazz.getDeclaredField(propertyName);
+                final Field field = clazz.getDeclaredField(propertyName);
                 if (!field.isAccessible()) {
                     field.setAccessible(true);
                 }
 
-                Object value = field.get(o);
+                final Object value = field.get(o);
 
-                ColumnInfo columnInfo = configuration.get(propertyName);
+                final ColumnInfo columnInfo = configuration.get(propertyName);
                 if (columnInfo == null) {
                     // no column info means the property hasn't been properly mapped; suppress validation
                     return true;
                 }
 
-                if (!hasValidNullability(columnInfo, value)) {return false;}
-                if (!isValidLengthString(columnInfo, value)) {return false;}
-                if (!isValidLengthChar(columnInfo, value)) {return false;}
-                if (!hasValidPrecision(columnInfo, value)) {return false;}
-                if (!hasValidScale(columnInfo, value)) {return false;}
+                if (!hasValidNullability(columnInfo, value)) {
+                    return false;
+                }
+                if (!isValidLengthString(columnInfo, value)) {
+                    return false;
+                }
+                if (!isValidLengthChar(columnInfo, value)) {
+                    return false;
+                }
+                if (!hasValidPrecision(columnInfo, value)) {
+                    return false;
+                }
+                if (!hasValidScale(columnInfo, value)) {
+                    return false;
+                }
             } catch (NoSuchFieldException e) {
                 // if the field doesn't exist, assume the configuration is faulty and skip this property
             } catch (IllegalAccessException e) {
@@ -103,7 +115,9 @@ public class ValidationManager {
 
     private boolean hasValidNullability(final ColumnInfo columnInfo, final Object value) {
         if (!columnInfo.getIsNullable()) {
-            if (value == null) {return false;}
+            if (value == null) {
+                return false;
+            }
         }
 
         return true;
@@ -123,7 +137,7 @@ public class ValidationManager {
 
     private boolean isValidLengthChar(final ColumnInfo columnInfo, final Object value) {
         if (columnInfo.getDataType().equals("char")) {
-            if (value== null) {
+            if (value == null) {
                 return false;
             } else {
                 if (value.toString().length() != columnInfo.getMaximumLength()) {
@@ -138,7 +152,7 @@ public class ValidationManager {
     private boolean hasValidPrecision(final ColumnInfo columnInfo, final Object value) {
         if (columnInfo.getPrecision() != 0) {
             if (value != null) {
-                BigDecimal bigDecimalValue = new BigDecimal(value.toString());
+                final BigDecimal bigDecimalValue = new BigDecimal(value.toString());
                 if (bigDecimalValue.precision() > columnInfo.getPrecision()) {
                     return false;
                 }
@@ -151,7 +165,7 @@ public class ValidationManager {
     private boolean hasValidScale(final ColumnInfo columnInfo, final Object value) {
         if (columnInfo.getScale() != 0) {
             if (value != null) {
-                BigDecimal bigDecimalValue = new BigDecimal(value.toString());
+                final BigDecimal bigDecimalValue = new BigDecimal(value.toString());
                 if (bigDecimalValue.scale() > columnInfo.getScale()) {
                     return false;
                 }
@@ -161,15 +175,15 @@ public class ValidationManager {
         return true;
     }
 
-    public boolean hasConfiguration(Class clazz) {
+    public boolean hasConfiguration(final Class clazz) {
         return configurations.containsKey(clazz);
     }
 
-    public ValidationConfiguration getConfiguration(Class clazz) {
+    public ValidationConfiguration getConfiguration(final Class clazz) {
         return configurations.get(clazz);
     }
 
-    public void setConfiguration(Class clazz, String propertyName, ColumnInfo columnInfo) {
+    public void setConfiguration(final Class clazz, final String propertyName, final ColumnInfo columnInfo) {
         if (!configurations.containsKey(clazz)) {
             configurations.put(clazz, new ValidationConfiguration());
         }
diff --git a/util/src/main/resources/com/ning/billing/util/bus/dao/PersistentBusSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/bus/dao/PersistentBusSqlDao.sql.stg
index 0cbd4ec..61e991b 100644
--- a/util/src/main/resources/com/ning/billing/util/bus/dao/PersistentBusSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/bus/dao/PersistentBusSqlDao.sql.stg
@@ -14,6 +14,7 @@ getNextBusEventEntry() ::= <<
     where
       processing_state != 'PROCESSED'
       and processing_state != 'REMOVED'
+      and creating_owner = :owner
       and (processing_owner IS NULL OR processing_available_date \<= :now)
     order by
       record_id asc
diff --git a/util/src/main/resources/com/ning/billing/util/ddl.sql b/util/src/main/resources/com/ning/billing/util/ddl.sql
index 9ea7c1a..a0e7dad 100644
--- a/util/src/main/resources/com/ning/billing/util/ddl.sql
+++ b/util/src/main/resources/com/ning/billing/util/ddl.sql
@@ -102,7 +102,8 @@ CREATE TABLE notifications (
     record_id int(11) unsigned NOT NULL AUTO_INCREMENT,
     id char(36) NOT NULL,
     created_date datetime NOT NULL,
-	notification_key varchar(256) NOT NULL,
+    class_name varchar(256) NOT NULL,
+	notification_key varchar(2048) NOT NULL,
 	creating_owner char(50) NOT NULL,
     effective_date datetime NOT NULL,
     queue_name char(64) NOT NULL,
@@ -112,7 +113,7 @@ CREATE TABLE notifications (
     PRIMARY KEY(record_id)
 ) ENGINE=innodb;
 CREATE UNIQUE INDEX notifications_id ON notifications(id);
-CREATE INDEX  `idx_comp_where` ON notifications (`effective_date`, `queue_name`, `processing_state`,`processing_owner`,`processing_available_date`);
+CREATE INDEX  `idx_comp_where` ON notifications (`effective_date`, `queue_name`, `processing_state`,`creating_owner`,`processing_owner`,`processing_available_date`);
 CREATE INDEX  `idx_update` ON notifications (`processing_state`,`processing_owner`,`processing_available_date`);
 CREATE INDEX  `idx_get_ready` ON notifications (`effective_date`,`created_date`,`id`);
 
@@ -153,7 +154,7 @@ CREATE TABLE bus_events (
     processing_state varchar(14) DEFAULT 'AVAILABLE',
     PRIMARY KEY(record_id)
 ) ENGINE=innodb;
-CREATE INDEX  `idx_bus_where` ON bus_events (`processing_state`,`processing_owner`,`processing_available_date`);
+CREATE INDEX  `idx_bus_where` ON bus_events (`processing_state`,`processing_owner`,`creating_owner`,`processing_available_date`);
 
 DROP TABLE IF EXISTS claimed_bus_events;
 CREATE TABLE claimed_bus_events (
diff --git a/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg b/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg
index 0731adc..3c81e21 100644
--- a/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg
+++ b/util/src/main/resources/com/ning/billing/util/notificationq/dao/NotificationSqlDao.sql.stg
@@ -4,6 +4,7 @@ getReadyNotifications() ::= <<
     select
       record_id
       , id
+      , class_name
       , notification_key
       , created_date
       , creating_owner
@@ -13,11 +14,13 @@ getReadyNotifications() ::= <<
       , processing_available_date
       , processing_state
     from notifications
+    FORCE INDEX (idx_comp_where)
     where
       effective_date \<= :now
       and queue_name = :queueName
       and processing_state != 'PROCESSED'
       and processing_state != 'REMOVED'
+      and creating_owner = :owner
       and (processing_owner IS NULL OR processing_available_date \<= :now)
     order by
       effective_date asc
@@ -62,6 +65,7 @@ removeNotificationsByKey() ::= <<
 insertNotification() ::= <<
     insert into notifications (
       id
+      , class_name
       , notification_key
       , created_date
       , creating_owner
@@ -72,6 +76,7 @@ insertNotification() ::= <<
       , processing_state
     ) values (
       :id
+      , :className
       , :notificationKey
       , :createdDate
       , :creatingOwner
diff --git a/util/src/test/java/com/ning/billing/api/TestApiListener.java b/util/src/test/java/com/ning/billing/api/TestApiListener.java
index 9eddf7b..5fc23bc 100644
--- a/util/src/test/java/com/ning/billing/api/TestApiListener.java
+++ b/util/src/test/java/com/ning/billing/api/TestApiListener.java
@@ -32,18 +32,18 @@ import com.ning.billing.payment.api.PaymentErrorEvent;
 import com.ning.billing.payment.api.PaymentInfoEvent;
 
 public class TestApiListener {
-    
+
     protected static final Logger log = LoggerFactory.getLogger(TestApiListener.class);
 
     private final List<NextEvent> nextExpectedEvent;
 
     private final TestListenerStatus testStatus;
-    
+
     private boolean nonExpectedMode;
-    
+
     private volatile boolean completed;
 
-    public TestApiListener(TestListenerStatus testStatus) {
+    public TestApiListener(final TestListenerStatus testStatus) {
         nextExpectedEvent = new Stack<NextEvent>();
         this.completed = false;
         this.testStatus = testStatus;
@@ -52,9 +52,9 @@ public class TestApiListener {
 
     public enum NextEvent {
         MIGRATE_ENTITLEMENT,
-        MIGRATE_BILLING,        
+        MIGRATE_BILLING,
         CREATE,
-        RE_CREATE,        
+        RE_CREATE,
         CHANGE,
         CANCEL,
         UNCANCEL,
@@ -63,66 +63,66 @@ public class TestApiListener {
         PHASE,
         INVOICE,
         PAYMENT,
-        PAYMENT_ERROR,        
+        PAYMENT_ERROR,
         REPAIR_BUNDLE
     }
-    
+
     public void setNonExpectedMode() {
-        synchronized(this) {
+        synchronized (this) {
             this.nonExpectedMode = true;
         }
     }
-    
+
     @Subscribe
-    public void handleEntitlementEvents(RepairEntitlementEvent event) {
+    public void handleEntitlementEvents(final RepairEntitlementEvent event) {
         log.info(String.format("TestApiListener Got RepairEntitlementEvent event %s", event.toString()));
         assertEqualsNicely(NextEvent.REPAIR_BUNDLE);
         notifyIfStackEmpty();
     }
 
     @Subscribe
-    public void handleEntitlementEvents(SubscriptionEvent event) {
+    public void handleEntitlementEvents(final SubscriptionEvent event) {
         log.info(String.format("TestApiListener Got subscription event %s", event.toString()));
         switch (event.getTransitionType()) {
-        case MIGRATE_ENTITLEMENT:
-            assertEqualsNicely(NextEvent.MIGRATE_ENTITLEMENT);
-            notifyIfStackEmpty();
-            break;
-        case MIGRATE_BILLING:
-            assertEqualsNicely(NextEvent.MIGRATE_BILLING);
-            notifyIfStackEmpty();
-            break;
-        case CREATE:
-            assertEqualsNicely(NextEvent.CREATE);
-            notifyIfStackEmpty();
-            break;
-        case RE_CREATE:
-            assertEqualsNicely(NextEvent.RE_CREATE);
-            notifyIfStackEmpty();
-            break;
-        case CANCEL:
-            assertEqualsNicely(NextEvent.CANCEL);
-            notifyIfStackEmpty();
-            break;
-        case CHANGE:
-            assertEqualsNicely(NextEvent.CHANGE);
-            notifyIfStackEmpty();
-            break;
-        case UNCANCEL:
-            assertEqualsNicely(NextEvent.UNCANCEL);
-            notifyIfStackEmpty();
-            break;
-        case PHASE:
-            assertEqualsNicely(NextEvent.PHASE);
-            notifyIfStackEmpty();
-            break;
-        default:
-            throw new RuntimeException("Unexpected event type " + event.getRequestedTransitionTime());
+            case MIGRATE_ENTITLEMENT:
+                assertEqualsNicely(NextEvent.MIGRATE_ENTITLEMENT);
+                notifyIfStackEmpty();
+                break;
+            case MIGRATE_BILLING:
+                assertEqualsNicely(NextEvent.MIGRATE_BILLING);
+                notifyIfStackEmpty();
+                break;
+            case CREATE:
+                assertEqualsNicely(NextEvent.CREATE);
+                notifyIfStackEmpty();
+                break;
+            case RE_CREATE:
+                assertEqualsNicely(NextEvent.RE_CREATE);
+                notifyIfStackEmpty();
+                break;
+            case CANCEL:
+                assertEqualsNicely(NextEvent.CANCEL);
+                notifyIfStackEmpty();
+                break;
+            case CHANGE:
+                assertEqualsNicely(NextEvent.CHANGE);
+                notifyIfStackEmpty();
+                break;
+            case UNCANCEL:
+                assertEqualsNicely(NextEvent.UNCANCEL);
+                notifyIfStackEmpty();
+                break;
+            case PHASE:
+                assertEqualsNicely(NextEvent.PHASE);
+                notifyIfStackEmpty();
+                break;
+            default:
+                throw new RuntimeException("Unexpected event type " + event.getRequestedTransitionTime());
         }
     }
 
     @Subscribe
-    public void handleInvoiceEvents(InvoiceCreationEvent event) {
+    public void handleInvoiceEvents(final InvoiceCreationEvent event) {
         log.info(String.format("TestApiListener Got Invoice event %s", event.toString()));
         assertEqualsNicely(NextEvent.INVOICE);
         notifyIfStackEmpty();
@@ -130,42 +130,43 @@ public class TestApiListener {
     }
 
     @Subscribe
-    public void handlePaymentEvents(PaymentInfoEvent event) {
+    public void handlePaymentEvents(final PaymentInfoEvent event) {
         log.info(String.format("TestApiListener Got PaymentInfo event %s", event.toString()));
         assertEqualsNicely(NextEvent.PAYMENT);
         notifyIfStackEmpty();
     }
 
     @Subscribe
-    public void handlePaymentErrorEvents(PaymentErrorEvent event) {
+    public void handlePaymentErrorEvents(final PaymentErrorEvent event) {
         log.info(String.format("TestApiListener Got PaymentError event %s", event.toString()));
         assertEqualsNicely(NextEvent.PAYMENT_ERROR);
-        notifyIfStackEmpty();   }
+        notifyIfStackEmpty();
+    }
 
     public void reset() {
-        synchronized(this) {
+        synchronized (this) {
             nextExpectedEvent.clear();
             completed = true;
             nonExpectedMode = false;
         }
     }
 
-    public void pushExpectedEvents(NextEvent ... events) {
-        for(NextEvent event : events) {
+    public void pushExpectedEvents(final NextEvent... events) {
+        for (final NextEvent event : events) {
             pushExpectedEvent(event);
         }
     }
 
-    public void pushExpectedEvent(NextEvent next) {
+    public void pushExpectedEvent(final NextEvent next) {
         synchronized (this) {
-            Joiner joiner = Joiner.on(" ");
+            final Joiner joiner = Joiner.on(" ");
             nextExpectedEvent.add(next);
             log.info("TestListener stacking expected event {}, got [{}]", next, joiner.join(nextExpectedEvent));
             completed = false;
         }
     }
 
-    public boolean isCompleted(long timeout) {
+    public boolean isCompleted(final long timeout) {
         synchronized (this) {
             if (completed) {
                 return completed;
@@ -173,12 +174,12 @@ public class TestApiListener {
             long waitTimeMs = timeout;
             do {
                 try {
-                    DateTime before = new DateTime();
+                    final DateTime before = new DateTime();
                     wait(500);
                     if (completed) {
                         return completed;
                     }
-                    DateTime after = new DateTime();
+                    final DateTime after = new DateTime();
                     waitTimeMs -= after.getMillis() - before.getMillis();
                 } catch (Exception ignore) {
                     log.error("isCompleted got interrupted ", ignore);
@@ -187,7 +188,7 @@ public class TestApiListener {
             } while (waitTimeMs > 0 && !completed);
         }
         if (!completed && !nonExpectedMode) {
-            Joiner joiner = Joiner.on(" ");
+            final Joiner joiner = Joiner.on(" ");
             log.error("TestApiListener did not complete in " + timeout + " ms, remaining events are " + joiner.join(nextExpectedEvent));
         }
         return completed;
@@ -205,26 +206,26 @@ public class TestApiListener {
         log.debug("TestApiListener notifyIfStackEmpty EXIT");
     }
 
-    private void assertEqualsNicely(NextEvent received) {
+    private void assertEqualsNicely(final NextEvent received) {
 
-        synchronized(this) {
+        synchronized (this) {
             boolean foundIt = false;
-            Iterator<NextEvent> it = nextExpectedEvent.iterator();
+            final Iterator<NextEvent> it = nextExpectedEvent.iterator();
             while (it.hasNext()) {
-                NextEvent ev = it.next();
+                final NextEvent ev = it.next();
                 if (ev == received) {
                     it.remove();
                     foundIt = true;
                     if (!nonExpectedMode) {
-                        log.info("TestApiListener found event {}. Yeah!", received);    
+                        log.info("TestApiListener found event {}. Yeah!", received);
                     } else {
-                        log.error("TestApiListener found non expected event {}. Boohh! ", received);    
+                        log.error("TestApiListener found non expected event {}. Boohh! ", received);
                     }
                     break;
                 }
             }
             if (!foundIt && !nonExpectedMode) {
-                Joiner joiner = Joiner.on(" ");
+                final Joiner joiner = Joiner.on(" ");
                 log.error("TestApiListener Received event " + received + "; expecting " + joiner.join(nextExpectedEvent));
                 if (testStatus != null) {
                     testStatus.failed("TestApiListener [ApiListenerStatus]: Received event " + received + "; expecting " + joiner.join(nextExpectedEvent));
diff --git a/util/src/test/java/com/ning/billing/api/TestListenerStatus.java b/util/src/test/java/com/ning/billing/api/TestListenerStatus.java
index 23b8174..8fec86f 100644
--- a/util/src/test/java/com/ning/billing/api/TestListenerStatus.java
+++ b/util/src/test/java/com/ning/billing/api/TestListenerStatus.java
@@ -16,7 +16,7 @@
 package com.ning.billing.api;
 
 public interface TestListenerStatus {
-    
+
     public void failed(String msg);
 
     public void resetTestListenerStatus();
diff --git a/util/src/test/java/com/ning/billing/dbi/DbiConfig.java b/util/src/test/java/com/ning/billing/dbi/DbiConfig.java
index feb6ebd..88778f5 100644
--- a/util/src/test/java/com/ning/billing/dbi/DbiConfig.java
+++ b/util/src/test/java/com/ning/billing/dbi/DbiConfig.java
@@ -21,8 +21,7 @@ import org.skife.config.Default;
 import org.skife.config.Description;
 import org.skife.config.TimeSpan;
 
-public interface DbiConfig
-{
+public interface DbiConfig {
     @Description("The jdbc url for the database")
     @Config("com.ning.billing.dbi.jdbc.url")
     @Default("jdbc:mysql://127.0.0.1:3306/killbill")
@@ -52,4 +51,4 @@ public interface DbiConfig
     @Config("com.ning.billing.dbi.jdbc.connectionTimeout")
     @Default("10s")
     TimeSpan getConnectionTimeout();
-}
\ No newline at end of file
+}
diff --git a/util/src/test/java/com/ning/billing/dbi/DBIProvider.java b/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
index 1f22d5d..be2e012 100644
--- a/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
+++ b/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
@@ -16,31 +16,24 @@
 
 package com.ning.billing.dbi;
 
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.IDBI;
+
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.jolbox.bonecp.BoneCPConfig;
 import com.jolbox.bonecp.BoneCPDataSource;
-import org.skife.jdbi.v2.DBI;
-import org.skife.jdbi.v2.IDBI;
-import org.skife.jdbi.v2.TimingCollector;
-import org.skife.jdbi.v2.logging.Log4JLog;
-import org.skife.jdbi.v2.tweak.SQLLog;
-
-import java.util.concurrent.TimeUnit;
 
-public class DBIProvider implements Provider<IDBI>
-{
+public class DBIProvider implements Provider<IDBI> {
     private final DbiConfig config;
 
     @Inject
-    public DBIProvider(final DbiConfig config)
-    {
+    public DBIProvider(final DbiConfig config) {
         this.config = config;
     }
 
     @Override
-    public IDBI get()
-    {
+    public IDBI get() {
         final BoneCPConfig dbConfig = new BoneCPConfig();
         dbConfig.setJdbcUrl(config.getJdbcUrl());
         dbConfig.setUsername(config.getUsername());
@@ -55,8 +48,8 @@ public class DBIProvider implements Provider<IDBI>
 
         final BoneCPDataSource ds = new BoneCPDataSource(dbConfig);
         final DBI dbi = new DBI(ds);
-        final SQLLog log = new Log4JLog();
-        dbi.setSQLLog(log);
+        //final SQLLog log = new Log4JLog();
+        //dbi.setSQLLog(log);
 
         return dbi;
     }
diff --git a/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java b/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
index 2aef0a9..f1bfc60 100644
--- a/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
+++ b/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
@@ -17,13 +17,13 @@
 package com.ning.billing.dbi;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.ServerSocket;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.io.FileUtils;
 import org.skife.jdbi.v2.DBI;
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
@@ -39,8 +39,7 @@ import com.mysql.management.MysqldResourceI;
 /**
  * Utility class to embed MySQL for testing purposes
  */
-public class MysqlTestingHelper
-{
+public class MysqlTestingHelper {
 
     public static final String USE_LOCAL_DB_PROP = "com.ning.billing.dbi.test.useLocalDb";
 
@@ -51,14 +50,13 @@ public class MysqlTestingHelper
     private static final String PASSWORD = "root";
 
     // Discover dynamically list of all tables in that database;
-    private List<String> allTables;    
+    private List<String> allTables;
     private File dbDir;
     private File dataDir;
     private MysqldResource mysqldResource;
     private int port;
 
-    public MysqlTestingHelper()
-    {
+    public MysqlTestingHelper() {
         if (isUsingLocalInstance()) {
             port = 3306;
         } else {
@@ -68,8 +66,7 @@ public class MysqlTestingHelper
                 socket = new ServerSocket(0);
                 port = socket.getLocalPort();
                 socket.close();
-            }
-            catch (IOException e) {
+            } catch (IOException e) {
                 Assert.fail();
             }
         }
@@ -80,8 +77,7 @@ public class MysqlTestingHelper
         return (System.getProperty(USE_LOCAL_DB_PROP) != null);
     }
 
-    public void startMysql() throws IOException
-    {
+    public void startMysql() throws IOException {
         if (isUsingLocalInstance()) {
             return;
         }
@@ -106,15 +102,13 @@ public class MysqlTestingHelper
         mysqldResource.start("test-mysqld-thread", dbOpts);
         if (!mysqldResource.isRunning()) {
             throw new IllegalStateException("MySQL did not start.");
-        }
-        else {
+        } else {
             log.info("MySQL running on port " + mysqldResource.getPort());
             log.info(String.format("To connect to it: mysql -u%s -p%s -P%s -S%s/mysql.sock %s", USERNAME, PASSWORD, port, dataDir, DB_NAME));
         }
     }
 
-    public void cleanupTable(final String table)
-    {
+    public void cleanupTable(final String table) {
 
         if (!isUsingLocalInstance() && (mysqldResource == null || !mysqldResource.isRunning())) {
             log.error("Asked to cleanup table " + table + " but MySQL is not running!");
@@ -123,53 +117,50 @@ public class MysqlTestingHelper
 
         log.info("Deleting table: " + table);
         final IDBI dbi = getDBI();
-        dbi.withHandle(new HandleCallback<Void>()
-        {
+        dbi.withHandle(new HandleCallback<Void>() {
             @Override
-            public Void withHandle(final Handle handle) throws Exception
-            {
+            public Void withHandle(final Handle handle) throws Exception {
                 handle.execute("truncate " + table);
                 return null;
             }
         });
     }
-    
+
     public void cleanupAllTables() {
-    	final List<String> tablesToCleanup = fetchAllTables();
-    	for (String tableName : tablesToCleanup) {
-    		cleanupTable(tableName);
-    	}
+        final List<String> tablesToCleanup = fetchAllTables();
+        for (final String tableName : tablesToCleanup) {
+            cleanupTable(tableName);
+        }
     }
 
     public synchronized List<String> fetchAllTables() {
 
-    	if (allTables == null) {
-    		final String dbiString = "jdbc:mysql://localhost:" + port + "/information_schema";
-    		IDBI cleanupDbi = new DBI(dbiString, USERNAME, PASSWORD);
-
-    		final List<String> tables=  cleanupDbi.withHandle(new HandleCallback<List<String>>() {
-
-    			@Override
-    			public List<String> withHandle(Handle h) throws Exception {
-    				return h.createQuery("select table_name from tables where table_schema = :table_schema and table_type = 'BASE TABLE';")
-    				.bind("table_schema", DB_NAME)
-    				.map(new StringMapper())
-    				.list();
-    			}
-    		});
-    		allTables = tables;
-    	}
-    	return allTables;
+        if (allTables == null) {
+            final String dbiString = "jdbc:mysql://localhost:" + port + "/information_schema";
+            final IDBI cleanupDbi = new DBI(dbiString, USERNAME, PASSWORD);
+
+            final List<String> tables = cleanupDbi.withHandle(new HandleCallback<List<String>>() {
+
+                @Override
+                public List<String> withHandle(final Handle h) throws Exception {
+                    return h.createQuery("select table_name from tables where table_schema = :table_schema and table_type = 'BASE TABLE';")
+                            .bind("table_schema", DB_NAME)
+                            .map(new StringMapper())
+                            .list();
+                }
+            });
+            allTables = tables;
+        }
+        return allTables;
     }
 
-    
-    public void stopMysql()
-    {
+
+    public void stopMysql() {
         try {
             if (mysqldResource != null) {
                 mysqldResource.shutdown();
-                FileUtils.deleteQuietly(dataDir);
-                FileUtils.deleteQuietly(dbDir);
+                deleteRecursive(dataDir);
+                deleteRecursive(dbDir);
                 log.info("MySQLd stopped");
             }
         } catch (Exception ex) {
@@ -177,23 +168,19 @@ public class MysqlTestingHelper
         }
     }
 
-    public IDBI getDBI()
-    {
+    public IDBI getDBI() {
         final String dbiString = "jdbc:mysql://localhost:" + port + "/" + DB_NAME + "?createDatabaseIfNotExist=true&allowMultiQueries=true";
         return new DBI(dbiString, USERNAME, PASSWORD);
     }
 
-    public void initDb(final String ddl) throws IOException
-    {
+    public void initDb(final String ddl) throws IOException {
         if (isUsingLocalInstance()) {
             return;
         }
         final IDBI dbi = getDBI();
-        dbi.withHandle(new HandleCallback<Void>()
-        {
+        dbi.withHandle(new HandleCallback<Void>() {
             @Override
-            public Void withHandle(final Handle handle) throws Exception
-            {
+            public Void withHandle(final Handle handle) throws Exception {
                 log.info("Executing DDL script: " + ddl);
                 handle.createScript(ddl).execute();
                 return null;
@@ -204,4 +191,17 @@ public class MysqlTestingHelper
     public String getDbName() {
         return DB_NAME;
     }
+
+    public static boolean deleteRecursive(final File path) throws FileNotFoundException {
+        if (!path.exists()) {
+            throw new FileNotFoundException(path.getAbsolutePath());
+        }
+        boolean ret = true;
+        if (path.isDirectory()) {
+            for (final File f : path.listFiles()) {
+                ret = ret && deleteRecursive(f);
+            }
+        }
+        return ret && path.delete();
+    }
 }
diff --git a/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java b/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
index 7a3d28f..9b9d64f 100644
--- a/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
+++ b/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
@@ -26,12 +26,10 @@ import java.util.Map;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import bsh.This;
-
 public class BrainDeadProxyFactory {
     private static final Logger log = LoggerFactory.getLogger(BrainDeadProxyFactory.class);
-    
-    public static final Object ZOMBIE_VOID = new Object(); 
+
+    public static final Object ZOMBIE_VOID = new Object();
 
     public static interface ZombieControl {
 
@@ -42,47 +40,47 @@ public class BrainDeadProxyFactory {
     }
 
     @SuppressWarnings("unchecked")
-    public static <T> T createBrainDeadProxyFor(final Class<T> clazz, final Class<?> ... others) {
-        Class<?>[] clazzes = Arrays.copyOf(others, others.length + 2);
+    public static <T> T createBrainDeadProxyFor(final Class<T> clazz, final Class<?>... others) {
+        final Class<?>[] clazzes = Arrays.copyOf(others, others.length + 2);
         clazzes[others.length] = ZombieControl.class;
         clazzes[others.length + 1] = clazz;
         return (T) Proxy.newProxyInstance(clazz.getClassLoader(),
-                clazzes,
-                new InvocationHandler() {
-            private final Map<String,Object> results = new HashMap<String,Object>();
+                                          clazzes,
+                                          new InvocationHandler() {
+                                              private final Map<String, Object> results = new HashMap<String, Object>();
 
-            @Override
-            public Object invoke(Object proxy, Method method, Object[] args)
-                throws Throwable {
+                                              @Override
+                                              public Object invoke(final Object proxy, final Method method, final Object[] args)
+                                                      throws Throwable {
 
-                if (method.getDeclaringClass().equals(ZombieControl.class)) {
-                    if(method.getName().equals("addResult")) {
-                        results.put((String) args[0], args[1]);
-                        return proxy;
-                    } else if(method.getName().equals("clearResults")) {
-                        results.clear();
-                        return proxy;
-                    }
+                                                  if (method.getDeclaringClass().equals(ZombieControl.class)) {
+                                                      if (method.getName().equals("addResult")) {
+                                                          results.put((String) args[0], args[1]);
+                                                          return proxy;
+                                                      } else if (method.getName().equals("clearResults")) {
+                                                          results.clear();
+                                                          return proxy;
+                                                      }
 
-                } else {
+                                                  } else {
 
-                    Object result = results.get(method.getName());
-                    if (result == ZOMBIE_VOID) {
-                    	return (Void) null;
-                    } else if (result != null) {
-                    	if(result instanceof Throwable) {
-                    		throw ((Throwable) result);
-                    	}
-                        return result;
-                    } else if (method.getName().equals("equals")){
-                       return proxy == args[0];
-                    } else {
-                        log.error(String.format("No result for Method: '%s' on Class '%s'",method.getName(), method.getDeclaringClass().getName()));
-                        throw new UnsupportedOperationException();
-                    }
-                }
-                return null;
-            }
-        });
+                                                      final Object result = results.get(method.getName());
+                                                      if (result == ZOMBIE_VOID) {
+                                                          return (Void) null;
+                                                      } else if (result != null) {
+                                                          if (result instanceof Throwable) {
+                                                              throw ((Throwable) result);
+                                                          }
+                                                          return result;
+                                                      } else if (method.getName().equals("equals")) {
+                                                          return proxy == args[0];
+                                                      } else {
+                                                          log.error(String.format("No result for Method: '%s' on Class '%s'", method.getName(), method.getDeclaringClass().getName()));
+                                                          throw new UnsupportedOperationException();
+                                                      }
+                                                  }
+                                                  return null;
+                                              }
+                                          });
     }
 }
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockClockModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockClockModule.java
index cf7051f..2a94dd1 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockClockModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockClockModule.java
@@ -23,11 +23,10 @@ import com.ning.billing.util.clock.ClockMock;
 
 public class MockClockModule extends AbstractModule {
 
-	@Override
-	protected void configure() {
-	    bind(Clock.class).to(ClockMock.class).asEagerSingleton();
+    @Override
+    protected void configure() {
+        bind(Clock.class).to(ClockMock.class).asEagerSingleton();
         bind(ClockMock.class).asEagerSingleton();
-	}
+    }
 
 }
- 
\ No newline at end of file
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockDbHelperModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockDbHelperModule.java
index 232c4e8..be1ade6 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockDbHelperModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockDbHelperModule.java
@@ -26,13 +26,13 @@ import com.ning.billing.dbi.MysqlTestingHelper;
 
 public class MockDbHelperModule extends AbstractModule {
 
-    
+
     @Override
     protected void configure() {
         installMysqlTestingHelper();
     }
-    
-    public void  installMysqlTestingHelper() {
+
+    public void installMysqlTestingHelper() {
 
         final MysqlTestingHelper helper = new MysqlTestingHelper();
         bind(MysqlTestingHelper.class).toInstance(helper);
@@ -41,10 +41,10 @@ public class MockDbHelperModule extends AbstractModule {
             final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
             bind(DbiConfig.class).toInstance(config);
         } else {
-            final IDBI dbi = helper.getDBI(); 
+            final IDBI dbi = helper.getDBI();
             bind(IDBI.class).toInstance(dbi);
         }
 
     }
-    
+
 }
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockEntitlementModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockEntitlementModule.java
index 044618e..5037f48 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockEntitlementModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockEntitlementModule.java
@@ -27,34 +27,34 @@ import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.util.glue.RealImplementation;
 
 public class MockEntitlementModule extends AbstractModule implements EntitlementModule {
-    
+
     /* (non-Javadoc)
-     * @see com.ning.billing.mock.glue.EntitlementModule#installEntitlementService()
-     */
+    * @see com.ning.billing.mock.glue.EntitlementModule#installEntitlementService()
+    */
     @Override
     public void installEntitlementService() {
         bind(EntitlementService.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementService.class));
     }
-    
+
     /* (non-Javadoc)
-     * @see com.ning.billing.mock.glue.EntitlementModule#installEntitlementUserApi()
-     */
+    * @see com.ning.billing.mock.glue.EntitlementModule#installEntitlementUserApi()
+    */
     @Override
     public void installEntitlementUserApi() {
         bind(EntitlementUserApi.class).annotatedWith(RealImplementation.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class));
     }
-    
+
     /* (non-Javadoc)
-     * @see com.ning.billing.mock.glue.EntitlementModule#installEntitlementMigrationApi()
-     */
+    * @see com.ning.billing.mock.glue.EntitlementModule#installEntitlementMigrationApi()
+    */
     @Override
     public void installEntitlementMigrationApi() {
         bind(EntitlementMigrationApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementMigrationApi.class));
     }
-    
+
     /* (non-Javadoc)
-     * @see com.ning.billing.mock.glue.EntitlementModule#installChargeThruApi()
-     */
+    * @see com.ning.billing.mock.glue.EntitlementModule#installChargeThruApi()
+    */
     @Override
     public void installChargeThruApi() {
         bind(ChargeThruApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(ChargeThruApi.class));
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockInvoiceModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockInvoiceModule.java
index f499e9a..5c34b36 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockInvoiceModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockInvoiceModule.java
@@ -28,7 +28,7 @@ public class MockInvoiceModule extends AbstractModule implements InvoiceModule {
 
     @Override
     public void installInvoiceUserApi() {
-       bind(InvoiceUserApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceUserApi.class));
+        bind(InvoiceUserApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(InvoiceUserApi.class));
     }
 
     @Override
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockJunctionModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockJunctionModule.java
index 1549c0b..67769dd 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockJunctionModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockJunctionModule.java
@@ -25,11 +25,11 @@ import com.ning.billing.junction.api.BlockingApi;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 
 public class MockJunctionModule extends AbstractModule implements JunctionModule {
-    private BillingApi billingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(BillingApi.class);
-    private BlockingApi blockingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(BlockingApi.class);
-    private AccountUserApi userApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
-    private EntitlementUserApi entUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
-    
+    private final BillingApi billingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(BillingApi.class);
+    private final BlockingApi blockingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(BlockingApi.class);
+    private final AccountUserApi userApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+    private final EntitlementUserApi entUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementUserApi.class);
+
     @Override
     protected void configure() {
         installBlockingApi();
@@ -42,18 +42,18 @@ public class MockJunctionModule extends AbstractModule implements JunctionModule
     public void installBillingApi() {
         bind(BillingApi.class).toInstance(billingApi);
     }
-    
-    
+
+
     @Override
     public void installAccountUserApi() {
         bind(AccountUserApi.class).toInstance(userApi);
     }
-    
+
     @Override
     public void installBlockingApi() {
         bind(BlockingApi.class).toInstance(blockingApi);
     }
-    
+
     @Override
     public void installEntitlementUserApi() {
         bind(EntitlementUserApi.class).toInstance(entUserApi);
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockPaymentModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockPaymentModule.java
index 189e1f1..e974333 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/MockPaymentModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockPaymentModule.java
@@ -24,8 +24,8 @@ public class MockPaymentModule extends AbstractModule {
 
     @Override
     protected void configure() {
-       
+
         bind(PaymentApi.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(PaymentApi.class));
-        
+
     }
 }
diff --git a/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java b/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java
index c42717d..76dea1d 100644
--- a/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java
+++ b/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java
@@ -25,7 +25,7 @@ import com.ning.billing.dbi.DbiConfig;
 import com.ning.billing.dbi.MysqlTestingHelper;
 
 public class TestDbiModule extends AbstractModule {
- 
+
     protected void configure() {
 
         final MysqlTestingHelper helper = new MysqlTestingHelper();
@@ -35,9 +35,9 @@ public class TestDbiModule extends AbstractModule {
             final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
             bind(DbiConfig.class).toInstance(config);
         } else {
-            final IDBI dbi = helper.getDBI(); 
+            final IDBI dbi = helper.getDBI();
             bind(IDBI.class).toInstance(dbi);
         }
 
-     }
+    }
 }
diff --git a/util/src/test/java/com/ning/billing/mock/MockAccountBuilder.java b/util/src/test/java/com/ning/billing/mock/MockAccountBuilder.java
index 842372c..0985646 100644
--- a/util/src/test/java/com/ning/billing/mock/MockAccountBuilder.java
+++ b/util/src/test/java/com/ning/billing/mock/MockAccountBuilder.java
@@ -21,29 +21,30 @@ import java.util.UUID;
 import org.joda.time.DateTimeZone;
 
 import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountData;
 import com.ning.billing.account.api.MutableAccountData;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.junction.api.BlockingState;
 
 public class MockAccountBuilder {
     private final UUID id;
-    private String externalKey;
-    private String email;
-    private String name;
+    private String externalKey = "";
+    private String email = "";
+    private String name = "";
     private int firstNameLength;
-    private Currency currency;
+    private Currency currency = Currency.USD;
     private int billingCycleDay;
     private UUID paymentMethodId;
-    private DateTimeZone timeZone;
-    private String locale;
-    private String address1;
-    private String address2;
-    private String companyName;
-    private String city;
-    private String stateOrProvince;
-    private String country;
-    private String postalCode;
-    private String phone;
+    private DateTimeZone timeZone = DateTimeZone.UTC;
+    private String locale = "";
+    private String address1 = "";
+    private String address2 = "";
+    private String companyName = "";
+    private String city = "";
+    private String stateOrProvince = "";
+    private String country = "";
+    private String postalCode = "";
+    private String phone = "";
     private boolean migrated;
     private boolean isNotifiedForInvoices;
 
@@ -55,6 +56,29 @@ public class MockAccountBuilder {
         this.id = id;
     }
 
+    public MockAccountBuilder(final AccountData data) {
+        this.id = UUID.randomUUID();
+        this.address1(data.getAddress1());
+        this.address2(data.getAddress2());
+        this.billingCycleDay(data.getBillCycleDay());
+        this.city(data.getCity());
+        this.companyName(data.getCompanyName());
+        this.country(data.getCountry());
+        this.currency(data.getCurrency());
+        this.email(data.getEmail());
+        this.externalKey(data.getExternalKey());
+        this.firstNameLength(data.getFirstNameLength());
+        this.isNotifiedForInvoices(data.isNotifiedForInvoices());
+        this.locale(data.getLocale());
+        this.migrated(data.isMigrated());
+        this.name(data.getName());
+        this.paymentMethodId(data.getPaymentMethodId());
+        this.phone(data.getPhone());
+        this.postalCode(data.getPostalCode());
+        this.stateOrProvince(data.getStateOrProvince());
+        this.timeZone(data.getTimeZone());
+    }
+
     public MockAccountBuilder externalKey(final String externalKey) {
         this.externalKey = externalKey;
         return this;
@@ -151,8 +175,7 @@ public class MockAccountBuilder {
     }
 
     public Account build() {
-        return new Account(){
-            
+        return new Account() {
             @Override
             public String getExternalKey() {
                 return externalKey;
@@ -160,109 +183,109 @@ public class MockAccountBuilder {
 
             @Override
             public String getName() {
-               
+
                 return name;
             }
 
             @Override
-            public int getFirstNameLength() {
-               
+            public Integer getFirstNameLength() {
+
                 return firstNameLength;
             }
 
             @Override
             public String getEmail() {
-               
+
                 return email;
             }
 
             @Override
-            public int getBillCycleDay() {
-               
+            public Integer getBillCycleDay() {
+
                 return billingCycleDay;
             }
 
             @Override
             public Currency getCurrency() {
-               
+
                 return currency;
             }
 
             @Override
             public UUID getPaymentMethodId() {
-               
+
                 return paymentMethodId;
             }
 
             @Override
             public DateTimeZone getTimeZone() {
-               
+
                 return timeZone;
             }
 
             @Override
             public String getLocale() {
-               
+
                 return locale;
             }
 
             @Override
             public String getAddress1() {
-               
+
                 return address1;
             }
 
             @Override
             public String getAddress2() {
-               
+
                 return address2;
             }
 
             @Override
             public String getCompanyName() {
-               
+
                 return companyName;
             }
 
             @Override
             public String getCity() {
-               
+
                 return city;
             }
 
             @Override
             public String getStateOrProvince() {
-               
+
                 return stateOrProvince;
             }
 
             @Override
             public String getPostalCode() {
-               
+
                 return postalCode;
             }
 
             @Override
             public String getCountry() {
-               
+
                 return country;
             }
 
             @Override
             public String getPhone() {
-               
+
                 return phone;
             }
 
             @Override
-            public boolean isMigrated() {
-               
+            public Boolean isMigrated() {
+
                 return migrated;
             }
 
             @Override
-            public boolean isNotifiedForInvoices() {
-               
+            public Boolean isNotifiedForInvoices() {
+
                 return isNotifiedForInvoices;
             }
 
@@ -280,6 +303,11 @@ public class MockAccountBuilder {
             public MutableAccountData toMutableAccountData() {
                 throw new UnsupportedOperationException();
             }
+
+            @Override
+            public Account mergeWithDelegate(final Account delegate) {
+                throw new UnsupportedOperationException();
+            }
         };
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/bus/TestEventBus.java b/util/src/test/java/com/ning/billing/util/bus/TestEventBus.java
index a64aa3e..a91842d 100644
--- a/util/src/test/java/com/ning/billing/util/bus/TestEventBus.java
+++ b/util/src/test/java/com/ning/billing/util/bus/TestEventBus.java
@@ -19,7 +19,7 @@ package com.ning.billing.util.bus;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-@Test(groups={"slow"})
+@Test(groups = {"slow"})
 public class TestEventBus extends TestEventBusBase {
 
 
@@ -28,7 +28,7 @@ public class TestEventBus extends TestEventBusBase {
         eventBus = new InMemoryBus();
         super.setup();
     }
-    
+
     @Test(groups = "slow")
     public void testSimple() {
         super.testSimple();
diff --git a/util/src/test/java/com/ning/billing/util/bus/TestEventBusBase.java b/util/src/test/java/com/ning/billing/util/bus/TestEventBusBase.java
index bd74b44..52f06c6 100644
--- a/util/src/test/java/com/ning/billing/util/bus/TestEventBusBase.java
+++ b/util/src/test/java/com/ning/billing/util/bus/TestEventBusBase.java
@@ -17,15 +17,15 @@ package com.ning.billing.util.bus;
 
 import java.util.UUID;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
 import com.ning.billing.util.bus.BusEvent.BusEventType;
@@ -41,26 +41,26 @@ public class TestEventBusBase {
     public void setup() throws Exception {
         eventBus.start();
     }
-    
+
     @AfterClass(groups = "slow")
     public void tearDown() {
         eventBus.stop();
     }
 
-    
-    public static  class MyEvent implements BusEvent {
-        
-        private String name;
-        private Long value;
-        private UUID userToken;
-        private String type;
+
+    public static class MyEvent implements BusEvent {
+
+        private final String name;
+        private final Long value;
+        private final UUID userToken;
+        private final String type;
 
         @JsonCreator
-        public MyEvent(@JsonProperty("name") String name,
-                @JsonProperty("value") Long value,
-                @JsonProperty("token") UUID token,
-                @JsonProperty("type") String type) {
-                
+        public MyEvent(@JsonProperty("name") final String name,
+                       @JsonProperty("value") final Long value,
+                       @JsonProperty("token") final UUID token,
+                       @JsonProperty("type") final String type) {
+
             this.name = name;
             this.value = value;
             this.userToken = token;
@@ -90,39 +90,39 @@ public class TestEventBusBase {
             return type;
         }
     }
-    
+
     public static final class MyEventWithException extends MyEvent {
-        
+
         @JsonCreator
-        public MyEventWithException(@JsonProperty("name") String name,
-                @JsonProperty("value") Long value,
-                @JsonProperty("token") UUID token,
-                @JsonProperty("type") String type) {
+        public MyEventWithException(@JsonProperty("name") final String name,
+                                    @JsonProperty("value") final Long value,
+                                    @JsonProperty("token") final UUID token,
+                                    @JsonProperty("type") final String type) {
             super(name, value, token, type);
-        }        
+        }
     }
 
 
     public static final class MyOtherEvent implements BusEvent {
 
-        private String name;
-        private Double value;
-        private UUID userToken;
-        private String type;
+        private final String name;
+        private final Double value;
+        private final UUID userToken;
+        private final String type;
 
 
         @JsonCreator
-        public MyOtherEvent(@JsonProperty("name") String name,
-                @JsonProperty("value") Double value,
-                @JsonProperty("token") UUID token,
-                @JsonProperty("type") String type) {
-                
+        public MyOtherEvent(@JsonProperty("name") final String name,
+                            @JsonProperty("value") final Double value,
+                            @JsonProperty("token") final UUID token,
+                            @JsonProperty("type") final String type) {
+
             this.name = name;
             this.value = value;
             this.userToken = token;
             this.type = type;
         }
-       
+
         @JsonIgnore
         @Override
         public BusEventType getBusEventType() {
@@ -146,9 +146,9 @@ public class TestEventBusBase {
             return type;
         }
     }
-    
+
     public static class MyEventHandlerException extends RuntimeException {
-        public MyEventHandlerException(String msg) {
+        public MyEventHandlerException(final String msg) {
             super(msg);
         }
     }
@@ -160,7 +160,7 @@ public class TestEventBusBase {
         private volatile int gotEvents;
 
 
-        public MyEventHandler(int exp) {
+        public MyEventHandler(final int exp) {
             this.expectedEvents = exp;
             this.gotEvents = 0;
         }
@@ -170,19 +170,19 @@ public class TestEventBusBase {
         }
 
         @Subscribe
-        public synchronized void processEvent(MyEvent event) {
+        public synchronized void processEvent(final MyEvent event) {
             gotEvents++;
             //log.debug("Got event {} {}", event.name, event.value);
         }
 
         @Subscribe
-        public synchronized void processEvent(MyEventWithException event) {
+        public synchronized void processEvent(final MyEventWithException event) {
             throw new MyEventHandlerException("FAIL");
         }
-        
-        public synchronized boolean waitForCompletion(long timeoutMs) {
 
-            long ini = System.currentTimeMillis();
+        public synchronized boolean waitForCompletion(final long timeoutMs) {
+
+            final long ini = System.currentTimeMillis();
             long remaining = timeoutMs;
             while (gotEvents < expectedEvents && remaining > 0) {
                 try {
@@ -200,40 +200,40 @@ public class TestEventBusBase {
 
     public void testSimpleWithException() {
         try {
-        MyEventHandler handler = new MyEventHandler(1);
-        eventBus.register(handler);
+            final MyEventHandler handler = new MyEventHandler(1);
+            eventBus.register(handler);
+
+            eventBus.post(new MyEventWithException("my-event", 1L, UUID.randomUUID(), BusEventType.ACCOUNT_CHANGE.toString()));
 
-        eventBus.post(new MyEventWithException("my-event", 1L, UUID.randomUUID(), BusEventType.ACCOUNT_CHANGE.toString()));
-        
-        Thread.sleep(50000);
+            Thread.sleep(50000);
         } catch (Exception e) {
-            
+
         }
-        
+
     }
-    
+
     public void testSimple() {
         try {
 
-            int nbEvents = 5;
-            MyEventHandler handler = new MyEventHandler(nbEvents);
+            final int nbEvents = 5;
+            final MyEventHandler handler = new MyEventHandler(nbEvents);
             eventBus.register(handler);
 
             for (int i = 0; i < nbEvents; i++) {
                 eventBus.post(new MyEvent("my-event", (long) i, UUID.randomUUID(), BusEventType.ACCOUNT_CHANGE.toString()));
             }
 
-            boolean completed = handler.waitForCompletion(10000);
+            final boolean completed = handler.waitForCompletion(10000);
             Assert.assertEquals(completed, true);
         } catch (Exception e) {
-            Assert.fail("",e);
+            Assert.fail("", e);
         }
     }
 
     public void testDifferentType() {
         try {
 
-            MyEventHandler handler = new MyEventHandler(1);
+            final MyEventHandler handler = new MyEventHandler(1);
             eventBus.register(handler);
 
             for (int i = 0; i < 5; i++) {
@@ -241,10 +241,10 @@ public class TestEventBusBase {
             }
             eventBus.post(new MyEvent("my-event", 11l, UUID.randomUUID(), BusEventType.ACCOUNT_CHANGE.toString()));
 
-            boolean completed = handler.waitForCompletion(10000);
+            final boolean completed = handler.waitForCompletion(10000);
             Assert.assertEquals(completed, true);
         } catch (Exception e) {
-            Assert.fail("",e);
+            Assert.fail("", e);
         }
 
     }
diff --git a/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java b/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java
index b42b694..1b58ce1 100644
--- a/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java
+++ b/util/src/test/java/com/ning/billing/util/bus/TestPersistentEventBus.java
@@ -15,13 +15,8 @@
  */
 package com.ning.billing.util.bus;
 
-
-import java.io.IOException;
-
-import org.apache.commons.io.IOUtils;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
-import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
@@ -36,13 +31,13 @@ import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.BusModule.BusType;
+import com.ning.billing.util.io.IOUtils;
 
 @Guice(modules = TestPersistentEventBus.PersistentBusModuleTest.class)
 public class TestPersistentEventBus extends TestEventBusBase {
-    
     @Inject
     private MysqlTestingHelper helper;
-    
+
     @BeforeClass(groups = {"slow"})
     public void setup() throws Exception {
         helper.startMysql();
@@ -51,18 +46,16 @@ public class TestPersistentEventBus extends TestEventBusBase {
         cleanup();
         super.setup();
     }
-    
+
     @BeforeMethod(groups = {"slow"})
     public void cleanup() {
         helper.cleanupTable("bus_events");
         helper.cleanupTable("claimed_bus_events");
     }
-    
-    public static class PersistentBusModuleTest extends AbstractModule {
 
+    public static class PersistentBusModuleTest extends AbstractModule {
         @Override
         protected void configure() {
-            
             //System.setProperty("com.ning.billing.dbi.test.useLocalDb", "true");
 
             bind(Clock.class).to(ClockMock.class).asEagerSingleton();
@@ -81,17 +74,17 @@ public class TestPersistentEventBus extends TestEventBusBase {
             install(new BusModule(BusType.PERSISTENT));
         }
     }
-    
+
     @Test(groups = {"slow"})
     public void testSimple() {
         super.testSimple();
     }
-    
+
     // Until Guava fixes exception handling, r13?
-    @Test(groups={"slow"}, enabled=false)
+    @Test(groups = {"slow"}, enabled = false)
     public void testSimpleWithException() {
         super.testSimpleWithException();
-        
+
     }
- 
+
 }
diff --git a/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java b/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java
index 13738c9..3ed0f8d 100644
--- a/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java
+++ b/util/src/test/java/com/ning/billing/util/callcontext/TestCallContext.java
@@ -18,21 +18,22 @@ package com.ning.billing.util.callcontext;
 
 import java.util.UUID;
 
-import com.ning.billing.util.clock.DefaultClock;
 import org.joda.time.DateTime;
 
+import com.ning.billing.util.clock.DefaultClock;
+
 public class TestCallContext implements CallContext {
-	
+
     private final String userName;
     private final DateTime updatedDate;
     private final DateTime createdDate;
     private final UUID userToken;
-    
-    public TestCallContext(String userName) {
-    	this(userName, new DefaultClock().getUTCNow(), new DefaultClock().getUTCNow());
+
+    public TestCallContext(final String userName) {
+        this(userName, new DefaultClock().getUTCNow(), new DefaultClock().getUTCNow());
     }
 
-    public TestCallContext(String userName, DateTime createdDate, DateTime updatedDate) {
+    public TestCallContext(final String userName, final DateTime createdDate, final DateTime updatedDate) {
         this.userName = userName;
         this.createdDate = createdDate;
         this.updatedDate = updatedDate;
@@ -74,8 +75,8 @@ public class TestCallContext implements CallContext {
         return updatedDate;
     }
 
-	@Override
-	public UUID getUserToken() {
-		return userToken;
-	}
+    @Override
+    public UUID getUserToken() {
+        return userToken;
+    }
 }
diff --git a/util/src/test/java/com/ning/billing/util/clock/ClockMock.java b/util/src/test/java/com/ning/billing/util/clock/ClockMock.java
index ab702cb..d8542e0 100644
--- a/util/src/test/java/com/ning/billing/util/clock/ClockMock.java
+++ b/util/src/test/java/com/ning/billing/util/clock/ClockMock.java
@@ -32,13 +32,13 @@ import com.ning.billing.catalog.api.Duration;
 import com.ning.billing.catalog.api.TimeUnit;
 
 public class ClockMock implements Clock {
-    
+
     private MutablePeriod delta = new MutablePeriod();
     private static final Logger log = LoggerFactory.getLogger(ClockMock.class);
 
-     
+
     @Override
-    public synchronized DateTime getNow(DateTimeZone tz) {
+    public synchronized DateTime getNow(final DateTimeZone tz) {
         return getUTCNow().toDateTime(tz);
     }
 
@@ -46,90 +46,92 @@ public class ClockMock implements Clock {
     public synchronized DateTime getUTCNow() {
         return truncate(adjust(now()));
     }
-    
-    private DateTime adjust(DateTime now) {
+
+    private DateTime adjust(final DateTime now) {
         return now.plus(delta);
     }
 
-    public synchronized void setTime(DateTime time) {
-        DateTime prev = getUTCNow();
+    public synchronized void setTime(final DateTime time) {
+        final DateTime prev = getUTCNow();
         delta = new MutablePeriod(now(), time);
         logChange(prev);
     }
-    
-    public synchronized void addDays(int days) {
+
+    public synchronized void addDays(final int days) {
         adjustTo(Days.days(days));
     }
-    
-    public synchronized void addWeeks(int weeks) {
+
+    public synchronized void addWeeks(final int weeks) {
         adjustTo(Weeks.weeks(weeks));
     }
-    
-    public synchronized void addMonths(int months) {
+
+    public synchronized void addMonths(final int months) {
         adjustTo(Months.months(months));
     }
-    
-    public synchronized void addYears(int years) {
+
+    public synchronized void addYears(final int years) {
         adjustTo(Years.years(years));
     }
-    
+
     public synchronized void reset() {
         delta = new MutablePeriod();
     }
-    
+
     @Override
     public String toString() {
         return getUTCNow().toString();
     }
-    
-    private void adjustTo(ReadablePeriod period) {
-        DateTime prev = getUTCNow();
+
+    private void adjustTo(final ReadablePeriod period) {
+        final DateTime prev = getUTCNow();
         delta.add(period);
         logChange(prev);
     }
-    
-    private void logChange(DateTime prev) {     
-        DateTime now = getUTCNow();
+
+    private void logChange(final DateTime prev) {
+        final DateTime now = getUTCNow();
         log.info(String.format("            ************      ADJUSTING CLOCK FROM %s to %s     ********************", prev, now));
     }
-    
+
     private DateTime now() {
         return new DateTime(DateTimeZone.UTC);
     }
 
-    private DateTime truncate(DateTime time) {
+    private DateTime truncate(final DateTime time) {
         return time.minus(time.getMillisOfSecond());
     }
-   
+
     //
     //Backward compatibility stuff
     //
-    public synchronized void setDeltaFromReality(Duration duration, long epsilon) {
-        DateTime prev = getUTCNow();
-        delta.addMillis((int)epsilon);
+    public synchronized void setDeltaFromReality(final Duration duration, final long epsilon) {
+        final DateTime prev = getUTCNow();
+        delta.addMillis((int) epsilon);
         addDeltaFromReality(duration);
         logChange(prev);
-        
+
     }
 
-    public synchronized void addDeltaFromReality(Duration delta) {
+    public synchronized void addDeltaFromReality(final Duration delta) {
         adjustTo(periodFromDuration(delta));
     }
 
-    public synchronized void setDeltaFromReality(long delta) {
+    public synchronized void setDeltaFromReality(final long delta) {
         adjustTo(new Period(delta));
     }
 
-    public synchronized void addDeltaFromReality(long delta) {
+    public synchronized void addDeltaFromReality(final long delta) {
         adjustTo(new Period(delta));
     }
 
     public synchronized void resetDeltaFromReality() {
         reset();
     }
-    
-    public ReadablePeriod periodFromDuration(Duration duration) {
-        if (duration.getUnit() != TimeUnit.UNLIMITED) {return new Period();}
+
+    public ReadablePeriod periodFromDuration(final Duration duration) {
+        if (duration.getUnit() != TimeUnit.UNLIMITED) {
+            return new Period();
+        }
 
         switch (duration.getUnit()) {
             case DAYS:
@@ -140,10 +142,10 @@ public class ClockMock implements Clock {
                 return Years.years(duration.getNumber());
             case UNLIMITED:
                 return Years.years(100);
-           default:
+            default:
                 return new Period();
         }
     }
-    
+
 
 }
diff --git a/util/src/test/java/com/ning/billing/util/clock/OldClockMock.java b/util/src/test/java/com/ning/billing/util/clock/OldClockMock.java
index b31db77..b032bed 100644
--- a/util/src/test/java/com/ning/billing/util/clock/OldClockMock.java
+++ b/util/src/test/java/com/ning/billing/util/clock/OldClockMock.java
@@ -16,14 +16,15 @@
 
 package com.ning.billing.util.clock;
 
-import com.ning.billing.catalog.api.Duration;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
-import java.util.List;
+import com.ning.billing.catalog.api.Duration;
 
 // STEPH should really be in tests but not accessible from other sub modules
 public class OldClockMock extends DefaultClock {
@@ -49,7 +50,7 @@ public class OldClockMock extends DefaultClock {
     }
 
     @Override
-    public synchronized DateTime getNow(DateTimeZone tz) {
+    public synchronized DateTime getNow(final DateTimeZone tz) {
         return adjust(super.getNow(tz));
     }
 
@@ -58,12 +59,12 @@ public class OldClockMock extends DefaultClock {
         return getNow(DateTimeZone.UTC);
     }
 
-    private void logClockAdjustment(DateTime prev, DateTime next) {
+    private void logClockAdjustment(final DateTime prev, final DateTime next) {
         log.info(String.format("            ************      ADJUSTING CLOCK FROM %s to %s     ********************", prev, next));
     }
 
-    public synchronized void setDeltaFromReality(Duration delta, long epsilon) {
-        DateTime prev = getUTCNow();
+    public synchronized void setDeltaFromReality(final Duration delta, final long epsilon) {
+        final DateTime prev = getUTCNow();
         deltaType = DeltaType.DELTA_DURATION;
         deltaFromRealityDuration = new ArrayList<Duration>();
         deltaFromRealityDuration.add(delta);
@@ -72,8 +73,8 @@ public class OldClockMock extends DefaultClock {
         logClockAdjustment(prev, getUTCNow());
     }
 
-    public synchronized void addDeltaFromReality(Duration delta) {
-        DateTime prev = getUTCNow();
+    public synchronized void addDeltaFromReality(final Duration delta) {
+        final DateTime prev = getUTCNow();
         if (deltaType != DeltaType.DELTA_DURATION) {
             throw new RuntimeException("ClockMock should be set with type DELTA_DURATION");
         }
@@ -81,8 +82,8 @@ public class OldClockMock extends DefaultClock {
         logClockAdjustment(prev, getUTCNow());
     }
 
-    public synchronized void setDeltaFromReality(long delta) {
-        DateTime prev = getUTCNow();
+    public synchronized void setDeltaFromReality(final long delta) {
+        final DateTime prev = getUTCNow();
         deltaType = DeltaType.DELTA_ABS;
         deltaFromRealityDuration = null;
         deltaFromRealityDurationEpsilon = 0;
@@ -90,8 +91,8 @@ public class OldClockMock extends DefaultClock {
         logClockAdjustment(prev, getUTCNow());
     }
 
-    public synchronized void addDeltaFromReality(long delta) {
-        DateTime prev = getUTCNow();
+    public synchronized void addDeltaFromReality(final long delta) {
+        final DateTime prev = getUTCNow();
         if (deltaType != DeltaType.DELTA_ABS) {
             throw new RuntimeException("ClockMock should be set with type DELTA_ABS");
         }
@@ -108,8 +109,8 @@ public class OldClockMock extends DefaultClock {
         deltaFromRealityMs = 0;
     }
 
-    private DateTime adjust(DateTime realNow) {
-        switch(deltaType) {
+    private DateTime adjust(final DateTime realNow) {
+        switch (deltaType) {
             case DELTA_NONE:
                 return realNow;
             case DELTA_ABS:
@@ -121,26 +122,26 @@ public class OldClockMock extends DefaultClock {
         }
     }
 
-    private DateTime adjustFromDuration(DateTime input) {
+    private DateTime adjustFromDuration(final DateTime input) {
 
         DateTime result = input;
-        for (Duration cur : deltaFromRealityDuration) {
+        for (final Duration cur : deltaFromRealityDuration) {
             switch (cur.getUnit()) {
-            case DAYS:
-                result = result.plusDays(cur.getNumber());
-                break;
+                case DAYS:
+                    result = result.plusDays(cur.getNumber());
+                    break;
 
-            case MONTHS:
-                result = result.plusMonths(cur.getNumber());
-                break;
+                case MONTHS:
+                    result = result.plusMonths(cur.getNumber());
+                    break;
 
-            case YEARS:
-                result = result.plusYears(cur.getNumber());
-                break;
+                case YEARS:
+                    result = result.plusYears(cur.getNumber());
+                    break;
 
-            case UNLIMITED:
-            default:
-                throw new RuntimeException("ClockMock is adjusting an unlimited time period");
+                case UNLIMITED:
+                default:
+                    throw new RuntimeException("ClockMock is adjusting an unlimited time period");
             }
         }
         if (deltaFromRealityDurationEpsilon != 0) {
@@ -149,7 +150,7 @@ public class OldClockMock extends DefaultClock {
         return result;
     }
 
-    private DateTime adjustFromAbsolute(DateTime input) {
+    private DateTime adjustFromAbsolute(final DateTime input) {
         return truncateMs(input.plus(deltaFromRealityMs));
     }
 
@@ -158,5 +159,5 @@ public class OldClockMock extends DefaultClock {
         return getUTCNow().toString();
     }
 
-    
+
 }
diff --git a/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java b/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java
index 6721ee8..96f7a06 100644
--- a/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java
+++ b/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.util.config;
 
-import com.ning.billing.catalog.api.InvalidConfigException;
-import org.testng.annotations.Test;
-import org.xml.sax.SAXException;
-
 import javax.xml.bind.JAXBException;
 import javax.xml.transform.TransformerException;
 import java.io.ByteArrayInputStream;
@@ -28,28 +24,30 @@ import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 
+import org.testng.annotations.Test;
+import org.xml.sax.SAXException;
+
+import com.ning.billing.catalog.api.InvalidConfigException;
+
 import static org.testng.Assert.assertEquals;
 
 
 public class TestXMLLoader {
-	public static final String TEST_XML = 
-			"<xmlTestClass>" +
-			"	<foo>foo</foo>" +
-			"	<bar>1.0</bar>" +
-			"	<lala>42</lala>" +
-			"</xmlTestClass>";
-	
-	@Test
-	public void test() throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, URISyntaxException, ValidationException {
-		InputStream is = new ByteArrayInputStream(TEST_XML.getBytes());
-		XmlTestClass test = XMLLoader.getObjectFromStream(new URI("internal:/"), is, XmlTestClass.class);
-		assertEquals(test.getFoo(), "foo");
-		assertEquals(test.getBar(),1.0);
-		assertEquals(test.getLala(), 42);
-	}
-	
-	
-	
-	
-	
+    public static final String TEST_XML =
+            "<xmlTestClass>" +
+                    "	<foo>foo</foo>" +
+                    "	<bar>1.0</bar>" +
+                    "	<lala>42</lala>" +
+                    "</xmlTestClass>";
+
+    @Test
+    public void test() throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, URISyntaxException, ValidationException {
+        final InputStream is = new ByteArrayInputStream(TEST_XML.getBytes());
+        final XmlTestClass test = XMLLoader.getObjectFromStream(new URI("internal:/"), is, XmlTestClass.class);
+        assertEquals(test.getFoo(), "foo");
+        assertEquals(test.getBar(), 1.0);
+        assertEquals(test.getLala(), 42);
+    }
+
+
 }
diff --git a/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java b/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java
index f863784..8eae647 100644
--- a/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java
+++ b/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java
@@ -16,25 +16,19 @@
 
 package com.ning.billing.util.config;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-
 import javax.xml.bind.JAXBException;
 import javax.xml.transform.TransformerException;
+import java.io.IOException;
+import java.io.InputStream;
 
-import org.apache.commons.io.IOUtils;
 import org.testng.annotations.Test;
 
+import com.ning.billing.util.io.IOUtils;
+
 public class TestXMLSchemaGenerator {
-	
-	@Test
-	public void test() throws IOException, TransformerException, JAXBException {
-		InputStream stream = XMLSchemaGenerator.xmlSchema(XmlTestClass.class);
-		StringWriter writer = new StringWriter();
-		IOUtils.copy(stream, writer);
-		String result = writer.toString();
-		
-		System.out.println(result);
-	}
+    @Test(groups = "fast", enabled = false)
+    public void test() throws IOException, TransformerException, JAXBException {
+        final InputStream stream = XMLSchemaGenerator.xmlSchema(XmlTestClass.class);
+        System.out.println(IOUtils.toString(stream));
+    }
 }
diff --git a/util/src/test/java/com/ning/billing/util/config/TestXMLWriter.java b/util/src/test/java/com/ning/billing/util/config/TestXMLWriter.java
index 007c16b..11878b9 100644
--- a/util/src/test/java/com/ning/billing/util/config/TestXMLWriter.java
+++ b/util/src/test/java/com/ning/billing/util/config/TestXMLWriter.java
@@ -16,38 +16,37 @@
 
 package com.ning.billing.util.config;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.net.URI;
 
 import org.testng.annotations.Test;
 
+import static org.testng.Assert.assertEquals;
+
 public class TestXMLWriter {
-	public static final String TEST_XML = 
-			"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
-		    "<xmlTestClass>" +
-			"<foo>foo</foo>" +
-			"<bar>1.0</bar>" +
-			"<lala>42</lala>" +
-			"</xmlTestClass>";
-	
-	@Test
-	public void test() throws Exception {
-		InputStream is = new ByteArrayInputStream(TEST_XML.getBytes());
-		XmlTestClass test = XMLLoader.getObjectFromStream(new URI("internal:/"), is, XmlTestClass.class);
-		assertEquals(test.getFoo(), "foo");
-		assertEquals(test.getBar(), 1.0);
-		assertEquals(test.getLala(), 42);
-		
-		String output = XMLWriter.writeXML(test, XmlTestClass.class);
-		
-		System.out.println(output);
-		assertEquals(output.replaceAll("\\s", ""), TEST_XML.replaceAll("\\s", ""));
-		 
-	}
-
-	
+    public static final String TEST_XML =
+            "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
+                    "<xmlTestClass>" +
+                    "<foo>foo</foo>" +
+                    "<bar>1.0</bar>" +
+                    "<lala>42</lala>" +
+                    "</xmlTestClass>";
+
+    @Test
+    public void test() throws Exception {
+        final InputStream is = new ByteArrayInputStream(TEST_XML.getBytes());
+        final XmlTestClass test = XMLLoader.getObjectFromStream(new URI("internal:/"), is, XmlTestClass.class);
+        assertEquals(test.getFoo(), "foo");
+        assertEquals(test.getBar(), 1.0);
+        assertEquals(test.getLala(), 42);
+
+        final String output = XMLWriter.writeXML(test, XmlTestClass.class);
+
+        System.out.println(output);
+        assertEquals(output.replaceAll("\\s", ""), TEST_XML.replaceAll("\\s", ""));
+
+    }
+
+
 }
diff --git a/util/src/test/java/com/ning/billing/util/config/XmlTestClass.java b/util/src/test/java/com/ning/billing/util/config/XmlTestClass.java
index baa8f3c..c39cb71 100644
--- a/util/src/test/java/com/ning/billing/util/config/XmlTestClass.java
+++ b/util/src/test/java/com/ning/billing/util/config/XmlTestClass.java
@@ -22,25 +22,25 @@ import javax.xml.bind.annotation.XmlRootElement;
 
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.FIELD)
-public class XmlTestClass extends ValidatingConfig<XmlTestClass>{
-	private String foo;
-	private Double bar;
-	private int lala;
-	
-	public String getFoo() {
-		return foo;
-	}
-	
-	public Double getBar() {
-		return bar;
-	}
-	
-	public int getLala() {
-		return lala;
-	}
-	
-	@Override
-	public ValidationErrors validate(XmlTestClass root, ValidationErrors errors) {
-		return errors;
-	}
-}
\ No newline at end of file
+public class XmlTestClass extends ValidatingConfig<XmlTestClass> {
+    private String foo;
+    private Double bar;
+    private int lala;
+
+    public String getFoo() {
+        return foo;
+    }
+
+    public Double getBar() {
+        return bar;
+    }
+
+    public int getLala() {
+        return lala;
+    }
+
+    @Override
+    public ValidationErrors validate(final XmlTestClass root, final ValidationErrors errors) {
+        return errors;
+    }
+}
diff --git a/util/src/test/java/com/ning/billing/util/customfield/dao/MockCustomFieldDao.java b/util/src/test/java/com/ning/billing/util/customfield/dao/MockCustomFieldDao.java
index 445f30f..0e46f0a 100644
--- a/util/src/test/java/com/ning/billing/util/customfield/dao/MockCustomFieldDao.java
+++ b/util/src/test/java/com/ning/billing/util/customfield/dao/MockCustomFieldDao.java
@@ -16,42 +16,43 @@
 
 package com.ning.billing.util.customfield.dao;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.customfield.CustomField;
-import com.ning.billing.util.dao.ObjectType;
-import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
-
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
+
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.dao.ObjectType;
+
 public class MockCustomFieldDao implements CustomFieldDao {
     private final Map<UUID, List<CustomField>> fields = new HashMap<UUID, List<CustomField>>();
 
     @Override
-    public void saveEntitiesFromTransaction(Transmogrifier transactionalDao, UUID objectId, ObjectType objectType, List<CustomField> entities, CallContext context) {
+    public void saveEntitiesFromTransaction(final Transmogrifier transactionalDao, final UUID objectId, final ObjectType objectType, final List<CustomField> entities, final CallContext context) {
         fields.put(objectId, entities);
     }
 
     @Override
-    public void saveEntities(UUID objectId, ObjectType objectType, List<CustomField> entities, CallContext context) {
+    public void saveEntities(final UUID objectId, final ObjectType objectType, final List<CustomField> entities, final CallContext context) {
         fields.put(objectId, entities);
     }
 
     @Override
-    public Map<String, CustomField> loadEntities(UUID objectId, ObjectType objectType) {
+    public Map<String, CustomField> loadEntities(final UUID objectId, final ObjectType objectType) {
         return getMap(fields.get(objectId));
     }
 
     @Override
-    public Map<String, CustomField> loadEntitiesFromTransaction(Transmogrifier dao, UUID objectId, ObjectType objectType) {
+    public Map<String, CustomField> loadEntitiesFromTransaction(final Transmogrifier dao, final UUID objectId, final ObjectType objectType) {
         return getMap(fields.get(objectId));
     }
 
-    private Map<String, CustomField> getMap(List<CustomField> customFields) {
-        Map<String, CustomField> map = new HashMap<String, CustomField>();
-        for (CustomField customField : customFields) {
+    private Map<String, CustomField> getMap(final List<CustomField> customFields) {
+        final Map<String, CustomField> map = new HashMap<String, CustomField>();
+        for (final CustomField customField : customFields) {
             map.put(customField.getName(), customField);
         }
         return map;
diff --git a/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java b/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
index 7a31ab8..e5caad4 100644
--- a/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
+++ b/util/src/test/java/com/ning/billing/util/customfield/TestFieldStore.java
@@ -19,23 +19,24 @@ package com.ning.billing.util.customfield;
 import java.io.IOException;
 import java.util.UUID;
 
-import com.ning.billing.util.callcontext.CallContext;
-import com.ning.billing.util.callcontext.CallOrigin;
-import com.ning.billing.util.callcontext.UserType;
-import com.ning.billing.util.callcontext.DefaultCallContextFactory;
-import com.ning.billing.util.clock.ClockMock;
-import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
-import com.ning.billing.util.customfield.dao.CustomFieldDao;
-import com.ning.billing.util.dao.ObjectType;
-import org.apache.commons.io.IOUtils;
 import org.skife.jdbi.v2.IDBI;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
+
 import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContextFactory;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
+import com.ning.billing.util.customfield.dao.CustomFieldDao;
 import com.ning.billing.util.customfield.dao.CustomFieldSqlDao;
+import com.ning.billing.util.dao.ObjectType;
+import com.ning.billing.util.io.IOUtils;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
@@ -60,17 +61,15 @@ public class TestFieldStore {
             dbi = helper.getDBI();
             customFieldDao = new AuditedCustomFieldDao(dbi);
             context = new DefaultCallContextFactory(new ClockMock()).createCallContext("Fezzik", CallOrigin.TEST, UserType.TEST);
-        }
-        catch (Throwable t) {
+        } catch (Throwable t) {
             log.error("Setup failed", t);
             fail(t.toString());
         }
     }
 
     @AfterClass(groups = {"util", "slow"})
-    public void stopMysql()
-    {
-        if (helper!= null) {
+    public void stopMysql() {
+        if (helper != null) {
             helper.stopMysql();
         }
     }
@@ -82,11 +81,11 @@ public class TestFieldStore {
 
         final FieldStore fieldStore1 = new DefaultFieldStore(id, objectType);
 
-        String fieldName = "TestField1";
+        final String fieldName = "TestField1";
         String fieldValue = "Kitty Hawk";
         fieldStore1.setValue(fieldName, fieldValue);
 
-        CustomFieldSqlDao customFieldSqlDao = dbi.onDemand(CustomFieldSqlDao.class);
+        final CustomFieldSqlDao customFieldSqlDao = dbi.onDemand(CustomFieldSqlDao.class);
         customFieldDao.saveEntitiesFromTransaction(customFieldSqlDao, id, objectType, fieldStore1.getEntityList(), context);
 
         final FieldStore fieldStore2 = DefaultFieldStore.create(id, objectType);
diff --git a/util/src/test/java/com/ning/billing/util/email/DefaultCatalogTranslationTest.java b/util/src/test/java/com/ning/billing/util/email/DefaultCatalogTranslationTest.java
index a42829f..d092a5a 100644
--- a/util/src/test/java/com/ning/billing/util/email/DefaultCatalogTranslationTest.java
+++ b/util/src/test/java/com/ning/billing/util/email/DefaultCatalogTranslationTest.java
@@ -14,14 +14,18 @@ package com.ning.billing.util.email;/*
  * under the License.
  */
 
-import com.ning.billing.util.template.translation.DefaultCatalogTranslator;
-import com.ning.billing.util.template.translation.Translator;
-import com.ning.billing.util.template.translation.TranslatorConfig;
+import java.util.Locale;
+import java.util.Map;
+
+import org.skife.config.ConfigSource;
 import org.skife.config.ConfigurationObjectFactory;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import java.util.Locale;
+import com.google.common.collect.ImmutableMap;
+import com.ning.billing.util.template.translation.DefaultCatalogTranslator;
+import com.ning.billing.util.template.translation.Translator;
+import com.ning.billing.util.template.translation.TranslatorConfig;
 
 import static org.testng.Assert.assertEquals;
 
@@ -29,17 +33,27 @@ import static org.testng.Assert.assertEquals;
 public class DefaultCatalogTranslationTest {
     private Translator translation;
 
-    @BeforeClass(groups={"fast", "email"})
+    @BeforeClass(groups = {"fast", "email"})
     public void setup() {
-        final TranslatorConfig config = new ConfigurationObjectFactory(System.getProperties()).build(TranslatorConfig.class);
+        final ConfigSource configSource = new ConfigSource() {
+            private final Map<String, String> properties = ImmutableMap.<String, String>of("killbill.template.invoiceFormatterFactoryClass",
+                                                                                           "com.ning.billing.mock.MockInvoiceFormatterFactory");
+
+            @Override
+            public String getString(final String propertyName) {
+                return properties.get(propertyName);
+            }
+        };
+
+        final TranslatorConfig config = new ConfigurationObjectFactory(configSource).build(TranslatorConfig.class);
         translation = new DefaultCatalogTranslator(config);
     }
 
     @Test(groups = {"fast", "email"}, enabled = false)
     public void testInitialization() {
-        String ningPlusText = "ning-plus";
-        String ningProText = "ning-pro";
-        String badText = "Bad text";
+        final String ningPlusText = "ning-plus";
+        final String ningProText = "ning-pro";
+        final String badText = "Bad text";
 
         assertEquals(translation.getTranslation(Locale.US, ningPlusText), "Plus");
         assertEquals(translation.getTranslation(Locale.US, ningProText), "Pro");
@@ -57,28 +71,28 @@ public class DefaultCatalogTranslationTest {
     @Test(enabled = false)
     public void testExistingTranslation() {
         // if the translation exists, return the translation
-        String originalText = "ning-plus";
-        assertEquals(translation.getTranslation(Locale.US,  originalText), "Plus");
+        final String originalText = "ning-plus";
+        assertEquals(translation.getTranslation(Locale.US, originalText), "Plus");
     }
 
     @Test
     public void testMissingTranslation() {
         // if the translation is missing from the file, return the original text
-        String originalText = "missing translation";
+        final String originalText = "missing translation";
         assertEquals(translation.getTranslation(Locale.US, originalText), originalText);
     }
 
     @Test(enabled = false)
     public void testMissingTranslationFileWithEnglishText() {
         // if the translation file doesn't exist, return the "English" translation
-        String originalText = "ning-plus";
+        final String originalText = "ning-plus";
         assertEquals(translation.getTranslation(Locale.CHINA, originalText), "Plus");
     }
 
     @Test
     public void testMissingFileAndText() {
         // if the file is missing, and the "English" translation is missing, return the original text
-        String originalText = "missing translation";
+        final String originalText = "missing translation";
         assertEquals(translation.getTranslation(Locale.CHINA, originalText), originalText);
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/email/EmailSenderTest.java b/util/src/test/java/com/ning/billing/util/email/EmailSenderTest.java
index 1685628..b3e4d64 100644
--- a/util/src/test/java/com/ning/billing/util/email/EmailSenderTest.java
+++ b/util/src/test/java/com/ning/billing/util/email/EmailSenderTest.java
@@ -14,13 +14,13 @@ package com.ning.billing.util.email;/*
  * under the License.
  */
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.skife.config.ConfigurationObjectFactory;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import java.util.ArrayList;
-import java.util.List;
-
 @Test(groups = {"slow", "email"})
 public class EmailSenderTest {
     private EmailConfig config;
@@ -30,13 +30,13 @@ public class EmailSenderTest {
         config = new ConfigurationObjectFactory(System.getProperties()).build(EmailConfig.class);
     }
 
-    @Test
+    @Test(enabled = false)
     public void testSendEmail() throws Exception {
-        String html = "<html><body><h1>Test E-mail</h1></body></html>";
-        List<String> recipients = new ArrayList<String>();
+        final String html = "<html><body><h1>Test E-mail</h1></body></html>";
+        final List<String> recipients = new ArrayList<String>();
         recipients.add("killbill.ning@gmail.com");
 
-        EmailSender sender = new DefaultEmailSender(config);
+        final EmailSender sender = new DefaultEmailSender(config);
         sender.sendSecureEmail(recipients, null, "Test message", html);
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/globallocker/MockGlobalLocker.java b/util/src/test/java/com/ning/billing/util/globallocker/MockGlobalLocker.java
index b1f3378..4a1ff01 100644
--- a/util/src/test/java/com/ning/billing/util/globallocker/MockGlobalLocker.java
+++ b/util/src/test/java/com/ning/billing/util/globallocker/MockGlobalLocker.java
@@ -16,14 +16,11 @@
 
 package com.ning.billing.util.globallocker;
 
-import com.ning.billing.util.globallocker.GlobalLock;
-import com.ning.billing.util.globallocker.GlobalLocker;
-
 public class MockGlobalLocker implements GlobalLocker {
 
     @Override
-    public GlobalLock lockWithNumberOfTries(LockerService service,
-            String lockKey, int retry) {
+    public GlobalLock lockWithNumberOfTries(final LockerService service,
+                                            final String lockKey, final int retry) {
         return new GlobalLock() {
             @Override
             public void release() {
@@ -32,7 +29,7 @@ public class MockGlobalLocker implements GlobalLocker {
     }
 
     @Override
-    public Boolean isFree(LockerService service, String lockKey) {
+    public Boolean isFree(final LockerService service, final String lockKey) {
         return Boolean.TRUE;
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java b/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java
index be642f8..4619b42 100644
--- a/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java
+++ b/util/src/test/java/com/ning/billing/util/globallocker/TestMysqlGlobalLocker.java
@@ -19,7 +19,6 @@ package com.ning.billing.util.globallocker;
 import java.io.IOException;
 import java.util.UUID;
 
-import org.apache.commons.io.IOUtils;
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.TransactionCallback;
@@ -33,14 +32,11 @@ import org.testng.annotations.Test;
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
 import com.ning.billing.dbi.MysqlTestingHelper;
-import com.ning.billing.util.globallocker.GlobalLock;
-import com.ning.billing.util.globallocker.GlobalLocker;
-import com.ning.billing.util.globallocker.LockFailedException;
-import com.ning.billing.util.globallocker.MySqlGlobalLocker;
 import com.ning.billing.util.globallocker.GlobalLocker.LockerService;
+import com.ning.billing.util.io.IOUtils;
 
 @Test(groups = "slow")
-@Guice(modules=TestMysqlGlobalLocker.TestMysqlGlobalLockerModule.class)
+@Guice(modules = TestMysqlGlobalLocker.TestMysqlGlobalLockerModule.class)
 public class TestMysqlGlobalLocker {
 
     @Inject
@@ -50,7 +46,7 @@ public class TestMysqlGlobalLocker {
     private MysqlTestingHelper helper;
 
     @BeforeClass(groups = "slow")
-    public void setup() throws IOException  {
+    public void setup() throws IOException {
         final String testDdl = IOUtils.toString(TestMysqlGlobalLocker.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
         helper.startMysql();
         helper.initDb(testDdl);
@@ -64,19 +60,19 @@ public class TestMysqlGlobalLocker {
     }
 
     // Used as a manual test to validate the simple DAO by stepping through that locking is done and release correctly
-    @Test(groups= "slow", enabled = true)
+    @Test(groups = "slow", enabled = true)
     public void testSimpleLocking() {
 
         final String lockName = UUID.randomUUID().toString();
 
-        GlobalLocker locker = new MySqlGlobalLocker(dbi);
-        GlobalLock lock = locker.lockWithNumberOfTries(LockerService.INVOICE, lockName, 3);
+        final GlobalLocker locker = new MySqlGlobalLocker(dbi);
+        final GlobalLock lock = locker.lockWithNumberOfTries(LockerService.INVOICE, lockName, 3);
 
         dbi.inTransaction(new TransactionCallback<Void>() {
             @Override
-            public Void inTransaction(Handle conn, TransactionStatus status)
+            public Void inTransaction(final Handle conn, final TransactionStatus status)
                     throws Exception {
-                conn.execute("insert into dummy2 (dummy_id) values ('" + UUID.randomUUID().toString()  + "')");
+                conn.execute("insert into dummy2 (dummy_id) values ('" + UUID.randomUUID().toString() + "')");
                 return null;
             }
         });
@@ -95,11 +91,11 @@ public class TestMysqlGlobalLocker {
         Assert.assertEquals(locker.isFree(LockerService.INVOICE, lockName), Boolean.TRUE);
     }
 
-    public final static class TestMysqlGlobalLockerModule extends AbstractModule {
+    public static final class TestMysqlGlobalLockerModule extends AbstractModule {
 
         @Override
         protected void configure() {
-            MysqlTestingHelper helper = new MysqlTestingHelper();
+            final MysqlTestingHelper helper = new MysqlTestingHelper();
             bind(MysqlTestingHelper.class).toInstance(helper);
             final IDBI dbi = helper.getDBI();
             bind(IDBI.class).toInstance(dbi);
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java b/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java
index 7c61363..d7141d3 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/dao/TestNotificationSqlDao.java
@@ -21,7 +21,6 @@ import java.sql.SQLException;
 import java.util.List;
 import java.util.UUID;
 
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.Handle;
@@ -33,9 +32,11 @@ import org.testng.annotations.BeforeSuite;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
+
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
 import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.notificationq.DefaultNotification;
 import com.ning.billing.util.notificationq.Notification;
 import com.ning.billing.util.notificationq.dao.NotificationSqlDao.NotificationSqlMapper;
@@ -47,9 +48,8 @@ import static org.testng.Assert.assertNotNull;
 @Test(groups = "slow")
 @Guice(modules = TestNotificationSqlDao.TestNotificationSqlDaoModule.class)
 public class TestNotificationSqlDao {
+    private static final String hostname = "Yop";
 
-    private final static String hostname = "Yop";
-    
     @Inject
     private IDBI dbi;
 
@@ -65,7 +65,7 @@ public class TestNotificationSqlDao {
     }
 
     @BeforeSuite(groups = "slow")
-    public void setup()  {
+    public void setup() {
         try {
             startMysql();
             dao = dbi.onDemand(NotificationSqlDao.class);
@@ -75,8 +75,7 @@ public class TestNotificationSqlDao {
     }
 
     @AfterSuite(groups = "slow")
-    public void stopMysql()
-    {
+    public void stopMysql() {
         if (helper != null) {
             helper.stopMysql();
         }
@@ -88,7 +87,7 @@ public class TestNotificationSqlDao {
         dbi.withHandle(new HandleCallback<Void>() {
 
             @Override
-            public Void withHandle(Handle handle) throws Exception {
+            public Void withHandle(final Handle handle) throws Exception {
                 handle.execute("delete from notifications");
                 handle.execute("delete from claimed_notifications");
                 return null;
@@ -101,14 +100,14 @@ public class TestNotificationSqlDao {
 
         final String ownerId = UUID.randomUUID().toString();
 
-        String notificationKey = UUID.randomUUID().toString();
-        DateTime effDt = new DateTime();
-        Notification notif = new DefaultNotification("testBasic", hostname, notificationKey, effDt);
+        final String notificationKey = UUID.randomUUID().toString();
+        final DateTime effDt = new DateTime();
+        final Notification notif = new DefaultNotification("testBasic", hostname, notificationKey.getClass().getName(), notificationKey, effDt);
         dao.insertNotification(notif);
 
         Thread.sleep(1000);
-        DateTime now = new DateTime();
-        List<Notification> notifications = dao.getReadyNotifications(now.toDate(), hostname, 3, "testBasic");
+        final DateTime now = new DateTime();
+        final List<Notification> notifications = dao.getReadyNotifications(now.toDate(), hostname, 3, "testBasic");
         assertNotNull(notifications);
         assertEquals(notifications.size(), 1);
 
@@ -119,8 +118,8 @@ public class TestNotificationSqlDao {
         assertEquals(notification.getProcessingState(), PersistentQueueEntryLifecycleState.AVAILABLE);
         assertEquals(notification.getNextAvailableDate(), null);
 
-        DateTime nextAvailable = now.plusMinutes(5);
-        int res = dao.claimNotification(ownerId, nextAvailable.toDate(), notification.getId().toString(), now.toDate());
+        final DateTime nextAvailable = now.plusMinutes(5);
+        final int res = dao.claimNotification(ownerId, nextAvailable.toDate(), notification.getId().toString(), now.toDate());
         assertEquals(res, 1);
         dao.insertClaimedHistory(ownerId, now.toDate(), notification.getId().toString());
 
@@ -143,26 +142,27 @@ public class TestNotificationSqlDao {
     }
 
     private Notification fetchNotification(final String notificationId) {
-        Notification res =  dbi.withHandle(new HandleCallback<Notification>() {
+        final Notification res = dbi.withHandle(new HandleCallback<Notification>() {
 
             @Override
-            public Notification withHandle(Handle handle) throws Exception {
-                Notification res = handle.createQuery("   select" +
-                        " record_id " +
-                		", id" +
-                		", notification_key" +
-                		", created_date" +
-                		", creating_owner" +
-                		", effective_date" +
-                		", queue_name" +
-                		", processing_owner" +
-                		", processing_available_date" +
-                		", processing_state" +
-                		"    from notifications " +
-                		" where " +
-                		" id = '" + notificationId + "';")
-                		.map(new NotificationSqlMapper())
-                		.first();
+            public Notification withHandle(final Handle handle) throws Exception {
+                final Notification res = handle.createQuery("   select" +
+                                                                    " record_id " +
+                                                                    ", id" +
+                                                                    ", class_name" +                                                                    
+                                                                    ", notification_key" +
+                                                                    ", created_date" +
+                                                                    ", creating_owner" +
+                                                                    ", effective_date" +
+                                                                    ", queue_name" +
+                                                                    ", processing_owner" +
+                                                                    ", processing_available_date" +
+                                                                    ", processing_state" +
+                                                                    "    from notifications " +
+                                                                    " where " +
+                                                                    " id = '" + notificationId + "';")
+                                               .map(new NotificationSqlMapper())
+                                               .first();
                 return res;
             }
         });
@@ -181,11 +181,11 @@ public class TestNotificationSqlDao {
         Assert.assertEquals(input, expected);
     }
 
-    private DateTime truncateAndUTC(DateTime input) {
+    private DateTime truncateAndUTC(final DateTime input) {
         if (input == null) {
             return null;
         }
-        DateTime result = input.minus(input.getMillisOfSecond());
+        final DateTime result = input.minus(input.getMillisOfSecond());
         return result.toDateTime(DateTimeZone.UTC);
     }
 
@@ -195,7 +195,7 @@ public class TestNotificationSqlDao {
 
             final MysqlTestingHelper helper = new MysqlTestingHelper();
             bind(MysqlTestingHelper.class).toInstance(helper);
-            IDBI dbi = helper.getDBI();
+            final IDBI dbi = helper.getDBI();
             bind(IDBI.class).toInstance(dbi);
         }
     }
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/DummyObject.java b/util/src/test/java/com/ning/billing/util/notificationq/DummyObject.java
index 9495001..0e1f60d 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/DummyObject.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/DummyObject.java
@@ -22,7 +22,7 @@ public class DummyObject {
     private final String value;
     private final UUID key;
 
-    public DummyObject(String value, UUID key) {
+    public DummyObject(final String value, final UUID key) {
         super();
         this.value = value;
         this.key = key;
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/DummySqlTest.java b/util/src/test/java/com/ning/billing/util/notificationq/DummySqlTest.java
index 83b1b20..12d71c9 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/DummySqlTest.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/DummySqlTest.java
@@ -46,15 +46,15 @@ public interface DummySqlTest extends Transactional<DummySqlTest>, Transmogrifie
 
     public static class DummySqlTestBinder implements Binder<Bind, DummyObject> {
         @Override
-        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, DummyObject dummy) {
+        public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final DummyObject dummy) {
             stmt.bind("dummy_id", dummy.getKey().toString());
             stmt.bind("value", dummy.getValue());
         }
     }
 
-    public static class DummySqlTestMapper  implements ResultSetMapper<DummyObject> {
+    public static class DummySqlTestMapper implements ResultSetMapper<DummyObject> {
         @Override
-        public DummyObject map(int index, ResultSet r, StatementContext ctx)
+        public DummyObject map(final int index, final ResultSet r, final StatementContext ctx)
                 throws SQLException {
             final UUID key = UUID.fromString(r.getString("dummy_id"));
             final String value = r.getString("value");
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
index fb1bfe7..5e7d607 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueue.java
@@ -16,16 +16,17 @@
 
 package com.ning.billing.util.notificationq;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.TreeSet;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.ning.billing.config.NotificationConfig;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
@@ -34,11 +35,13 @@ import com.ning.billing.util.queue.PersistentQueueEntryLifecycle.PersistentQueue
 public class MockNotificationQueue extends NotificationQueueBase implements NotificationQueue {
     private final TreeSet<Notification> notifications;
 
-    public MockNotificationQueue(final Clock clock,  final String svcName, final String queueName, final NotificationQueueHandler handler, final NotificationConfig config) {
+    ObjectMapper objectMapper = new ObjectMapper();
+    
+    public MockNotificationQueue(final Clock clock, final String svcName, final String queueName, final NotificationQueueHandler handler, final NotificationConfig config) {
         super(clock, svcName, queueName, handler, config);
         notifications = new TreeSet<Notification>(new Comparator<Notification>() {
             @Override
-            public int compare(Notification o1, Notification o2) {
+            public int compare(final Notification o1, final Notification o2) {
                 if (o1.getEffectiveDate().equals(o2.getEffectiveDate())) {
                     return o1.getNotificationKey().compareTo(o2.getNotificationKey());
                 } else {
@@ -49,24 +52,25 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
     }
 
     @Override
-    public void recordFutureNotification(DateTime futureNotificationTime, NotificationKey notificationKey) {
-        Notification notification = new DefaultNotification("MockQueue", hostname, notificationKey.toString(), futureNotificationTime);
-        synchronized(notifications) {
+    public void recordFutureNotification(final DateTime futureNotificationTime, final NotificationKey notificationKey) throws IOException  {
+        final String json = objectMapper.writeValueAsString(notificationKey);
+        final Notification notification = new DefaultNotification("MockQueue", hostname, notificationKey.getClass().getName(), json, futureNotificationTime);
+        synchronized (notifications) {
             notifications.add(notification);
         }
     }
 
     @Override
     public void recordFutureNotificationFromTransaction(
-            Transmogrifier transactionalDao, DateTime futureNotificationTime,
-            NotificationKey notificationKey) {
+            final Transmogrifier transactionalDao, final DateTime futureNotificationTime,
+            final NotificationKey notificationKey) throws IOException  {
         recordFutureNotification(futureNotificationTime, notificationKey);
     }
 
     public List<Notification> getPendingEvents() {
-        List<Notification> result = new ArrayList<Notification>();
+        final List<Notification> result = new ArrayList<Notification>();
 
-        for (Notification notification : notifications) {
+        for (final Notification notification : notifications) {
             if (notification.getProcessingState() == PersistentQueueEntryLifecycleState.AVAILABLE) {
                 result.add(notification);
             }
@@ -79,14 +83,14 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
 
         int result = 0;
 
-        List<Notification> processedNotifications = new ArrayList<Notification>();
-        List<Notification> oldNotifications = new ArrayList<Notification>();
+        final List<Notification> processedNotifications = new ArrayList<Notification>();
+        final List<Notification> oldNotifications = new ArrayList<Notification>();
 
-        List<Notification> readyNotifications = new ArrayList<Notification>();
-        synchronized(notifications) {
-            Iterator<Notification> it = notifications.iterator();
+        final List<Notification> readyNotifications = new ArrayList<Notification>();
+        synchronized (notifications) {
+            final Iterator<Notification> it = notifications.iterator();
             while (it.hasNext()) {
-                Notification cur = it.next();
+                final Notification cur = it.next();
                 if (cur.isAvailableForProcessing(clock.getUTCNow())) {
                     readyNotifications.add(cur);
                 }
@@ -94,13 +98,17 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
         }
 
         result = readyNotifications.size();
-        for (Notification cur : readyNotifications) {
-            handler.handleReadyNotification(cur.getNotificationKey(), cur.getEffectiveDate());
-            DefaultNotification processedNotification = new DefaultNotification(-1L, cur.getId(), hostname, hostname, "MockQueue", clock.getUTCNow().plus(CLAIM_TIME_MS), PersistentQueueEntryLifecycleState.PROCESSED, cur.getNotificationKey(), cur.getEffectiveDate());
+        for (final Notification cur : readyNotifications) {
+            
+            
+            NotificationKey key = deserializeEvent(cur.getNotificationKeyClass(), cur.getNotificationKey()); 
+            handler.handleReadyNotification(key, cur.getEffectiveDate());
+            final DefaultNotification processedNotification = new DefaultNotification(-1L, cur.getId(), hostname, hostname, "MockQueue", clock.getUTCNow().plus(CLAIM_TIME_MS), PersistentQueueEntryLifecycleState.PROCESSED,
+                    cur.getNotificationKeyClass(), cur.getNotificationKey(), cur.getEffectiveDate());
             oldNotifications.add(cur);
             processedNotifications.add(processedNotification);
         }
-        synchronized(notifications) {
+        synchronized (notifications) {
             if (oldNotifications.size() > 0) {
                 notifications.removeAll(oldNotifications);
             }
@@ -113,18 +121,18 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
     }
 
     @Override
-    public void removeNotificationsByKey(NotificationKey key) {
-        List<Notification> toClearNotifications = new ArrayList<Notification>();
-        for (Notification notification : notifications) {
+    public void removeNotificationsByKey(final NotificationKey key) {
+        final List<Notification> toClearNotifications = new ArrayList<Notification>();
+        for (final Notification notification : notifications) {
             if (notification.getNotificationKey().equals(key.toString())) {
-                    toClearNotifications.add(notification);
+                toClearNotifications.add(notification);
             }
         }
-        synchronized(notifications) {
+        synchronized (notifications) {
             if (toClearNotifications.size() > 0) {
                 notifications.removeAll(toClearNotifications);
             }
         }
-        
+
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueueService.java b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueueService.java
index 9af43c1..5cedbe3 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueueService.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/MockNotificationQueueService.java
@@ -28,9 +28,9 @@ public class MockNotificationQueueService extends NotificationQueueServiceBase {
     }
 
     @Override
-    protected NotificationQueue createNotificationQueueInternal(String svcName,
-            String queueName, NotificationQueueHandler handler,
-            NotificationConfig config) {
+    protected NotificationQueue createNotificationQueueInternal(final String svcName,
+                                                                final String queueName, final NotificationQueueHandler handler,
+                                                                final NotificationConfig config) {
         return new MockNotificationQueue(clock, svcName, queueName, handler, config);
     }
 }
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
index 5adac12..11db32e 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.util.notificationq;
 
-import static com.jayway.awaitility.Awaitility.await;
-import static java.util.concurrent.TimeUnit.MINUTES;
-import static org.testng.Assert.assertEquals;
-
 import java.io.IOException;
 import java.sql.SQLException;
 import java.util.Collection;
@@ -29,7 +25,6 @@ import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
@@ -45,6 +40,8 @@ import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.inject.AbstractModule;
@@ -54,9 +51,14 @@ import com.ning.billing.config.NotificationConfig;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
 import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
 
+import static com.jayway.awaitility.Awaitility.await;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static org.testng.Assert.assertEquals;
+
 @Test(groups = "slow")
 @Guice(modules = TestNotificationQueue.TestNotificationQueueModule.class)
 public class TestNotificationQueue {
@@ -84,25 +86,47 @@ public class TestNotificationQueue {
         helper.initDb(testDdl);
     }
 
-    @BeforeSuite(groups="slow")
+    
+    private final static class TestNotificationKey implements NotificationKey, Comparable<TestNotificationKey> {
+        
+        private final String value;
+
+        @JsonCreator
+        public TestNotificationKey(@JsonProperty("value") String value) {
+            super();
+            this.value = value;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        @Override
+        public int compareTo(TestNotificationKey arg0) {
+            return value.compareTo(arg0.value);
+        }
+    }
+    
+    
+    @BeforeSuite(groups = "slow")
     public void setup() throws Exception {
         startMysql();
         dao = dbi.onDemand(DummySqlTest.class);
     }
 
-    @AfterClass(groups="slow")
+    @AfterClass(groups = "slow")
     public void tearDown() {
         if (helper != null) {
             helper.stopMysql();
         }
     }
 
-    @BeforeTest(groups="slow")
+    @BeforeTest(groups = "slow")
     public void beforeTest() {
         dbi.withHandle(new HandleCallback<Void>() {
 
             @Override
-            public Void withHandle(Handle handle) throws Exception {
+            public Void withHandle(final Handle handle) throws Exception {
                 handle.execute("delete from notifications");
                 handle.execute("delete from claimed_notifications");
                 handle.execute("delete from dummy");
@@ -111,25 +135,25 @@ public class TestNotificationQueue {
         });
         // Reset time to real value
         ((ClockMock) clock).resetDeltaFromReality();
-        eventsReceived=0;
+        eventsReceived = 0;
     }
 
 
-
     /**
      * Test that we can post a notification in the future from a transaction and get the notification
      * callback with the correct key when the time is ready
+     *
      * @throws Exception
      */
-    @Test(groups={"slow"}, enabled = true)
+    @Test(groups = {"slow"}, enabled = true)
     public void testSimpleNotification() throws Exception {
 
-        final Map<String, Boolean> expectedNotifications = new TreeMap<String, Boolean>();
+        final Map<NotificationKey, Boolean> expectedNotifications = new TreeMap<NotificationKey, Boolean>();
 
         final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "foo",
                 new NotificationQueueHandler() {
             @Override
-            public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
+            public void handleReadyNotification(final NotificationKey notificationKey, final DateTime eventDateTime) {
                 synchronized (expectedNotifications) {
                     log.info("Handler received key: " + notificationKey);
 
@@ -147,20 +171,16 @@ public class TestNotificationQueue {
         final DummyObject obj = new DummyObject("foo", key);
         final DateTime now = new DateTime();
         final DateTime readyTime = now.plusMillis(2000);
-        final NotificationKey notificationKey = new NotificationKey() {
-            @Override
-            public String toString() {
-                return key.toString();
-            }
-        };
-        expectedNotifications.put(notificationKey.toString(), Boolean.FALSE);
+        final NotificationKey notificationKey = new TestNotificationKey(key.toString());
+
+        expectedNotifications.put(notificationKey, Boolean.FALSE);
 
 
         // Insert dummy to be processed in 2 sec'
         dao.inTransaction(new Transaction<Void, DummySqlTest>() {
             @Override
-            public Void inTransaction(DummySqlTest transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final DummySqlTest transactional,
+                    final TransactionStatus status) throws Exception {
 
                 transactional.insertDummy(obj);
                 queue.recordFutureNotificationFromTransaction(transactional,
@@ -178,22 +198,22 @@ public class TestNotificationQueue {
         await().atMost(1, MINUTES).until(new Callable<Boolean>() {
             @Override
             public Boolean call() throws Exception {
-                return expectedNotifications.get(notificationKey.toString());
+                return expectedNotifications.get(notificationKey);
             }
         });
 
         queue.stopQueue();
-	    Assert.assertTrue(expectedNotifications.get(notificationKey.toString()));
-	}
+        Assert.assertTrue(expectedNotifications.get(notificationKey));
+    }
 
-    @Test(groups="slow")
+    @Test(groups = "slow")
     public void testManyNotifications() throws InterruptedException {
-        final Map<String, Boolean> expectedNotifications = new TreeMap<String, Boolean>();
+        final Map<NotificationKey, Boolean> expectedNotifications = new TreeMap<NotificationKey, Boolean>();
 
         final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "many",
                 new NotificationQueueHandler() {
             @Override
-            public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
+            public void handleReadyNotification(final NotificationKey notificationKey, final DateTime eventDateTime) {
                 synchronized (expectedNotifications) {
                     expectedNotifications.put(notificationKey, Boolean.TRUE);
                     expectedNotifications.notify();
@@ -215,18 +235,13 @@ public class TestNotificationQueue {
             final DummyObject obj = new DummyObject("foo", key);
             final int currentIteration = i;
 
-            final NotificationKey notificationKey = new NotificationKey() {
-                @Override
-                public String toString() {
-                    return key.toString();
-                }
-            };
-            expectedNotifications.put(notificationKey.toString(), Boolean.FALSE);
+            final NotificationKey notificationKey = new TestNotificationKey(key.toString());
+            expectedNotifications.put(notificationKey, Boolean.FALSE);
 
             dao.inTransaction(new Transaction<Void, DummySqlTest>() {
                 @Override
-                public Void inTransaction(DummySqlTest transactional,
-                        TransactionStatus status) throws Exception {
+                public Void inTransaction(final DummySqlTest transactional,
+                        final TransactionStatus status) throws Exception {
 
                     transactional.insertDummy(obj);
                     queue.recordFutureNotificationFromTransaction(transactional,
@@ -247,46 +262,54 @@ public class TestNotificationQueue {
         int nbTry = MAX_NOTIFICATIONS + 1;
         boolean success = false;
         do {
-            synchronized(expectedNotifications) {
+            synchronized (expectedNotifications) {
 
-                Collection<Boolean> completed =  Collections2.filter(expectedNotifications.values(), new Predicate<Boolean>() {
+                final Collection<Boolean> completed = Collections2.filter(expectedNotifications.values(), new Predicate<Boolean>() {
                     @Override
-                    public boolean apply(Boolean input) {
+                    public boolean apply(final Boolean input) {
                         return input;
                     }
                 });
 
-				if (completed.size() == MAX_NOTIFICATIONS) {
-					success = true;
-					break;
-				}
-				//log.debug(String.format("BEFORE WAIT : Got %d notifications at time %s (real time %s)", completed.size(), clock.getUTCNow(), new DateTime()));
-				expectedNotifications.wait(1000);
-			}
-		} while (nbTry-- > 0);
+                if (completed.size() == MAX_NOTIFICATIONS) {
+                    success = true;
+                    break;
+                }
+                //log.debug(String.format("BEFORE WAIT : Got %d notifications at time %s (real time %s)", completed.size(), clock.getUTCNow(), new DateTime()));
+                expectedNotifications.wait(1000);
+            }
+        } while (nbTry-- > 0);
 
         queue.stopQueue();
-		assertEquals(success, true);
-	}
+        log.info("STEPH GOT SIZE " +  Collections2.filter(expectedNotifications.values(), new Predicate<Boolean>() {
+            @Override
+            public boolean apply(final Boolean input) {
+                return input;
+            }
+        }).size());
+        assertEquals(success, true);
+    }
 
     /**
      * Test that we can post a notification in the future from a transaction and get the notification
      * callback with the correct key when the time is ready
+     *
      * @throws Exception
      */
-    @Test(groups={"slow"}, enabled = true)
+    @Test(groups = {"slow"}, enabled = true)
     public void testMultipleHandlerNotification() throws Exception {
 
-        final Map<String, Boolean> expectedNotificationsFred = new TreeMap<String, Boolean>();
-        final Map<String, Boolean> expectedNotificationsBarney = new TreeMap<String, Boolean>();
+        final Map<NotificationKey, Boolean> expectedNotificationsFred = new TreeMap<NotificationKey, Boolean>();
+        final Map<NotificationKey, Boolean> expectedNotificationsBarney = new TreeMap<NotificationKey, Boolean>();
 
-        NotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi,  clock);
+        final NotificationQueueService notificationQueueService = new DefaultNotificationQueueService(dbi, clock);
 
-        NotificationConfig config=new NotificationConfig() {
+        final NotificationConfig config = new NotificationConfig() {
             @Override
             public boolean isNotificationProcessingOff() {
                 return false;
             }
+
             @Override
             public long getSleepTimeMs() {
                 return 10;
@@ -296,7 +319,7 @@ public class TestNotificationQueue {
 
         final NotificationQueue queueFred = notificationQueueService.createNotificationQueue("UtilTest", "Fred", new NotificationQueueHandler() {
             @Override
-            public void handleReadyNotification(String notificationKey, DateTime eventDateTime)  {
+            public void handleReadyNotification(final NotificationKey notificationKey, final DateTime eventDateTime) {
                 log.info("Fred received key: " + notificationKey);
                 expectedNotificationsFred.put(notificationKey, Boolean.TRUE);
                 eventsReceived++;
@@ -306,7 +329,7 @@ public class TestNotificationQueue {
 
         final NotificationQueue queueBarney = notificationQueueService.createNotificationQueue("UtilTest", "Barney", new NotificationQueueHandler() {
             @Override
-            public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
+            public void handleReadyNotification(final NotificationKey notificationKey, final DateTime eventDateTime) {
                 log.info("Barney received key: " + notificationKey);
                 expectedNotificationsBarney.put(notificationKey, Boolean.TRUE);
                 eventsReceived++;
@@ -322,30 +345,20 @@ public class TestNotificationQueue {
         final DummyObject obj = new DummyObject("foo", key);
         final DateTime now = new DateTime();
         final DateTime readyTime = now.plusMillis(2000);
-        final NotificationKey notificationKeyFred = new NotificationKey() {
-            @Override
-            public String toString() {
-                return "Fred" ;
-            }
-        };
+        final NotificationKey notificationKeyFred = new TestNotificationKey("Fred");
 
 
-        final NotificationKey notificationKeyBarney = new NotificationKey() {
-            @Override
-            public String toString() {
-                return "Barney" ;
-            }
-        };
+        final NotificationKey notificationKeyBarney = new TestNotificationKey("Barney"); 
 
-        expectedNotificationsFred.put(notificationKeyFred.toString(), Boolean.FALSE);
-        expectedNotificationsFred.put(notificationKeyBarney.toString(), Boolean.FALSE);
+        expectedNotificationsFred.put(notificationKeyFred, Boolean.FALSE);
+        expectedNotificationsFred.put(notificationKeyBarney, Boolean.FALSE);
 
 
         // Insert dummy to be processed in 2 sec'
         dao.inTransaction(new Transaction<Void, DummySqlTest>() {
             @Override
-            public Void inTransaction(DummySqlTest transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final DummySqlTest transactional,
+                    final TransactionStatus status) throws Exception {
 
                 transactional.insertDummy(obj);
                 queueFred.recordFutureNotificationFromTransaction(transactional,
@@ -377,9 +390,9 @@ public class TestNotificationQueue {
         }
 
         queueFred.stopQueue();
-		Assert.assertTrue(expectedNotificationsFred.get(notificationKeyFred.toString()));
-		Assert.assertFalse(expectedNotificationsFred.get(notificationKeyBarney.toString()));
-	}
+        Assert.assertTrue(expectedNotificationsFred.get(notificationKeyFred));
+        Assert.assertFalse(expectedNotificationsFred.get(notificationKeyBarney));
+    }
 
     NotificationConfig getNotificationConfig(final boolean off,
             final long sleepTime, final int maxReadyEvents, final long claimTimeMs) {
@@ -388,40 +401,31 @@ public class TestNotificationQueue {
             public boolean isNotificationProcessingOff() {
                 return off;
             }
+
             @Override
             public long getSleepTimeMs() {
                 return sleepTime;
             }
         };
     }
-    
-    
-    @Test(groups="slow")
+
+
+    @Test(groups = "slow")
     public void testRemoveNotifications() throws InterruptedException {
-        
+
         final UUID key = UUID.randomUUID();
-        final NotificationKey notificationKey = new NotificationKey() {
-            @Override
-            public String toString() {
-                return key.toString();
-            }
-        };        
+        final NotificationKey notificationKey = new TestNotificationKey(key.toString());
         final UUID key2 = UUID.randomUUID();
-        final NotificationKey notificationKey2 = new NotificationKey() {
-            @Override
-            public String toString() {
-                return key2.toString();
-            }
-        };        
+        final NotificationKey notificationKey2 = new TestNotificationKey(key2.toString());
 
         final DefaultNotificationQueue queue = new DefaultNotificationQueue(dbi, clock, "test-svc", "many",
                 new NotificationQueueHandler() {
             @Override
-            public void handleReadyNotification(String key, DateTime eventDateTime) {
-                    if(key.equals(notificationKey) || key.equals(notificationKey2)) { //ignore stray events from other tests
-                        log.info("Received notification with key: " + notificationKey);
-                        eventsReceived++;
-                    }
+            public void handleReadyNotification(final NotificationKey inputKey, final DateTime eventDateTime) {
+                if (inputKey.equals(notificationKey) || inputKey.equals(notificationKey2)) { //ignore stray events from other tests
+                    log.info("Received notification with key: " + notificationKey);
+                    eventsReceived++;
+                }
             }
         },
         getNotificationConfig(false, 100, 10, 10000));
@@ -431,30 +435,30 @@ public class TestNotificationQueue {
 
         final DateTime start = clock.getUTCNow().plusHours(1);
         final int nextReadyTimeIncrementMs = 1000;
- 
+
         // add 3 events
 
         dao.inTransaction(new Transaction<Void, DummySqlTest>() {
             @Override
-            public Void inTransaction(DummySqlTest transactional,
-                    TransactionStatus status) throws Exception {
+            public Void inTransaction(final DummySqlTest transactional,
+                    final TransactionStatus status) throws Exception {
 
                 queue.recordFutureNotificationFromTransaction(transactional,
                         start.plus(nextReadyTimeIncrementMs), notificationKey);
                 queue.recordFutureNotificationFromTransaction(transactional,
-                        start.plus(2 *nextReadyTimeIncrementMs), notificationKey);
+                        start.plus(2 * nextReadyTimeIncrementMs), notificationKey);
                 queue.recordFutureNotificationFromTransaction(transactional,
                         start.plus(3 * nextReadyTimeIncrementMs), notificationKey2);
                 return null;
             }
         });
-    
-    
-      queue.removeNotificationsByKey(notificationKey); // should remove 2 of the 3
 
-    // Move time in the future after the notification effectiveDate
-        ((ClockMock) clock).setDeltaFromReality(4000000 + nextReadyTimeIncrementMs * 3 );
-        
+
+        queue.removeNotificationsByKey(notificationKey); // should remove 2 of the 3
+
+        // Move time in the future after the notification effectiveDate
+        ((ClockMock) clock).setDeltaFromReality(4000000 + nextReadyTimeIncrementMs * 3);
+
         try {
             await().atMost(10, TimeUnit.SECONDS).until(new Callable<Boolean>() {
                 @Override
@@ -471,7 +475,6 @@ public class TestNotificationQueue {
     }
 
 
-
     public static class TestNotificationQueueModule extends AbstractModule {
         @Override
         protected void configure() {
@@ -480,9 +483,9 @@ public class TestNotificationQueue {
 
             final MysqlTestingHelper helper = new MysqlTestingHelper();
             bind(MysqlTestingHelper.class).toInstance(helper);
-            IDBI dbi = helper.getDBI();
+            final IDBI dbi = helper.getDBI();
             bind(IDBI.class).toInstance(dbi);
-            IDBI otherDbi = helper.getDBI();
+            final IDBI otherDbi = helper.getDBI();
             bind(IDBI.class).annotatedWith(Names.named("global-lock")).toInstance(otherDbi);
             /*
             bind(DBI.class).toProvider(DBIProvider.class).asEagerSingleton();
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/TestAuditedTagDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/TestAuditedTagDao.java
index e986950..2bb6a37 100644
--- a/util/src/test/java/com/ning/billing/util/tag/dao/TestAuditedTagDao.java
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/TestAuditedTagDao.java
@@ -22,7 +22,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-import org.apache.commons.io.IOUtils;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -41,6 +40,7 @@ import com.ning.billing.util.callcontext.DefaultCallContextFactory;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.dao.ObjectType;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.tag.MockTagStoreModuleSql;
 import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.TagDefinition;
diff --git a/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java b/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java
index cc74c55..c895b67 100644
--- a/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java
+++ b/util/src/test/java/com/ning/billing/util/tag/dao/TestDefaultTagDefinitionDao.java
@@ -21,7 +21,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-import org.apache.commons.io.IOUtils;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -39,6 +38,7 @@ import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.DefaultCallContextFactory;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.tag.MockTagStoreModuleSql;
 import com.ning.billing.util.tag.TagDefinition;
 import com.ning.billing.util.tag.TestTagStore;
diff --git a/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
index 69187ae..a5016a7 100644
--- a/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
+++ b/util/src/test/java/com/ning/billing/util/tag/TestTagStore.java
@@ -22,7 +22,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.joda.time.Seconds;
 import org.skife.jdbi.v2.Handle;
@@ -46,6 +45,7 @@ import com.ning.billing.util.callcontext.DefaultCallContextFactory;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.dao.ObjectType;
+import com.ning.billing.util.io.IOUtils;
 import com.ning.billing.util.tag.dao.TagDao;
 import com.ning.billing.util.tag.dao.TagDefinitionDao;
 
diff --git a/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java b/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java
index 4e845db..204abdb 100644
--- a/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java
+++ b/util/src/test/java/com/ning/billing/util/validation/TestValidationManager.java
@@ -16,19 +16,19 @@
 
 package com.ning.billing.util.validation;
 
-import com.ning.billing.dbi.MysqlTestingHelper;
-import com.ning.billing.util.globallocker.TestMysqlGlobalLocker;
-import com.ning.billing.util.validation.dao.DatabaseSchemaDao;
+import java.io.IOException;
+import java.util.Collection;
 
-import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.IDBI;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import java.io.IOException;
-import java.util.Collection;
+import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.util.globallocker.TestMysqlGlobalLocker;
+import com.ning.billing.util.io.IOUtils;
+import com.ning.billing.util.validation.dao.DatabaseSchemaDao;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
@@ -41,7 +41,7 @@ public class TestValidationManager {
     private static final String TABLE_NAME = "validation_test";
 
     private ValidationManager vm;
-    
+
     @BeforeClass(groups = "slow")
     public void setup() throws IOException {
         setupDatabase();
@@ -49,8 +49,8 @@ public class TestValidationManager {
     }
 
     private void setupDao() {
-        IDBI dbi = helper.getDBI();
-        DatabaseSchemaDao dao = new DatabaseSchemaDao(dbi);
+        final IDBI dbi = helper.getDBI();
+        final DatabaseSchemaDao dao = new DatabaseSchemaDao(dbi);
         vm = new ValidationManager(dao);
         vm.loadSchemaInformation(helper.getDbName());
     }
@@ -74,12 +74,12 @@ public class TestValidationManager {
 
     @Test(groups = "slow")
     public void testRetrievingColumnInfo() {
-        Collection<ColumnInfo> columnInfoList = vm.getTableInfo(TABLE_NAME);
+        final Collection<ColumnInfo> columnInfoList = vm.getTableInfo(TABLE_NAME);
         assertEquals(columnInfoList.size(), 4);
         assertNotNull(vm.getColumnInfo(TABLE_NAME, "column1"));
         assertNull(vm.getColumnInfo(TABLE_NAME, "bogus"));
 
-        ColumnInfo numericColumnInfo = vm.getColumnInfo(TABLE_NAME, "column3");
+        final ColumnInfo numericColumnInfo = vm.getColumnInfo(TABLE_NAME, "column3");
         assertNotNull(numericColumnInfo);
         assertEquals(numericColumnInfo.getScale(), 4);
         assertEquals(numericColumnInfo.getPrecision(), 10);
@@ -87,17 +87,17 @@ public class TestValidationManager {
 
     @Test(groups = "slow")
     public void testSimpleConfiguration() {
-        String STRING_FIELD_2 = "column2";
-        String STRING_FIELD_2_PROPERTY = "stringField2";
+        final String STRING_FIELD_2 = "column2";
+        final String STRING_FIELD_2_PROPERTY = "stringField2";
 
-        SimpleTestClass testObject = new SimpleTestClass(null, null, 7.9, new DateTime());
+        final SimpleTestClass testObject = new SimpleTestClass(null, null, 7.9, new DateTime());
 
         vm.setConfiguration(testObject.getClass(), STRING_FIELD_2_PROPERTY, vm.getColumnInfo(TABLE_NAME, STRING_FIELD_2));
 
         assertTrue(vm.hasConfiguration(testObject.getClass()));
         assertFalse(vm.hasConfiguration(ValidationManager.class));
 
-        ValidationConfiguration configuration = vm.getConfiguration(SimpleTestClass.class);
+        final ValidationConfiguration configuration = vm.getConfiguration(SimpleTestClass.class);
         assertNotNull(configuration);
         assertTrue(configuration.hasMapping(STRING_FIELD_2_PROPERTY));
 
@@ -160,7 +160,7 @@ public class TestValidationManager {
         private double numericField1;
         private DateTime dateTimeField1;
 
-        public SimpleTestClass(String stringField1, String stringField2, double numericField1, DateTime dateTimeField1) {
+        public SimpleTestClass(final String stringField1, final String stringField2, final double numericField1, final DateTime dateTimeField1) {
             this.stringField1 = stringField1;
             this.stringField2 = stringField2;
             this.numericField1 = numericField1;
@@ -171,7 +171,7 @@ public class TestValidationManager {
             return stringField1;
         }
 
-        public void setStringField1(String stringField1) {
+        public void setStringField1(final String stringField1) {
             this.stringField1 = stringField1;
         }
 
@@ -179,7 +179,7 @@ public class TestValidationManager {
             return stringField2;
         }
 
-        public void setStringField2(String stringField2) {
+        public void setStringField2(final String stringField2) {
             this.stringField2 = stringField2;
         }
 
@@ -187,7 +187,7 @@ public class TestValidationManager {
             return numericField1;
         }
 
-        public void setNumericField1(double numericField1) {
+        public void setNumericField1(final double numericField1) {
             this.numericField1 = numericField1;
         }
 
@@ -195,7 +195,7 @@ public class TestValidationManager {
             return dateTimeField1;
         }
 
-        public void setDateTimeField1(DateTime dateTimeField1) {
+        public void setDateTimeField1(final DateTime dateTimeField1) {
             this.dateTimeField1 = dateTimeField1;
         }
     }