killbill-aplcache

Merge branch 'integration' of github.com:ning/killbill

3/20/2012 5:13:05 PM

Changes

account/pom.xml 2(+1 -1)

api/pom.xml 2(+1 -1)

beatrix/pom.xml 7(+1 -6)

catalog/pom.xml 2(+1 -1)

invoice/pom.xml 2(+1 -1)

payment/pom.xml 2(+1 -1)

pom.xml 71(+46 -25)

util/pom.xml 12(+1 -11)

Details

account/pom.xml 2(+1 -1)

diff --git a/account/pom.xml b/account/pom.xml
index 230e8f9..28c7a7a 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.7-SNAPSHOT</version>
+        <version>0.1.8-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-account</artifactId>
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 4ce9587..fb0d005 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
@@ -29,14 +29,17 @@ import com.ning.billing.account.api.MigrationAccountData;
 import com.ning.billing.account.dao.AccountDao;
 import com.ning.billing.util.CallContext;
 import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.entity.CallContextFactory;
 import com.ning.billing.util.entity.EntityPersistenceException;
 import com.ning.billing.util.tag.Tag;
 
 public class DefaultAccountUserApi implements com.ning.billing.account.api.AccountUserApi {
+    private final CallContextFactory factory;
     private final AccountDao dao;
 
     @Inject
-    public DefaultAccountUserApi(final AccountDao dao) {
+    public DefaultAccountUserApi(final CallContextFactory factory, final AccountDao dao) {
+        this.factory = factory;
         this.dao = dao;
     }
 
@@ -111,13 +114,13 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
 	public Account migrateAccount(final MigrationAccountData data, final List<CustomField> fields,
                                   final List<Tag> tags, final CallContext context)
             throws AccountApiException {
-		
+        CallContext migrationContext = factory.toMigrationCallContext(context, data.getCreatedDate(), data.getUpdatedDate());
 		Account account = new DefaultAccount(data);
         account.setFields(fields);
         account.addTags(tags);
 
         try {
-            dao.create(account, context);
+            dao.create(account, migrationContext);
         } catch (EntityPersistenceException e) {
             throw new AccountApiException(e, ErrorCode.ACCOUNT_CREATION_FAILED);
         }
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 d62d84c..97d1860 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
@@ -24,7 +24,7 @@ import com.ning.billing.util.CallContext;
 import com.ning.billing.util.CallOrigin;
 import com.ning.billing.util.UserType;
 import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.entity.DefaultCallContext;
+import com.ning.billing.util.entity.CallContextFactory;
 import org.apache.commons.io.IOUtils;
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
@@ -67,7 +67,7 @@ public abstract class AccountDaoTestBase {
             accountDao.test();
 
             Clock clock = injector.getInstance(Clock.class);
-            context = new DefaultCallContext(clock, "Vizzini", CallOrigin.TEST, UserType.TEST);
+            context = new CallContextFactory(clock).createCallContext("Vizzini", CallOrigin.TEST, UserType.TEST);
 
 
             BusService busService = injector.getInstance(BusService.class);
diff --git a/analytics/pom.xml b/analytics/pom.xml
index ad46c31..8a655ca 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.7-SNAPSHOT</version>
+        <version>0.1.8-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-analytics</artifactId>
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 3924858..2a9b8f3 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
@@ -29,12 +29,13 @@ import java.util.UUID;
 import com.ning.billing.util.CallContext;
 import com.ning.billing.util.CallOrigin;
 import com.ning.billing.util.UserType;
-import com.ning.billing.util.entity.DefaultCallContext;
+import com.ning.billing.util.entity.CallContextFactory;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
@@ -98,7 +99,7 @@ public class TestAnalyticsService {
     private static final String CARD_COUNTRY = "France";
 
     private final Clock clock = new DefaultClock();
-    private final CallContext context = new DefaultCallContext(clock, "Analytics Test", CallOrigin.TEST, UserType.TEST);
+    private final CallContext context = new CallContextFactory(clock).createCallContext("Analytics Test", CallOrigin.TEST, UserType.TEST);
 
     @Inject
     private AccountUserApi accountApi;
@@ -137,6 +138,15 @@ public class TestAnalyticsService {
     private InvoiceCreationNotification invoiceCreationNotification;
     private PaymentInfo paymentInfoNotification;
 
+    @BeforeMethod
+    public void cleanup() throws Exception
+    {
+        helper.cleanupTable("bst");
+        helper.cleanupTable("bac");
+
+    }
+
+
     @BeforeClass(alwaysRun = true)
     public void startMysql() throws IOException, ClassNotFoundException, SQLException, EntitlementUserApiException {
         // Killbill generic setup
@@ -179,6 +189,9 @@ public class TestAnalyticsService {
         helper.initDb(invoiceDdl);
         helper.initDb(paymentDdl);
         helper.initDb(utilDdl);
+
+        helper.cleanupTable("tag_definitions");
+        helper.cleanupTable("accounts");
     }
 
     private void createSubscriptionTransitionEvent(final Account account) throws EntitlementUserApiException {
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 a9a5422..e31d562 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
@@ -128,6 +128,7 @@ public class TestAnalyticsDao
     public void cleanup() throws Exception
     {
         helper.cleanupTable("bst");
+        helper.cleanupTable("bac");
     }
 
     @Test(groups = "slow")
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 dc2dbdf..dc338d2 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
@@ -127,17 +127,6 @@ public class MockSubscription implements Subscription
     }
 
     @Override
-    public List<SubscriptionTransition> getActiveTransitions() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-
-    public List<SubscriptionTransition> getAllTransitions() {
-        throw new UnsupportedOperationException();
-     }
-
-    @Override
     public SubscriptionTransition getPendingTransition() {
         throw new UnsupportedOperationException();
     }

api/pom.xml 2(+1 -1)

diff --git a/api/pom.xml b/api/pom.xml
index 75e229b..de14404 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.7-SNAPSHOT</version>
+        <version>0.1.8-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-api</artifactId>
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
new file mode 100644
index 0000000..a6f4e91
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/catalog/api/MigrationPlan.java
@@ -0,0 +1,22 @@
+/*
+ * 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.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__";
+}
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 9498c6f..826860b 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
@@ -38,6 +38,7 @@ public interface EntitlementMigrationApi {
 
     public interface EntitlementSubscriptionMigration {
         public ProductCategory getCategory();
+        public DateTime getChargedThroughDate();
         public EntitlementSubscriptionMigrationCase [] getSubscriptionCases();
     }
 
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 a9ce2c7..83d0b68 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
@@ -68,10 +68,6 @@ public interface Subscription extends CustomizableEntity {
 
     public ProductCategory getCategory();
 
-    public List<SubscriptionTransition> getActiveTransitions();
-
-    public List<SubscriptionTransition> getAllTransitions();
-
     public SubscriptionTransition getPendingTransition();
 
     public SubscriptionTransition getPreviousTransition();
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransition.java b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransition.java
index 43f96c6..80b836a 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransition.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransition.java
@@ -29,6 +29,7 @@ public interface SubscriptionTransition extends BusEvent {
     public enum SubscriptionTransitionType {
         MIGRATE_ENTITLEMENT,
         CREATE,
+        MIGRATE_BILLING,
         CHANGE,
         RE_CREATE,
         CANCEL,
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 bb93d8b..406160e 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
@@ -31,7 +31,7 @@ public interface Invoice extends Entity {
 
     List<InvoiceItem> getInvoiceItems();
 
-    List<InvoiceItem> getInvoiceItems(Class clazz);
+    public <T extends InvoiceItem> List<InvoiceItem> getInvoiceItems(Class<T> clazz);
 
     int getNumberOfItems();
 
@@ -62,4 +62,6 @@ public interface Invoice extends Entity {
     BigDecimal getBalance();
 
     boolean isDueForPayment(DateTime targetDate, int numberOfDays);
+
+	boolean isMigrationInvoice();
 }
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
new file mode 100644
index 0000000..8e17007
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceMigrationApi.java
@@ -0,0 +1,40 @@
+/*
+ * 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.invoice.api;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+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);
+
+}
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 641afa6..84292c4 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
@@ -26,7 +26,11 @@ import com.ning.billing.catalog.api.Currency;
 
 public interface InvoicePaymentApi {
 
-    public List<Invoice> getInvoicesByAccount(UUID accountId);
+    /**
+     * @param accountId
+     * @return All invoices, including migrated invoices
+     */
+    public List<Invoice> getAllInvoicesByAccount(UUID accountId);
 
     public Invoice getInvoice(UUID invoiceId);
 
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 08d649f..a66aa4e 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
@@ -25,8 +25,6 @@ import java.util.List;
 import java.util.UUID;
 
 public interface InvoiceUserApi {
-    public List<UUID> getInvoicesForPayment(DateTime targetDate, int numberOfDays);
-
     public List<Invoice> getInvoicesByAccount(UUID accountId);
 
     public List<Invoice> getInvoicesByAccount(UUID accountId, DateTime fromDate);
diff --git a/api/src/main/java/com/ning/billing/util/api/TagDefinitionUserApi.java b/api/src/main/java/com/ning/billing/util/api/TagDefinitionUserApi.java
index 3c462ed..f7e3a7d 100644
--- a/api/src/main/java/com/ning/billing/util/api/TagDefinitionUserApi.java
+++ b/api/src/main/java/com/ning/billing/util/api/TagDefinitionUserApi.java
@@ -53,4 +53,13 @@ public interface TagDefinitionUserApi {
      * @throws TagDefinitionApiException
      */
     public void deleteTagDefinition(String definitionName, CallContext context) throws TagDefinitionApiException;
+
+    
+	/**
+	 * 
+	 * @param name
+	 * @return the tag with this definition
+     * @throws TagDefinitionApiException
+	 */
+	public TagDefinition getTagDefinition(String name) throws TagDefinitionApiException;
 }
diff --git a/api/src/main/java/com/ning/billing/util/CallContext.java b/api/src/main/java/com/ning/billing/util/CallContext.java
index a76581d..eab2ef4 100644
--- a/api/src/main/java/com/ning/billing/util/CallContext.java
+++ b/api/src/main/java/com/ning/billing/util/CallContext.java
@@ -6,5 +6,6 @@ public interface CallContext {
     public String getUserName();
     public CallOrigin getCallOrigin();
     public UserType getUserType();
-    public DateTime getUTCNow();
+    public DateTime getCreatedDate();
+    public DateTime getUpdatedDate();
 }
diff --git a/api/src/main/java/com/ning/billing/util/tag/ControlTag.java b/api/src/main/java/com/ning/billing/util/tag/ControlTag.java
index a933cff..3ae9eb5 100644
--- a/api/src/main/java/com/ning/billing/util/tag/ControlTag.java
+++ b/api/src/main/java/com/ning/billing/util/tag/ControlTag.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.util.tag;
 
-import com.ning.billing.account.api.ControlTagType;
 
 public interface ControlTag extends Tag {
     public ControlTagType getControlTagType();
diff --git a/api/src/main/java/com/ning/billing/util/UserType.java b/api/src/main/java/com/ning/billing/util/UserType.java
index 5bc1175..0b44276 100644
--- a/api/src/main/java/com/ning/billing/util/UserType.java
+++ b/api/src/main/java/com/ning/billing/util/UserType.java
@@ -4,5 +4,6 @@ public enum UserType {
     SYSTEM,
     ADMIN,
     CUSTOMER,
+    MIGRATION,
     TEST
 }

beatrix/pom.xml 7(+1 -6)

diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index b7c7d4c..032ae4a 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.7-SNAPSHOT</version>
+        <version>0.1.8-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-beatrix</artifactId>
@@ -83,11 +83,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management</artifactId>
-            <version>5.0.11</version>
-        </dependency>
-        <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
             <scope>test</scope>
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 ba70513..8afaa93 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
@@ -36,6 +36,7 @@ import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.util.CallContext;
 import com.ning.billing.util.CallOrigin;
 import com.ning.billing.util.UserType;
+import com.ning.billing.util.entity.CallContextFactory;
 import com.ning.billing.util.entity.DefaultCallContext;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.RandomStringUtils;
@@ -98,7 +99,7 @@ public class TestIntegration {
 
     @Inject
     private ClockMock clock;
-    private final CallContext context = new DefaultCallContext(clock, "Integration Test", CallOrigin.TEST, UserType.TEST);
+    private final CallContext context = new CallContextFactory(clock).createCallContext("Integration Test", CallOrigin.TEST, UserType.TEST);
 
     @Inject
     private Lifecycle lifecycle;
@@ -173,6 +174,7 @@ public class TestIntegration {
         lifecycle.fireShutdownSequencePriorEventUnRegistration();
         busService.getBus().unregister(busHandler);
         lifecycle.fireShutdownSequencePostEventUnRegistration();
+        helper.stopMysql();
     }
 
 

catalog/pom.xml 2(+1 -1)

diff --git a/catalog/pom.xml b/catalog/pom.xml
index 9c7a5a0..bf0d550 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.7-SNAPSHOT</version>
+        <version>0.1.8-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-catalog</artifactId>
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 5523e12..0f021c3 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultPlanPhase.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultPlanPhase.java
@@ -16,6 +16,13 @@
 
 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 com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.CatalogApiException;
@@ -28,12 +35,6 @@ 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;
-import javax.xml.bind.annotation.XmlElement;
-import java.net.URI;
-
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultPlanPhase extends ValidatingConfig<StandaloneCatalog> implements PlanPhase {
 
@@ -59,8 +60,8 @@ public class DefaultPlanPhase extends ValidatingConfig<StandaloneCatalog> implem
 	//Not exposed in XML
 	private Plan plan;
 	
-	public static String phaseName(Plan plan, PlanPhase phase) {
-		return plan.getName() + "-" + phase.getPhaseType().toString().toLowerCase();
+	public static String phaseName(String planName, PhaseType phasetype) {
+		return planName + "-" + phasetype.toString().toLowerCase();
 	}
 	
 	public static String planName(String phaseName) throws CatalogApiException {
@@ -110,7 +111,7 @@ public class DefaultPlanPhase extends ValidatingConfig<StandaloneCatalog> implem
 	 */
 	@Override
 	public String getName() {
-		return phaseName(plan,this);
+		return phaseName(plan.getName(),this.getPhaseType());
 	}
 
 	/* (non-Javadoc)
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 b7f7b79..029cdcd 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/StandaloneCatalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/StandaloneCatalog.java
@@ -17,6 +17,7 @@
 package com.ning.billing.catalog;
 
 import java.net.URI;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Date;
 
@@ -254,6 +255,7 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
 		for(DefaultPlan p : plans) {
 			p.initialize(catalog, sourceURI);
 		}
+		
 	}
 
 
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 092a863..244ca49 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
@@ -16,24 +16,21 @@
 
 package com.ning.billing.catalog;
 
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.catalog.api.ProductCategory;
+import java.util.Date;
+
 import com.ning.billing.catalog.rules.CaseCancelPolicy;
 import com.ning.billing.catalog.rules.CaseChangePlanAlignment;
 import com.ning.billing.catalog.rules.CaseChangePlanPolicy;
 import com.ning.billing.catalog.rules.CaseCreateAlignment;
 import com.ning.billing.catalog.rules.PlanRules;
 
-import java.util.Date;
-
 public class MockCatalog extends StandaloneCatalog {
 	private static final String[] PRODUCT_NAMES = new String[]{ "TestProduct1", "TestProduct2", "TestProduct3"};
 	
 	public MockCatalog() {
 		setEffectiveDate(new Date());
 		setProducts(MockProduct.createAll());
-		setPlans(MockPlan.createAll());
+		setPlans((DefaultPlan[])MockPlan.createAll());
 		populateRules();
 		populatePriceLists();
 	}
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 58483c4..deececb 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockPlan.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockPlan.java
@@ -117,7 +117,7 @@ public class MockPlan extends DefaultPlan {
 
 
 	public static DefaultPlan[] createAll() {
-		return new MockPlan[]{
+		return new DefaultPlan[]{
 				createBicycleTrialEvergreen1USD(),
 				createBicycleNoTrialEvergreen1USD(),
 				createPickupTrialEvergreen10USD(),
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 c14a157..2772fc4 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
@@ -71,7 +71,7 @@ public class TestInternationalPrice {
 	  Assert.assertEquals(c.getCurrentPlans()[0].getFinalPhase().getRecurringPrice().getPrice(Currency.GBP), new BigDecimal(0));
   }
   
-  @Test
+   @Test
   public void testNegativeValuePrices(){
 	  StandaloneCatalog c = new MockCatalog();
 	  c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
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 a3b825d..e25ac82 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
@@ -60,10 +60,10 @@ public class TestPlanPhase {
 		DefaultPlanPhase ppEvergreen = MockPlanPhase.create1USDMonthlyEvergreen().setPhaseType(PhaseType.EVERGREEN).setPlan(p);
 		DefaultPlanPhase ppFixedterm = MockPlanPhase.create1USDMonthlyEvergreen().setPhaseType(PhaseType.FIXEDTERM).setPlan(p);
 		
-		String ppnDiscount = DefaultPlanPhase.phaseName(p, ppDiscount);
-		String ppnTrial = DefaultPlanPhase.phaseName(p, ppTrial);
-		String ppnEvergreen = DefaultPlanPhase.phaseName(p, ppEvergreen);
-		String ppnFixedterm = DefaultPlanPhase.phaseName(p, ppFixedterm);
+		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");
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 137fb52..5347c18 100644
--- a/entitlement/pom.xml
+++ b/entitlement/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.7-SNAPSHOT</version>
+        <version>0.1.8-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-entitlement</artifactId>
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
index 467c435..0781d4e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/DefaultEntitlementBillingApi.java
@@ -26,8 +26,7 @@ import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.CallContext;
 import com.ning.billing.util.CallOrigin;
 import com.ning.billing.util.UserType;
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.entity.DefaultCallContext;
+import com.ning.billing.util.entity.CallContextFactory;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
@@ -61,15 +60,15 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
 	private static final Logger log = LoggerFactory.getLogger(DefaultEntitlementBillingApi.class);
     private static final String API_USER_NAME = "Entitlement Billing Api";
 
-    private final Clock clock;
+    private final CallContextFactory factory;
     private final EntitlementDao entitlementDao;
     private final AccountUserApi accountApi;
     private final CatalogService catalogService;
 
     @Inject
-    public DefaultEntitlementBillingApi(final Clock clock, final EntitlementDao dao, final AccountUserApi accountApi, final CatalogService catalogService) {
+    public DefaultEntitlementBillingApi(final CallContextFactory factory, final EntitlementDao dao, final AccountUserApi accountApi, final CatalogService catalogService) {
         super();
-        this.clock = clock;
+        this.factory = factory;
         this.entitlementDao = dao;
         this.accountApi = accountApi;
         this.catalogService = catalogService;
@@ -86,7 +85,7 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
         	List<Subscription> subscriptions = entitlementDao.getSubscriptions(bundle.getId());
 
         	for (final Subscription subscription: subscriptions) {
-        		for (final SubscriptionTransition transition : subscription.getAllTransitions()) {
+        		for (final SubscriptionTransition transition : ((SubscriptionData) subscription).getBillingTransitions()) {
         			try {
         				BillingEvent event = new DefaultBillingEvent(transition, subscription, calculateBcd(bundle, subscription, transition, accountId), currency);
         				result.add(event);
@@ -129,10 +128,10 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
 		switch (alignment) {
     		case ACCOUNT :
     			result = account.getBillCycleDay();
-    			
+
     			if(result == 0) {
                     // in this case, we're making an internal call from the entitlement API to set the BCD for the account
-                    CallContext context = new DefaultCallContext(clock, API_USER_NAME, CallOrigin.INTERNAL, UserType.SYSTEM);
+                    CallContext context = factory.createCallContext(API_USER_NAME, CallOrigin.INTERNAL, UserType.SYSTEM);
     				result = calculateBcdFromSubscription(subscription, plan, account, context);
     			}
     		break;
@@ -164,6 +163,7 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
             log.error("Unexpected catalog error encountered when updating BCD",e);
         }
 
+
         Account modifiedAccount = new DefaultAccount(
                 account.getId(),
                 account.getExternalKey(),
@@ -188,15 +188,15 @@ public class DefaultEntitlementBillingApi implements EntitlementBillingApi {
         return result;
     }
 
-    private int billCycleDay(DateTime requestedDate, DateTimeZone timeZone, 
+    private int billCycleDay(DateTime requestedDate, DateTimeZone timeZone,
     		Plan plan) throws CatalogApiException {
 
         DateTime date = plan.dateOfFirstRecurringNonZeroCharge(requestedDate);
         return date.toDateTime(timeZone).getDayOfMonth();
 
     }
-    
-    
+
+
     @Override
     public void setChargedThroughDate(final UUID subscriptionId, final DateTime ctd) {
         SubscriptionData subscription = (SubscriptionData) entitlementDao.getSubscriptionFromId(subscriptionId);
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 7396136..24c4e07 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
@@ -20,7 +20,9 @@ import java.util.List;
 
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
+import com.ning.billing.entitlement.api.user.SubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.entitlement.events.user.ApiEventMigrateBilling;
 
 public class AccountMigrationData {
 
@@ -62,10 +64,16 @@ public class AccountMigrationData {
         private final List<EntitlementEvent> initialEvents;
 
         public SubscriptionMigrationData(SubscriptionData data,
-
-                List<EntitlementEvent> initialEvents) {
+                    List<EntitlementEvent> initialEvents) {
             super();
-            this.data = data;
+            // Set CTD to subscription object from MIGRATION_BILLING event
+            SubscriptionBuilder builder = new SubscriptionBuilder(data);
+            for (EntitlementEvent cur : initialEvents) {
+                if (cur instanceof ApiEventMigrateBilling) {
+                    builder.setChargedThroughDate(cur.getEffectiveDate());
+                }
+            }
+            this.data = new SubscriptionData(builder);
             this.initialEvents = initialEvents;
         }
 
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 0b372e8..812378b 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
@@ -41,10 +41,13 @@ import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
 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.ApiEventMigrate;
+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.clock.Clock;
 
@@ -121,10 +124,10 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
             for (EntitlementSubscriptionMigration curSub : sortedSubscriptions) {
                 SubscriptionMigrationData data = null;
                 if (bundleStartDate == null) {
-                    data = createInitialSubscription(bundleData.getId(), curSub.getCategory(), curSub.getSubscriptionCases(), now);
+                    data = createInitialSubscription(bundleData.getId(), curSub.getCategory(), curSub.getSubscriptionCases(), now, curSub.getChargedThroughDate());
                     bundleStartDate = data.getInitialEvents().get(0).getEffectiveDate();
                 } else {
-                    data = createSubscriptionMigrationDataWithBundleDate(bundleData.getId(), curSub.getCategory(), curSub.getSubscriptionCases(), now, bundleStartDate);
+                    data = createSubscriptionMigrationDataWithBundleDate(bundleData.getId(), curSub.getCategory(), curSub.getSubscriptionCases(), now, bundleStartDate, curSub.getChargedThroughDate());
                 }
                 if (data != null) {
                     bundleSubscriptionData.add(data);
@@ -138,7 +141,7 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
     }
 
     private SubscriptionMigrationData createInitialSubscription(UUID bundleId, ProductCategory productCategory,
-            EntitlementSubscriptionMigrationCase [] input, DateTime now)
+            EntitlementSubscriptionMigrationCase [] input, DateTime now, DateTime ctd)
         throws EntitlementMigrationApiException {
 
         TimedMigration [] events = migrationAligner.getEventsMigration(input, now);
@@ -151,11 +154,11 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
             .setBundleStartDate(migrationStartDate)
             .setStartDate(migrationStartDate),
             emptyEvents);
-        return new SubscriptionMigrationData(subscriptionData, toEvents(subscriptionData, now, events));
+        return new SubscriptionMigrationData(subscriptionData, toEvents(subscriptionData, now, ctd, events));
     }
 
     private SubscriptionMigrationData createSubscriptionMigrationDataWithBundleDate(UUID bundleId, ProductCategory productCategory,
-            EntitlementSubscriptionMigrationCase [] input, DateTime now, DateTime bundleStartDate)
+            EntitlementSubscriptionMigrationCase [] input, DateTime now, DateTime bundleStartDate, DateTime ctd)
     throws EntitlementMigrationApiException {
         TimedMigration [] events = migrationAligner.getEventsMigration(input, now);
         DateTime migrationStartDate= events[0].getEventTime();
@@ -167,11 +170,13 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
             .setBundleStartDate(bundleStartDate)
             .setStartDate(migrationStartDate),
             emptyEvents);
-        return new SubscriptionMigrationData(subscriptionData, toEvents(subscriptionData, now, events));
+        return new SubscriptionMigrationData(subscriptionData, toEvents(subscriptionData, now, ctd, events));
     }
 
-    private List<EntitlementEvent> toEvents(SubscriptionData subscriptionData, DateTime now, TimedMigration [] migrationEvents) {
+    private List<EntitlementEvent> toEvents(SubscriptionData subscriptionData, DateTime now, DateTime ctd, TimedMigration [] migrationEvents) {
 
+
+        ApiEventMigrateEntitlement creationEvent = null;
         List<EntitlementEvent> events = new ArrayList<EntitlementEvent>(migrationEvents.length);
         for (TimedMigration cur : migrationEvents) {
 
@@ -194,7 +199,8 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
 
                 switch(cur.getApiEventType()) {
                 case MIGRATE_ENTITLEMENT:
-                    events.add(new ApiEventMigrate(builder));
+                    creationEvent = new ApiEventMigrateEntitlement(builder);
+                    events.add(creationEvent);
                     break;
 
                 case CHANGE:
@@ -210,6 +216,44 @@ public class DefaultEntitlementMigrationApi implements EntitlementMigrationApi {
                 throw new EntitlementError(String.format("Unexpected type of migration event %s", cur.getEventType()));
             }
         }
+        if (creationEvent == null || ctd == null) {
+            throw new EntitlementError(String.format("Could not create migration billing event ctd = %s", ctd));
+        }
+        events.add(new ApiEventMigrateBilling(creationEvent, ctd));
+        Collections.sort(events, new Comparator<EntitlementEvent>() {
+
+            int compForApiType(EntitlementEvent o1, EntitlementEvent o2, ApiEventType type) {
+
+                ApiEventType apiO1 = null;
+                if (o1.getType() == EventType.API_USER) {
+                    apiO1 = ((ApiEvent) o1).getEventType();
+                }
+                ApiEventType apiO2 = null;
+                if (o2.getType() == EventType.API_USER) {
+                    apiO2 = ((ApiEvent) o2).getEventType();
+                }
+                if (apiO1 != null && apiO1 == type) {
+                    return -1;
+                } else if (apiO2 != null && apiO2 == type) {
+                    return 1;
+                } else {
+                    return 0;
+                }
+            }
+
+            @Override
+            public int compare(EntitlementEvent o1, EntitlementEvent o2) {
+
+                int comp = o1.getEffectiveDate().compareTo(o2.getEffectiveDate());
+                if (comp == 0) {
+                    comp = compForApiType(o1, o2, ApiEventType.MIGRATE_ENTITLEMENT);
+                }
+                if (comp == 0) {
+                    comp = compForApiType(o1, o2, ApiEventType.MIGRATE_BILLING);
+                }
+                return comp;
+            }
+        });
         return events;
     }
 }
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 6321d35..baf45f1 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
@@ -99,7 +99,7 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
             String realPriceList = (spec.getPriceListName() == null) ? PriceListSet.DEFAULT_PRICELIST_NAME : spec.getPriceListName();
             DateTime now = clock.getUTCNow();
             requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : now;
-            if (requestedDate != null && requestedDate.isAfter(now)) {
+            if (requestedDate.isAfter(now)) {
                 throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE, requestedDate.toString());
             }
             DateTime effectiveDate = requestedDate;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
index 9bd7dd5..d89d22e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
@@ -163,7 +163,7 @@ public class SubscriptionApiService {
             .setActiveVersion(subscription.getActiveVersion())
             .setProcessedDate(now)
             .setEffectiveDate(effectiveDate)
-            .setRequestedDate(now)
+            .setRequestedDate(requestedDate)
             .setFromDisk(true));
 
             dao.cancelSubscription(subscription.getId(), cancelEvent);
@@ -260,7 +260,7 @@ public class SubscriptionApiService {
             .setActiveVersion(subscription.getActiveVersion())
             .setProcessedDate(now)
             .setEffectiveDate(effectiveDate)
-            .setRequestedDate(now)
+            .setRequestedDate(requestedDate)
             .setFromDisk(true));
 
             TimedPhase nextTimedPhase = planAligner.getNextTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), requestedDate, effectiveDate);
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 823f0eb..78d60b4 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
@@ -25,6 +25,11 @@ import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.api.user.SubscriptionFactory.SubscriptionBuilder;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition.SubscriptionTransitionType;
+import com.ning.billing.entitlement.api.user.SubscriptionTransitionDataIterator.Kind;
+import com.ning.billing.entitlement.api.user.SubscriptionTransitionDataIterator.Order;
+import com.ning.billing.entitlement.api.user.SubscriptionTransitionDataIterator.TimeLimit;
+import com.ning.billing.entitlement.api.user.SubscriptionTransitionDataIterator.Visibility;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
@@ -43,7 +48,6 @@ import org.slf4j.LoggerFactory;
 import javax.annotation.Nullable;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
@@ -74,7 +78,7 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
     // so the user holding that subscription object get the correct state when
     // the call completes
     //
-    private List<SubscriptionTransitionData> transitions;
+    private LinkedList<SubscriptionTransitionData> transitions;
 
     // Transient object never returned at the API
     public SubscriptionData(SubscriptionBuilder builder) {
@@ -182,45 +186,29 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
         apiService.recreatePlan(this, spec, requestedDate);
     }
 
-    @Override
-    public List<SubscriptionTransition> getActiveTransitions() {
-        if (transitions == null) {
-            return Collections.emptyList();
-        }
-
-        List<SubscriptionTransition> activeTransitions = new ArrayList<SubscriptionTransition>();
-        for (SubscriptionTransition cur : transitions) {
-            if (cur.getEffectiveTransitionTime().isAfter(clock.getUTCNow())) {
-                activeTransitions.add(cur);
-            }
-        }
-        return activeTransitions;
-    }
+    public List<SubscriptionTransition> getBillingTransitions() {
 
-    @Override
-    public List<SubscriptionTransition> getAllTransitions() {
         if (transitions == null) {
             return Collections.emptyList();
         }
-
         List<SubscriptionTransition> result = new ArrayList<SubscriptionTransition>();
-        for (SubscriptionTransition cur : transitions) {
-            result.add(cur);
+        SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(clock, transitions,
+                Order.ASC_FROM_PAST, Kind.BILLING, Visibility.ALL, TimeLimit.ALL);
+        while (it.hasNext()) {
+            result.add(it.next());
         }
         return result;
     }
 
     @Override
     public SubscriptionTransition getPendingTransition() {
+
         if (transitions == null) {
             return null;
         }
-        for (SubscriptionTransition cur : transitions) {
-            if (cur.getEffectiveTransitionTime().isAfter(clock.getUTCNow())) {
-                return cur;
-            }
-        }
-        return null;
+        SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(clock, transitions,
+                Order.ASC_FROM_PAST, Kind.ENTITLEMENT, Visibility.ALL, TimeLimit.FUTURE_ONLY);
+        return it.hasNext() ? it.next() : null;
     }
 
     @Override
@@ -228,25 +216,15 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
         if (transitions == null) {
             return null;
         }
-
-        // ensure that the latestSubscription is always set; prevents NPEs
-        SubscriptionTransitionData latestSubscription = transitions.get(0);
-        for (SubscriptionTransitionData cur : transitions) {
-            if (cur.getEffectiveTransitionTime().isAfter(clock.getUTCNow()) ||
-                    // We are not looking at events that were patched on the fly-- such as future ADDON cancelation from Base Plan
-                   !cur.isFromDisk()) {
-                break;
-            }
-            latestSubscription = cur;
-        }
-        return latestSubscription;
+        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;
     }
 
     public SubscriptionTransition getTransitionFromEvent(EntitlementEvent event) {
         if (transitions == null || event == null) {
             return null;
         }
-
         for (SubscriptionTransition cur : transitions) {
             if (cur.getId().equals(event.getId())) {
                 return cur;
@@ -283,35 +261,32 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
             throw new EntitlementError(String.format("No transitions for subscription %s", getId()));
         }
 
-        Iterator<SubscriptionTransitionData> it = ((LinkedList<SubscriptionTransitionData>) transitions).descendingIterator();
+
+        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();
-            if (cur.getEffectiveTransitionTime().isAfter(clock.getUTCNow())) {
-                // Skip future events
-                continue;
-            }
-            if (cur.getEventType() == EventType.API_USER &&
-                    (cur.getApiEventType() == ApiEventType.CHANGE ||
-                            cur.getApiEventType() == ApiEventType.RE_CREATE)) {
+            if (cur.getTransitionType() == SubscriptionTransitionType.CREATE ||
+                    cur.getTransitionType() == SubscriptionTransitionType.RE_CREATE ||
+                    cur.getTransitionType() == SubscriptionTransitionType.CHANGE ||
+                    cur.getTransitionType() == SubscriptionTransitionType.MIGRATE_ENTITLEMENT) {
                 return cur;
             }
         }
-        // CREATE event
-        return transitions.get(0);
+        throw new EntitlementError(String.format("Failed to find InitialTransitionForCurrentPlan id = %s", getId().toString()));
     }
 
     public boolean isSubscriptionFutureCancelled() {
         if (transitions == null) {
             return false;
         }
-
-        for (SubscriptionTransitionData cur : transitions) {
-            if (cur.getEffectiveTransitionTime().isBefore(clock.getUTCNow()) ||
-                    cur.getEventType() == EventType.PHASE ||
-                        cur.getApiEventType() != ApiEventType.CANCEL) {
-                continue;
+        SubscriptionTransitionDataIterator it = new SubscriptionTransitionDataIterator(clock, transitions,
+                Order.ASC_FROM_PAST, Kind.ENTITLEMENT, Visibility.ALL, TimeLimit.FUTURE_ONLY);
+        while (it.hasNext()) {
+            SubscriptionTransitionData cur = it.next();
+            if (cur.getTransitionType() == SubscriptionTransitionType.CANCEL) {
+                return true;
             }
-            return true;
         }
         return false;
     }
@@ -337,23 +312,20 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
         if (transitions == null) {
             throw new EntitlementError(String.format("No transitions for subscription %s", getId()));
         }
-
-        Iterator<SubscriptionTransitionData> it = ((LinkedList<SubscriptionTransitionData>) transitions).descendingIterator();
+        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();
-            if (cur.getEffectiveTransitionTime().isAfter(clock.getUTCNow())) {
-                // Skip future events
-                continue;
-            }
-            if (cur.getEventType() == EventType.PHASE
-                    || (cur.getEventType() == EventType.API_USER &&
-                            (cur.getApiEventType() == ApiEventType.CHANGE ||
-                                    cur.getApiEventType() == ApiEventType.RE_CREATE))) {
+
+            if (cur.getTransitionType() == SubscriptionTransitionType.PHASE ||
+                    cur.getTransitionType() == SubscriptionTransitionType.CREATE ||
+                    cur.getTransitionType() == SubscriptionTransitionType.RE_CREATE ||
+                    cur.getTransitionType() == SubscriptionTransitionType.CHANGE ||
+                    cur.getTransitionType() == SubscriptionTransitionType.MIGRATE_ENTITLEMENT) {
                 return cur.getEffectiveTransitionTime();
             }
         }
-        // CREATE event
-        return transitions.get(0).getEffectiveTransitionTime();
+        throw new EntitlementError(String.format("Failed to find CurrentPhaseStart id = %s", getId().toString()));
     }
 
     public void rebuildTransitions(final List<EntitlementEvent> events, final Catalog catalog) {
@@ -368,8 +340,6 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
         String nextPriceList = null;
 
         SubscriptionState previousState = null;
-        //String previousPlanName = null;
-        //String previousPhaseName = null;
         String previousPriceList = null;
 
         transitions = new LinkedList<SubscriptionTransitionData>();
@@ -398,9 +368,14 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
                 apiEventType = userEV.getEventType();
                 isFromDisk = userEV.isFromDisk();
                 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();
@@ -423,7 +398,6 @@ public class SubscriptionData extends CustomizableEntityBase implements Subscrip
                             userEV.getEventType().toString()));
                 }
                 break;
-
             default:
                 throw new EntitlementError(String.format("Unexpected Event type = %s",
                         cur.getType()));
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
new file mode 100644
index 0000000..fbab9b2
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransitionDataIterator.java
@@ -0,0 +1,104 @@
+/*
+ * 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.entitlement.api.user;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import com.ning.billing.entitlement.api.user.SubscriptionTransition.SubscriptionTransitionType;
+import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.util.clock.Clock;
+
+public class SubscriptionTransitionDataIterator implements Iterator<SubscriptionTransitionData> {
+
+    private final Clock clock;
+    private final Iterator<SubscriptionTransitionData> it;
+    private final Kind kind;
+    private final TimeLimit timeLimit;
+    private final Visibility visibility;
+
+    private SubscriptionTransitionData next;
+
+    public enum Order {
+        ASC_FROM_PAST,
+        DESC_FROM_FUTURE
+    }
+
+    public enum Kind {
+        ENTITLEMENT,
+        BILLING,
+        ALL
+    }
+
+    public enum TimeLimit {
+        FUTURE_ONLY,
+        PAST_OR_PRESENT_ONLY,
+        ALL
+    }
+
+    public enum Visibility {
+        FROM_DISK_ONLY,
+        ALL
+    }
+
+    public SubscriptionTransitionDataIterator(Clock clock, LinkedList<SubscriptionTransitionData> transitions,
+            Order order, Kind kind, Visibility visibility, TimeLimit timeLimit) {
+        this.it = (order == Order.DESC_FROM_FUTURE) ? transitions.descendingIterator() : transitions.iterator();
+        this. clock = clock;
+        this.kind = kind;
+        this.timeLimit = timeLimit;
+        this.visibility = visibility;
+        this.next = null;
+    }
+
+    @Override
+    public boolean hasNext() {
+        do {
+            boolean hasNext = it.hasNext();
+            if (!hasNext) {
+                return false;
+            }
+            next = it.next();
+        }  while (shouldSkip(next));
+        return true;
+    }
+
+    private boolean shouldSkip(SubscriptionTransitionData input) {
+        if (visibility == Visibility.FROM_DISK_ONLY && !input.isFromDisk()) {
+            return true;
+        }
+        if ((kind == Kind.ENTITLEMENT && input.getTransitionType() == SubscriptionTransitionType.MIGRATE_BILLING) ||
+                (kind == Kind.BILLING && input.getTransitionType() == SubscriptionTransitionType.MIGRATE_ENTITLEMENT)) {
+            return true;
+        }
+        if ((timeLimit == TimeLimit.FUTURE_ONLY && ! input.getEffectiveTransitionTime().isAfter(clock.getUTCNow())) ||
+                ((timeLimit == TimeLimit.PAST_OR_PRESENT_ONLY && input.getEffectiveTransitionTime().isAfter(clock.getUTCNow())))) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public SubscriptionTransitionData next() {
+        return next;
+    }
+
+    @Override
+    public void remove() {
+        throw new EntitlementError("Operation SubscriptionTransitionDataIterator.remove not implemented");
+    }
+}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EventSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EventSqlDao.java
index 5a7681e..adf007e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EventSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EventSqlDao.java
@@ -138,7 +138,9 @@ public interface EventSqlDao extends Transactional<EventSqlDao>, CloseMe, Transm
                 } else if (userType == ApiEventType.RE_CREATE) {
                     result = new ApiEventReCreate(builder);
                 } else if (userType == ApiEventType.MIGRATE_ENTITLEMENT) {
-                    result = new ApiEventMigrate(builder);
+                    result = new ApiEventMigrateEntitlement(builder);
+                } else if (userType == ApiEventType.MIGRATE_BILLING) {
+                    result = new ApiEventMigrateBilling(builder);
                 } else if (userType == ApiEventType.CHANGE) {
                     result = new ApiEventChange(builder);
                 } else if (userType == ApiEventType.CANCEL) {
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 64e81e1..3f222ca 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
@@ -75,7 +75,7 @@ public interface SubscriptionSqlDao extends Transactional<SubscriptionSqlDao>, C
             stmt.bind("start_dt", getDate(sub.getStartDate()));
             stmt.bind("bundle_start_dt", getDate(sub.getBundleStartDate()));
             stmt.bind("active_version", sub.getActiveVersion());
-            stmt.bind("ctd_dt", getDate(sub.getPaidThroughDate()));
+            stmt.bind("ctd_dt", getDate(sub.getChargedThroughDate()));
             stmt.bind("ptd_dt", getDate(sub.getPaidThroughDate()));
         }
     }
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
new file mode 100644
index 0000000..3c10699
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventMigrateBilling.java
@@ -0,0 +1,40 @@
+/*
+ * 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.entitlement.events.user;
+
+import org.joda.time.DateTime;
+
+public class ApiEventMigrateBilling extends ApiEventBase {
+    public ApiEventMigrateBilling(ApiEventBuilder builder) {
+        super(builder.setEventType(ApiEventType.MIGRATE_BILLING));
+    }
+
+    public ApiEventMigrateBilling(ApiEventMigrateEntitlement input, 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));
+    }
+
+}
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 ec56655..a279f52 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
@@ -28,6 +28,10 @@ public enum ApiEventType {
         @Override
         public SubscriptionTransitionType getSubscriptionTransitionType() { return SubscriptionTransitionType.CREATE; }
     },
+    MIGRATE_BILLING {
+        @Override
+        public SubscriptionTransitionType getSubscriptionTransitionType() { return SubscriptionTransitionType.MIGRATE_BILLING; }
+    },
     CHANGE {
         @Override
         public SubscriptionTransitionType getSubscriptionTransitionType() { return SubscriptionTransitionType.CHANGE; }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java
index 5e8e1ef..8d8e00c 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java
@@ -22,6 +22,7 @@ import com.ning.billing.entitlement.api.user.SubscriptionTransition;
 import com.ning.billing.util.bus.Bus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testng.Assert;
 
 import java.util.Iterator;
 import java.util.List;
@@ -37,6 +38,7 @@ public class ApiTestListener {
 
     public enum NextEvent {
         MIGRATE_ENTITLEMENT,
+        MIGRATE_BILLING,
         CREATE,
         RE_CREATE,
         CHANGE,
@@ -72,6 +74,9 @@ public class ApiTestListener {
         case PHASE:
             subscriptionPhaseChanged(event);
             break;
+        case MIGRATE_BILLING:
+            subscriptionMigratedBilling(event);
+            break;
         default:
             throw new RuntimeException("Unexpected event type " + event.getRequestedTransitionTime());
         }
@@ -87,6 +92,9 @@ public class ApiTestListener {
 
     public boolean isCompleted(long timeout) {
         synchronized (this) {
+            if (completed) {
+                return completed;
+            }
             try {
                 wait(timeout);
             } catch (Exception ignore) {
@@ -129,8 +137,7 @@ public class ApiTestListener {
 
         if (!foundIt) {
             Joiner joiner = Joiner.on(" ");
-            System.err.println("Expected event " + expected + " got " + joiner.join(nextExpectedEvent));
-            System.exit(1);
+            Assert.fail("Expected event " + expected + " got " + joiner.join(nextExpectedEvent));
         }
     }
 
@@ -174,4 +181,11 @@ public class ApiTestListener {
         assertEqualsNicely(NextEvent.PHASE);
         notifyIfStackEmpty();
     }
+
+    public void subscriptionMigratedBilling(SubscriptionTransition migrated) {
+        log.debug("-> Got event MIGRATED_BLLING");
+        assertEqualsNicely(NextEvent.MIGRATE_BILLING);
+        notifyIfStackEmpty();
+    }
+
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
index 0f3c37d..2d96157 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.SortedSet;
 import java.util.UUID;
 
+import com.ning.billing.util.entity.CallContextFactory;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.testng.Assert;
@@ -105,7 +106,7 @@ public class TestDefaultEntitlementBillingApi {
 		builder.setStartDate(subscriptionStartDate).setId(oneId);
 		subscription = new SubscriptionData(builder) {
 		    @Override
-            public List<SubscriptionTransition> getAllTransitions() {
+            public List<SubscriptionTransition> getBillingTransitions() {
 		    	return transitions;
 		    }
 		};
@@ -134,7 +135,8 @@ public class TestDefaultEntitlementBillingApi {
 		AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
         ((ZombieControl) accountApi).addResult("getAccountById", account);
 
-		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(clock, dao, accountApi, catalogService);
+        CallContextFactory factory = new CallContextFactory(clock);
+		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, catalogService);
 		SortedSet<BillingEvent> events = api.getBillingEventsForAccount(new UUID(0L,0L));
 		Assert.assertEquals(events.size(), 0);
 	}
@@ -166,7 +168,8 @@ public class TestDefaultEntitlementBillingApi {
                     }
                 };
 			}} ;
-		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(clock, dao,accountApi,catalogService);
+        CallContextFactory factory = new CallContextFactory(clock);
+		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao,accountApi,catalogService);
 		SortedSet<BillingEvent> events = api.getBillingEventsForAccount(new UUID(0L,0L));
 		checkFirstEvent(events, nextPlan, 32, oneId, now, nextPhase, ApiEventType.CREATE.toString());
 	}
@@ -190,7 +193,8 @@ public class TestDefaultEntitlementBillingApi {
 		AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
 		((ZombieControl)accountApi).addResult("getAccountById", account);
 
-		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(clock, dao, accountApi, catalogService);
+        CallContextFactory factory = new CallContextFactory(clock);
+		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, catalogService);
 		SortedSet<BillingEvent> events = api.getBillingEventsForAccount(new UUID(0L,0L));
 		checkFirstEvent(events, nextPlan, subscription.getStartDate().getDayOfMonth(), oneId, now, nextPhase, ApiEventType.CREATE.toString());
 	}
@@ -222,7 +226,8 @@ public class TestDefaultEntitlementBillingApi {
                     }
                 };
 			}} ;
-		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(clock, dao, accountApi, catalogService);
+        CallContextFactory factory = new CallContextFactory(clock);
+		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, catalogService);
 		SortedSet<BillingEvent> events = api.getBillingEventsForAccount(new UUID(0L,0L));
 		checkFirstEvent(events, nextPlan, 32, oneId, now, nextPhase, ApiEventType.CREATE.toString());
 	}
@@ -245,7 +250,8 @@ public class TestDefaultEntitlementBillingApi {
 		AccountUserApi accountApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
 		((ZombieControl)accountApi).addResult("getAccountById", account);
 
-		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(clock, dao, accountApi, catalogService);
+        CallContextFactory factory = new CallContextFactory(clock);
+		DefaultEntitlementBillingApi api = new DefaultEntitlementBillingApi(factory, dao, accountApi, catalogService);
 		SortedSet<BillingEvent> events = api.getBillingEventsForAccount(new UUID(0L,0L));
 		checkFirstEvent(events, nextPlan, bundles.get(0).getStartDate().getDayOfMonth(), oneId, now, nextPhase, ApiEventType.CREATE.toString());
 	}
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 acd64ea..4868bf7 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
@@ -52,8 +52,9 @@ public abstract class TestMigration extends TestApiBase {
     public void testSingleBasePlan() {
 
         try {
+            final DateTime startDate = clock.getUTCNow().minusMonths(2);
             DateTime beforeMigration = clock.getUTCNow();
-            EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlan();
+            EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlan(startDate);
             DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
@@ -73,6 +74,7 @@ public abstract class TestMigration extends TestApiBase {
             assertEquals(subscription.getCurrentPhase().getPhaseType(), PhaseType.EVERGREEN);
             assertEquals(subscription.getState(), SubscriptionState.ACTIVE);
             assertEquals(subscription.getCurrentPlan().getName(), "assault-rifle-annual");
+            assertEquals(subscription.getChargedThroughDate(), startDate.plusYears(1));
         } catch (EntitlementMigrationApiException e) {
             Assert.fail("", e);
         }
@@ -82,11 +84,13 @@ public abstract class TestMigration extends TestApiBase {
     public void testPlanWithAddOn() {
         try {
             DateTime beforeMigration = clock.getUTCNow();
+            final DateTime initalBPStart = clock.getUTCNow().minusMonths(3);
             final DateTime initalAddonStart = clock.getUTCNow().minusMonths(1).plusDays(7);
-            EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlanAndAddons(initalAddonStart);
+            EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlanAndAddons(initalBPStart, initalAddonStart);
             DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
+            testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
             migrationApi.migrate(toBeMigrated);
             assertTrue(testListener.isCompleted(5000));
 
@@ -104,7 +108,8 @@ public abstract class TestMigration extends TestApiBase {
             assertEquals(baseSubscription.getCurrentPriceList(), PriceListSet.DEFAULT_PRICELIST_NAME);
             assertEquals(baseSubscription.getCurrentPhase().getPhaseType(), PhaseType.EVERGREEN);
             assertEquals(baseSubscription.getState(), SubscriptionState.ACTIVE);
-            assertEquals(baseSubscription.getCurrentPlan().getName(), "assault-rifle-annual");
+            assertEquals(baseSubscription.getCurrentPlan().getName(), "shotgun-annual");
+            assertEquals(baseSubscription.getChargedThroughDate(), initalBPStart.plusYears(1));
 
             Subscription aoSubscription = (subscriptions.get(0).getCurrentPlan().getProduct().getCategory() == ProductCategory.ADD_ON) ?
                     subscriptions.get(0) : subscriptions.get(1);
@@ -114,6 +119,7 @@ public abstract class TestMigration extends TestApiBase {
             assertEquals(aoSubscription.getCurrentPhase().getPhaseType(), PhaseType.DISCOUNT);
             assertEquals(aoSubscription.getState(), SubscriptionState.ACTIVE);
             assertEquals(aoSubscription.getCurrentPlan().getName(), "telescopic-scope-monthly");
+            assertEquals(aoSubscription.getChargedThroughDate(), initalAddonStart.plusMonths(1));
 
         } catch (EntitlementMigrationApiException e) {
             Assert.fail("", e);
@@ -125,8 +131,9 @@ public abstract class TestMigration extends TestApiBase {
 
         try {
 
+            final DateTime startDate = clock.getUTCNow().minusMonths(1);
             DateTime beforeMigration = clock.getUTCNow();
-            EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlanFutreCancelled();
+            EntitlementAccountMigration toBeMigrated = createAccountWithRegularBasePlanFutreCancelled(startDate);
             DateTime afterMigration = clock.getUTCNow();
 
             testListener.pushExpectedEvent(NextEvent.MIGRATE_ENTITLEMENT);
@@ -146,7 +153,9 @@ public abstract class TestMigration extends TestApiBase {
             assertEquals(subscription.getCurrentPhase().getPhaseType(), PhaseType.EVERGREEN);
             assertEquals(subscription.getState(), SubscriptionState.ACTIVE);
             assertEquals(subscription.getCurrentPlan().getName(), "assault-rifle-annual");
+            assertEquals(subscription.getChargedThroughDate(), startDate.plusYears(1));
 
+            testListener.pushExpectedEvent(NextEvent.MIGRATE_BILLING);
             testListener.pushExpectedEvent(NextEvent.CANCEL);
             Duration oneYear = getDurationYear(1);
             clock.setDeltaFromReality(oneYear, 0);
@@ -191,7 +200,9 @@ public abstract class TestMigration extends TestApiBase {
             assertEquals(subscription.getCurrentPhase().getPhaseType(), PhaseType.TRIAL);
             assertEquals(subscription.getState(), SubscriptionState.ACTIVE);
             assertEquals(subscription.getCurrentPlan().getName(), "assault-rifle-monthly");
+            assertEquals(subscription.getChargedThroughDate(), trialDate.plusDays(30));
 
+            testListener.pushExpectedEvent(NextEvent.MIGRATE_BILLING);
             testListener.pushExpectedEvent(NextEvent.PHASE);
             Duration thirtyDays = getDurationDay(30);
             clock.setDeltaFromReality(thirtyDays, 0);
@@ -255,7 +266,7 @@ public abstract class TestMigration extends TestApiBase {
     }
 
 
-    private EntitlementAccountMigration createAccountWithSingleBasePlan(final List<List<EntitlementSubscriptionMigrationCase>> cases) {
+    private EntitlementAccountMigration createAccountTest(final List<List<EntitlementSubscriptionMigrationCaseWithCTD>> cases) {
 
         return new EntitlementAccountMigration() {
 
@@ -273,15 +284,24 @@ public abstract class TestMigration extends TestApiBase {
 
                         for (int i = 0; i < cases.size(); i++) {
 
-                            final List<EntitlementSubscriptionMigrationCase> curCases = cases.get(i);
+                            final List<EntitlementSubscriptionMigrationCaseWithCTD> curCases = cases.get(i);
                             EntitlementSubscriptionMigration subscription = new EntitlementSubscriptionMigration() {
                                 @Override
-                                public EntitlementSubscriptionMigrationCase[] getSubscriptionCases() {
-                                    return curCases.toArray(new EntitlementSubscriptionMigrationCase[curCases.size()]);
+                                public EntitlementSubscriptionMigrationCaseWithCTD[] getSubscriptionCases() {
+                                    return curCases.toArray(new EntitlementSubscriptionMigrationCaseWithCTD[curCases.size()]);
                                 }
                                 @Override
                                 public ProductCategory getCategory() {
-                                    return ProductCategory.BASE;
+                                    return curCases.get(0).getPlanPhaseSpecifer().getProductCategory();
+                                }
+                                @Override
+                                public DateTime getChargedThroughDate() {
+                                    for (EntitlementSubscriptionMigrationCaseWithCTD cur :curCases) {
+                                        if (cur.getChargedThroughDate() != null) {
+                                            return cur.getChargedThroughDate();
+                                        }
+                                    }
+                                    return null;
                                 }
                             };
                             result[i] = subscription;
@@ -304,174 +324,126 @@ public abstract class TestMigration extends TestApiBase {
         };
     }
 
-    private EntitlementAccountMigration createAccountWithRegularBasePlanAndAddons(final DateTime initalAddonStart) {
-
-        List<EntitlementSubscriptionMigrationCase> cases = new LinkedList<EntitlementSubscriptionMigrationCase>();
-        cases.add(new EntitlementSubscriptionMigrationCase() {
-            @Override
-            public PlanPhaseSpecifier getPlanPhaseSpecifer() {
-                return new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-            }
-            @Override
-            public DateTime getEffectiveDate() {
-                return clock.getUTCNow().minusMonths(3);
-            }
-            @Override
-            public DateTime getCancelledDate() {
-                return null;
-            }
-        });
-
-        List<EntitlementSubscriptionMigrationCase> firstAddOnCases = new LinkedList<EntitlementSubscriptionMigrationCase>();
-
-        firstAddOnCases.add(new EntitlementSubscriptionMigrationCase() {
-            @Override
-            public PlanPhaseSpecifier getPlanPhaseSpecifer() {
-                return new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.DISCOUNT);
-            }
-            @Override
-            public DateTime getEffectiveDate() {
-                return initalAddonStart;
-            }
-            @Override
-            public DateTime getCancelledDate() {
-                return initalAddonStart.plusMonths(1);
-            }
-        });
-        firstAddOnCases.add(new EntitlementSubscriptionMigrationCase() {
-            @Override
-            public PlanPhaseSpecifier getPlanPhaseSpecifer() {
-                return new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-            }
-            @Override
-            public DateTime getEffectiveDate() {
-                return initalAddonStart.plusMonths(1);
-            }
-            @Override
-            public DateTime getCancelledDate() {
-                return null;
-            }
-        });
-
-        List<List<EntitlementSubscriptionMigrationCase>> input = new ArrayList<List<EntitlementSubscriptionMigrationCase>>();
+    private EntitlementAccountMigration createAccountWithRegularBasePlanAndAddons(final DateTime initialBPstart, final DateTime initalAddonStart) {
+
+        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>();
+        firstAddOnCases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
+                new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.DISCOUNT),
+                initalAddonStart,
+                initalAddonStart.plusMonths(1),
+                initalAddonStart.plusMonths(1)));
+        firstAddOnCases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
+                new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN),
+                initalAddonStart.plusMonths(1),
+                null,
+                null));
+
+
+        List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
         input.add(cases);
         input.add(firstAddOnCases);
-        return createAccountWithSingleBasePlan(input);
+        return createAccountTest(input);
     }
 
-    private EntitlementAccountMigration createAccountWithRegularBasePlan() {
-        List<EntitlementSubscriptionMigrationCase> cases = new LinkedList<EntitlementSubscriptionMigrationCase>();
-        cases.add(new EntitlementSubscriptionMigrationCase() {
-            @Override
-            public PlanPhaseSpecifier getPlanPhaseSpecifer() {
-                return new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-            }
-            @Override
-            public DateTime getEffectiveDate() {
-                return clock.getUTCNow().minusMonths(3);
-            }
-            @Override
-            public DateTime getCancelledDate() {
-                return null;
-            }
-        });
-        List<List<EntitlementSubscriptionMigrationCase>> input = new ArrayList<List<EntitlementSubscriptionMigrationCase>>();
+    private EntitlementAccountMigration createAccountWithRegularBasePlan(final DateTime startDate) {
+        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>>();
         input.add(cases);
-        return createAccountWithSingleBasePlan(input);
+        return createAccountTest(input);
     }
 
-    private EntitlementAccountMigration createAccountWithRegularBasePlanFutreCancelled() {
-        List<EntitlementSubscriptionMigrationCase> cases = new LinkedList<EntitlementSubscriptionMigrationCase>();
-        final DateTime effectiveDate = clock.getUTCNow().minusMonths(3);
-        cases.add(new EntitlementSubscriptionMigrationCase() {
-            @Override
-            public PlanPhaseSpecifier getPlanPhaseSpecifer() {
-                return new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-            }
-            @Override
-            public DateTime getEffectiveDate() {
-                return effectiveDate;
-            }
-            @Override
-            public DateTime getCancelledDate() {
-                return effectiveDate.plusYears(1);
-            }
-        });
-        List<List<EntitlementSubscriptionMigrationCase>> input = new ArrayList<List<EntitlementSubscriptionMigrationCase>>();
+    private EntitlementAccountMigration createAccountWithRegularBasePlanFutreCancelled(final DateTime startDate) {
+        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>>();
         input.add(cases);
-        return createAccountWithSingleBasePlan(input);
+        return createAccountTest(input);
     }
 
 
     private EntitlementAccountMigration createAccountFuturePendingPhase(final DateTime trialDate) {
-        List<EntitlementSubscriptionMigrationCase> cases = new LinkedList<EntitlementSubscriptionMigrationCase>();
-        cases.add(new EntitlementSubscriptionMigrationCase() {
-            @Override
-            public PlanPhaseSpecifier getPlanPhaseSpecifer() {
-                return new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.TRIAL);
-            }
-            @Override
-            public DateTime getEffectiveDate() {
-                return trialDate;
-            }
-            @Override
-            public DateTime getCancelledDate() {
-                return trialDate.plusDays(30);
-            }
-        });
-        cases.add(new EntitlementSubscriptionMigrationCase() {
-            @Override
-            public PlanPhaseSpecifier getPlanPhaseSpecifer() {
-                return new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-            }
-            @Override
-            public DateTime getEffectiveDate() {
-                return trialDate.plusDays(30);
-            }
-            @Override
-            public DateTime getCancelledDate() {
-                return null;
-            }
-        });
-        List<List<EntitlementSubscriptionMigrationCase>> input = new ArrayList<List<EntitlementSubscriptionMigrationCase>>();
+        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,
+                trialDate.plusDays(30),
+                trialDate.plusDays(30)));
+        cases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
+                new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN),
+                trialDate.plusDays(30),
+                null,
+                null));
+        List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
         input.add(cases);
-        return createAccountWithSingleBasePlan(input);
+        return createAccountTest(input);
     }
 
     private EntitlementAccountMigration createAccountFuturePendingChange() {
-        List<EntitlementSubscriptionMigrationCase> cases = new LinkedList<EntitlementSubscriptionMigrationCase>();
+        List<EntitlementSubscriptionMigrationCaseWithCTD> cases = new LinkedList<EntitlementSubscriptionMigrationCaseWithCTD>();
         final DateTime effectiveDate = clock.getUTCNow().minusDays(10);
-        cases.add(new EntitlementSubscriptionMigrationCase() {
-            @Override
-            public PlanPhaseSpecifier getPlanPhaseSpecifer() {
-                return new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-            }
-            @Override
-            public DateTime getEffectiveDate() {
-                return effectiveDate;
-            }
-            @Override
-            public DateTime getCancelledDate() {
-                return effectiveDate.plusMonths(1);
-            }
-        });
-        cases.add(new EntitlementSubscriptionMigrationCase() {
-            @Override
-            public PlanPhaseSpecifier getPlanPhaseSpecifer() {
-                return new PlanPhaseSpecifier("Shotgun", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN);
-            }
-            @Override
-            public DateTime getEffectiveDate() {
-                return effectiveDate.plusMonths(1).plusDays(1);
-            }
-            @Override
-            public DateTime getCancelledDate() {
-                return null;
-            }
-        });
-        List<List<EntitlementSubscriptionMigrationCase>> input = new ArrayList<List<EntitlementSubscriptionMigrationCase>>();
+        cases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
+                new PlanPhaseSpecifier("Assault-Rifle", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN),
+                effectiveDate,
+                effectiveDate.plusMonths(1),
+                effectiveDate.plusMonths(1)));
+        cases.add(new EntitlementSubscriptionMigrationCaseWithCTD(
+                new PlanPhaseSpecifier("Shotgun", ProductCategory.BASE, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.EVERGREEN),
+                effectiveDate.plusMonths(1).plusDays(1),
+                null,
+                null));
+        List<List<EntitlementSubscriptionMigrationCaseWithCTD>> input = new ArrayList<List<EntitlementSubscriptionMigrationCaseWithCTD>>();
         input.add(cases);
-        return createAccountWithSingleBasePlan(input);
+        return createAccountTest(input);
     }
 
+
+    public static class EntitlementSubscriptionMigrationCaseWithCTD implements EntitlementSubscriptionMigrationCase {
+
+        private final PlanPhaseSpecifier pps;
+        private final DateTime effDt;
+        private final DateTime cancelDt;
+        private final DateTime ctd;
+
+        public EntitlementSubscriptionMigrationCaseWithCTD(PlanPhaseSpecifier pps, DateTime effDt, DateTime cancelDt, DateTime ctd) {
+            this.pps = pps;
+            this.cancelDt = cancelDt;
+            this.effDt = effDt;
+            this.ctd = ctd;
+        }
+
+        @Override
+        public PlanPhaseSpecifier getPlanPhaseSpecifer() {
+            return pps;
+        }
+
+        @Override
+        public DateTime getEffectiveDate() {
+            return effDt;
+        }
+
+        @Override
+        public DateTime getCancelledDate() {
+            return cancelDt;
+        }
+
+        public DateTime getChargedThroughDate() {
+            return ctd;
+        }
+    }
 }
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 05d6fb5..e0de602 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
@@ -30,26 +30,27 @@ public class TestMigrationMemory extends TestMigration {
     }
 
     @Override
-    @Test(enabled=true, groups="fast")
+    @Test(enabled=false, groups="fast")
     public void testSingleBasePlan() {
         super.testSingleBasePlan();
     }
 
     @Override
-    @Test(enabled=true, groups="fast")
+    @Test(enabled=false, groups="fast")
     public void testSingleBasePlanFutureCancelled() {
         super.testSingleBasePlanFutureCancelled();
     }
 
     @Override
-    @Test(enabled=true, groups="fast")
-    public void testSingleBasePlanWithPendingPhase() {
-        super.testSingleBasePlanWithPendingPhase();
+    @Test(enabled=false, groups="fast")
+    public void testPlanWithAddOn() {
+        super.testPlanWithAddOn();
     }
 
+
     @Override
-    @Test(enabled=true, groups="fast")
-    public void testSingleBasePlanWithPendingChange() {
-        super.testSingleBasePlanWithPendingChange();
+    @Test(enabled=false, 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 84744d8..c395fed 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
@@ -53,10 +53,4 @@ public class TestMigrationSql extends TestMigration {
     public void testSingleBasePlanWithPendingPhase() {
         super.testSingleBasePlanWithPendingPhase();
     }
-
-    @Override
-    @Test(enabled=true, groups="slow")
-    public void testSingleBasePlanWithPendingChange() {
-        super.testSingleBasePlanWithPendingChange();
-    }
 }
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 3d553bd..31d8e8d 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
@@ -32,6 +32,7 @@ import org.joda.time.DateTimeZone;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
+import org.testng.ITestResult;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.AfterSuite;
@@ -118,12 +119,14 @@ public abstract class TestApiBase {
     @AfterClass(alwaysRun=true)
     public void tearDown() {
         try {
-            busService.getBus().register(testListener);
             ((DefaultBusService) busService).stopBus();
+            if (helper != null) {
+                helper.stopMysql();
+            }
         } catch (Exception e) {
             log.warn("Failed to tearDown test properly ", e);
         }
-
+        //if(helper != null) { helper.stopMysql(); }
     }
 
     @BeforeClass(alwaysRun=true)
@@ -183,7 +186,6 @@ public abstract class TestApiBase {
     @BeforeMethod(alwaysRun=true)
     public void setupTest() {
 
-        log.warn("\n");
         log.warn("RESET TEST FRAMEWORK\n\n");
 
         testListener.reset();
@@ -204,10 +206,20 @@ public abstract class TestApiBase {
 
     @AfterMethod(alwaysRun=true)
     public void cleanupTest() {
-        ((Engine)entitlementService).stop();
+        try {
+            busService.getBus().unregister(testListener);
+            ((Engine)entitlementService).stop();
+        } catch (Exception e) {
+            Assert.fail(e.getMessage());
+        }
         log.warn("DONE WITH TEST\n");
     }
 
+    @AfterMethod
+    public void am(ITestResult result) {
+      System.out.println("CURRENT METHOD NAME :" + result.getMethod().getMethodName());
+    }
+
     protected SubscriptionData createSubscription(final String productName, final BillingPeriod term, final String planSet) throws EntitlementUserApiException {
         return createSubscriptionWithBundle(bundle.getId(), productName, term, planSet);
     }
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 1e725bf..88c3825 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
@@ -66,12 +66,8 @@ public abstract class TestUserApiCancel extends TestApiBase {
             // CANCEL in trial period to get IMM policy
             subscription.cancel(clock.getUTCNow(), false);
             currentPhase = subscription.getCurrentPhase();
-
             testListener.isCompleted(1000);
 
-            List<SubscriptionTransition> allTransitions = subscription.getActiveTransitions();
-            printSubscriptionTransitions(allTransitions);
-
             assertNull(currentPhase);
             checkNextPhaseChange(subscription, 0, null);
 
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 dbcc680..fec3550 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
@@ -32,25 +32,25 @@ public class TestUserApiCancelMemory extends TestUserApiCancel {
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testCancelSubscriptionIMM() {
         super.testCancelSubscriptionIMM();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testCancelSubscriptionEOTWithChargeThroughDate() throws EntitlementBillingApiException {
         super.testCancelSubscriptionEOTWithChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testCancelSubscriptionEOTWithNoChargeThroughDate() {
         super.testCancelSubscriptionEOTWithNoChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testUncancel() throws EntitlementBillingApiException {
         super.testUncancel();
     }
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 03b9d91..ab76734 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
@@ -32,31 +32,31 @@ public class TestUserApiChangePlanMemory extends TestUserApiChangePlan {
 
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testChangePlanBundleAlignEOTWithNoChargeThroughDate() {
          super.testChangePlanBundleAlignEOTWithNoChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testChangePlanBundleAlignEOTWithChargeThroughDate() throws EntitlementBillingApiException {
         super.testChangePlanBundleAlignEOTWithChargeThroughDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testChangePlanBundleAlignIMM() {
         super.testChangePlanBundleAlignIMM();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testMultipleChangeLastIMM() throws EntitlementBillingApiException {
         super.testMultipleChangeLastIMM();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testMultipleChangeLastEOT() throws EntitlementBillingApiException {
         super.testMultipleChangeLastEOT();
     }
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 ee8490b..a56f13b 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
@@ -100,8 +100,6 @@ public abstract class TestUserApiCreate extends TestApiBase {
             assertDateWithin(subscription.getStartDate(), init, clock.getUTCNow());
             assertDateWithin(subscription.getBundleStartDate(), init, clock.getUTCNow());
 
-            printSubscriptionTransitions(subscription.getActiveTransitions());
-
             Plan currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
             assertEquals(currentPlan.getProduct().getName(), productName);
@@ -141,8 +139,6 @@ public abstract class TestUserApiCreate extends TestApiBase {
             assertDateWithin(subscription.getStartDate(), init, clock.getUTCNow());
             assertDateWithin(subscription.getBundleStartDate(), init, clock.getUTCNow());
 
-            printSubscriptionTransitions(subscription.getActiveTransitions());
-
             Plan currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
             assertEquals(currentPlan.getProduct().getName(), productName);
@@ -152,11 +148,6 @@ public abstract class TestUserApiCreate extends TestApiBase {
             PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
-
-            List<SubscriptionTransition> transitions = subscription.getActiveTransitions();
-            assertNotNull(transitions);
-            assertEquals(transitions.size(), 1);
-
             assertTrue(testListener.isCompleted(5000));
 
             List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
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 3adf86e..047ca67 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
@@ -31,25 +31,25 @@ public class TestUserApiCreateMemory extends TestUserApiCreate {
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testCreateWithRequestedDate() {
         super.testCreateWithRequestedDate();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testCreateWithInitialPhase() {
         super.testSimpleSubscriptionThroughPhases();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     public void testSimpleCreateSubscription() {
         super.testSimpleCreateSubscription();
     }
 
     @Override
-    @Test(enabled=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     protected void testSimpleSubscriptionThroughPhases() {
         super.testSimpleSubscriptionThroughPhases();
     }
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 fdb411c..b6f97c1 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=true, groups={"fast"})
+    @Test(enabled=false, groups={"fast"})
     protected void testRecreateWithBPCanceledThroughSubscription() {
         super.testRecreateWithBPCanceledThroughSubscription();
     }
 
     @Override
-    @Test(enabled=true, 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/TestUserCustomFieldsSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
index 65d3cac..30cf5ab 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserCustomFieldsSql.java
@@ -25,7 +25,7 @@ import com.ning.billing.util.CallContext;
 import com.ning.billing.util.CallOrigin;
 import com.ning.billing.util.UserType;
 import com.ning.billing.util.clock.DefaultClock;
-import com.ning.billing.util.entity.DefaultCallContext;
+import com.ning.billing.util.entity.CallContextFactory;
 import org.joda.time.DateTime;
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -43,7 +43,7 @@ import com.ning.billing.util.customfield.CustomField;
 
 public class TestUserCustomFieldsSql extends TestApiBase {
     private static final String USER_NAME = "Entitlement Test";
-    private final CallContext context = new DefaultCallContext(new DefaultClock(), USER_NAME, CallOrigin.TEST, UserType.TEST);
+    private final CallContext context = new CallContextFactory(new DefaultClock()).createCallContext(USER_NAME, CallOrigin.TEST, UserType.TEST);
 
     @Override
     protected Injector getInjector() {
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 59d5607..4fd4301 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
@@ -30,11 +30,11 @@ import org.joda.time.DateTime;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 import com.google.inject.Inject;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.catalog.api.TimeUnit;
 import com.ning.billing.config.EntitlementConfig;
-import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
 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;

invoice/pom.xml 2(+1 -1)

diff --git a/invoice/pom.xml b/invoice/pom.xml
index a91cb5d..90a72e5 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.7-SNAPSHOT</version>
+        <version>0.1.8-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-invoice</artifactId>
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 02a2931..3a04c3f 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
@@ -44,11 +44,11 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
         dao.notifyOfPaymentAttempt(invoicePayment);
     }
 
-    @Override
-    public List<Invoice> getInvoicesByAccount(final UUID accountId) {
-        return dao.getInvoicesByAccount(accountId);
-    }
-
+	@Override
+	public List<Invoice> getAllInvoicesByAccount(UUID accountId) {
+		return dao.getAllInvoicesByAccount(accountId);
+	}
+ 
     @Override
     public Invoice getInvoice(final UUID invoiceId) {
         return dao.getById(invoiceId);
@@ -76,5 +76,6 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
         InvoicePayment invoicePayment = new DefaultInvoicePayment(paymentAttemptId, invoiceId, paymentAttemptDate);
         dao.notifyOfPaymentAttempt(invoicePayment);
     }
-    
+
+
 }
\ No newline at end of file
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java
new file mode 100644
index 0000000..1b090be
--- /dev/null
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java
@@ -0,0 +1,57 @@
+/*
+ * 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.invoice.api.migration;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import com.ning.billing.util.CallContext;
+import com.ning.billing.util.CallOrigin;
+import com.ning.billing.util.UserType;
+import com.ning.billing.util.entity.CallContextFactory;
+import org.joda.time.DateTime;
+
+import com.google.inject.Inject;
+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.InvoiceMigrationApi;
+import com.ning.billing.invoice.dao.DefaultInvoiceDao;
+import com.ning.billing.invoice.model.MigrationInvoiceItem;
+import com.ning.billing.util.clock.Clock;
+
+public class DefaultInvoiceMigrationApi implements InvoiceMigrationApi {
+	
+	private DefaultInvoiceDao dao;
+	private Clock clock;
+
+	@Inject
+	public DefaultInvoiceMigrationApi(DefaultInvoiceDao dao, Clock clock) {
+		this.dao = dao;
+		this.clock = clock;
+	}
+
+	@Override
+	public UUID createMigrationInvoice(UUID accountId, DateTime targetDate, BigDecimal balance, Currency currency) {
+        CallContext context = new CallContextFactory(clock).createMigrationCallContext("Migration", CallOrigin.INTERNAL, UserType.MIGRATION, clock.getUTCNow(), clock.getUTCNow());
+		Invoice migrationInvoice = new MigrationInvoice(accountId, clock.getUTCNow(), targetDate, currency);
+		InvoiceItem migrationInvoiceItem = new MigrationInvoiceItem(migrationInvoice.getId(), targetDate, balance, currency );
+		migrationInvoice.addInvoiceItem(migrationInvoiceItem);
+		dao.create(migrationInvoice, context);
+		return migrationInvoice.getId();
+	}
+}
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/migration/MigrationInvoice.java b/invoice/src/main/java/com/ning/billing/invoice/api/migration/MigrationInvoice.java
new file mode 100644
index 0000000..5414dda
--- /dev/null
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/migration/MigrationInvoice.java
@@ -0,0 +1,13 @@
+package com.ning.billing.invoice.api.migration;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.model.DefaultInvoice;
+import org.joda.time.DateTime;
+
+import java.util.UUID;
+
+public class MigrationInvoice extends DefaultInvoice {
+    public MigrationInvoice(UUID accountId, DateTime invoiceDate, DateTime targetDate, Currency currency) {
+        super(UUID.randomUUID(), accountId, null, invoiceDate, targetDate, currency, true, null, null);
+    }
+}
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 87d3d0c..4c34d65 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
@@ -42,11 +42,6 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
     }
 
     @Override
-    public List<UUID> getInvoicesForPayment(final DateTime targetDate, final int numberOfDays) {
-        return dao.getInvoicesForPayment(targetDate, numberOfDays);
-    }
-
-    @Override
     public List<Invoice> getInvoicesByAccount(final UUID accountId) {
         return dao.getInvoicesByAccount(accountId);
     }
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 c250b7f..62b5729 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
@@ -81,6 +81,21 @@ public class DefaultInvoiceDao implements InvoiceDao {
     }
 
     @Override
+    public List<Invoice> getAllInvoicesByAccount(final UUID accountId) {
+    	return invoiceSqlDao.inTransaction(new Transaction<List<Invoice>, InvoiceSqlDao>() {
+    		@Override
+    		public List<Invoice> inTransaction(final InvoiceSqlDao invoiceDao, final TransactionStatus status) throws Exception {
+    			List<Invoice> invoices = invoiceDao.getAllInvoicesByAccount(accountId.toString());
+
+    			getInvoiceItemsWithinTransaction(invoices, invoiceDao);
+    			getInvoicePaymentsWithinTransaction(invoices, invoiceDao);
+
+    			return invoices;
+    		}
+    	});
+    }
+
+    @Override
     public List<Invoice> getInvoicesByAccount(final UUID accountId, final DateTime fromDate) {
         return invoiceSqlDao.inTransaction(new Transaction<List<Invoice>, InvoiceSqlDao>() {
             @Override
@@ -189,11 +204,6 @@ public class DefaultInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<UUID> getInvoicesForPayment(final DateTime targetDate, final int numberOfDays) {
-        return invoiceSqlDao.getInvoicesForPayment(targetDate.toDate(), numberOfDays);
-    }
-
-    @Override
     public BigDecimal getAccountBalance(final UUID accountId) {
         return invoiceSqlDao.getAccountBalance(accountId.toString());
     }
@@ -302,4 +312,5 @@ public class DefaultInvoiceDao implements InvoiceDao {
             }
         }
     }
+
 }
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 1c7932f..7d734c4 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
@@ -39,9 +39,6 @@ public interface InvoiceDao {
 
     List<Invoice> getInvoicesBySubscription(final UUID subscriptionId);
 
-    List<UUID> getInvoicesForPayment(final DateTime targetDate,
-                                     final int numberOfDays);
-
     UUID getInvoiceIdByPaymentAttemptId(final UUID paymentAttemptId);
 
     InvoicePayment getInvoicePayment(final UUID paymentAttemptId);
@@ -53,4 +50,6 @@ public interface InvoiceDao {
     List<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, final DateTime upToDate);
 
     void test();
+
+	List<Invoice> getAllInvoicesByAccount(UUID accountId);
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
index c43c8f4..6eda77e 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
@@ -60,6 +60,9 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
 
     @SqlQuery
     List<Invoice> getInvoicesByAccount(@Bind("accountId") final String accountId);
+    
+    @SqlQuery
+    List<Invoice> getAllInvoicesByAccount(@Bind("accountId") final String string);
 
     @SqlQuery
     List<Invoice> getInvoicesByAccountAfterDate(@Bind("accountId") final String accountId,
@@ -73,17 +76,14 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
     UUID getInvoiceIdByPaymentAttemptId(@Bind("paymentAttemptId") final String paymentAttemptId);
 
     @SqlQuery
-    @RegisterMapper(UuidMapper.class)
-    List<UUID> getInvoicesForPayment(@Bind("targetDate") final Date targetDate,
-                                    @Bind("numberOfDays") final int numberOfDays);
-
-    @SqlQuery
     @RegisterMapper(BalanceMapper.class)
     BigDecimal getAccountBalance(@Bind("accountId") final String accountId);
 
     @SqlQuery
     List<Invoice> getUnpaidInvoicesByAccountId(@Bind("accountId") final String accountId,
                                                @Bind("upToDate") final Date upToDate);
+    
+    
 
     @BindingAnnotation(InvoiceBinder.InvoiceBinderFactory.class)
     @Retention(RetentionPolicy.RUNTIME)
@@ -100,6 +100,7 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
                         q.bind("invoiceDate", invoice.getInvoiceDate().toDate());
                         q.bind("targetDate", invoice.getTargetDate().toDate());
                         q.bind("currency", invoice.getCurrency().toString());
+                        q.bind("migrated", invoice.isMigrationInvoice());
                     }
                 };
             }
@@ -115,10 +116,11 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
             DateTime invoiceDate = new DateTime(result.getTimestamp("invoice_date"));
             DateTime targetDate = new DateTime(result.getTimestamp("target_date"));
             Currency currency = Currency.valueOf(result.getString("currency"));
+            boolean isMigrationInvoice = result.getBoolean("migrated");
             String createdBy = result.getString("created_by");
             DateTime createdDate = new DateTime(result.getTimestamp("created_date"));
 
-            return new DefaultInvoice(id, accountId, invoiceNumber, invoiceDate, targetDate, currency, createdBy, createdDate);
+            return new DefaultInvoice(id, accountId, invoiceNumber, invoiceDate, targetDate, currency, isMigrationInvoice, createdBy, createdDate);
         }
     }
 
@@ -141,5 +143,6 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
     }
 
 
+
 }
 
diff --git a/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java b/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java
index e85d369..c5e55cc 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java
@@ -22,10 +22,12 @@ import com.google.inject.AbstractModule;
 import com.ning.billing.config.InvoiceConfig;
 import com.ning.billing.invoice.InvoiceListener;
 import com.ning.billing.invoice.api.DefaultInvoiceService;
+import com.ning.billing.invoice.api.InvoiceMigrationApi;
 import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.invoice.api.InvoiceService;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.invoice.api.invoice.DefaultInvoicePaymentApi;
+import com.ning.billing.invoice.api.migration.DefaultInvoiceMigrationApi;
 import com.ning.billing.invoice.api.user.DefaultInvoiceUserApi;
 import com.ning.billing.invoice.dao.DefaultInvoiceDao;
 import com.ning.billing.invoice.dao.InvoiceDao;
@@ -59,6 +61,10 @@ public class InvoiceModule extends AbstractModule {
     protected void installInvoiceService() {
         bind(InvoiceService.class).to(DefaultInvoiceService.class).asEagerSingleton();
     }
+    
+    protected void installInvoiceMigrationApi() {
+    	bind(InvoiceMigrationApi.class).to(DefaultInvoiceMigrationApi.class).asEagerSingleton();
+	}
 
     protected void installNotifier() {
         bind(NextBillingDateNotifier.class).to(DefaultNextBillingDateNotifier.class).asEagerSingleton();
@@ -85,6 +91,9 @@ public class InvoiceModule extends AbstractModule {
         installInvoiceDao();
         installInvoiceUserApi();
         installInvoicePaymentApi();
+        installInvoiceMigrationApi();
         installGlobalLocker();
     }
+
+
 }
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 6a57755..a8e3d0c 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
@@ -21,8 +21,7 @@ import java.util.UUID;
 import com.ning.billing.util.CallContext;
 import com.ning.billing.util.CallOrigin;
 import com.ning.billing.util.UserType;
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.entity.DefaultCallContext;
+import com.ning.billing.util.entity.CallContextFactory;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,18 +34,18 @@ import com.ning.billing.invoice.api.InvoiceApiException;
 public class InvoiceListener {
     private final static Logger log = LoggerFactory.getLogger(InvoiceListener.class);
 	private final InvoiceDispatcher dispatcher;
-    private final Clock clock;
+    private final CallContextFactory factory;
 
     @Inject
-    public InvoiceListener(Clock clock, InvoiceDispatcher dispatcher) {
-        this.clock = clock;
+    public InvoiceListener(CallContextFactory factory,InvoiceDispatcher dispatcher) {
         this.dispatcher = dispatcher;
+        this.factory = factory;
     }
 
     @Subscribe
     public void handleSubscriptionTransition(final SubscriptionTransition transition) {
         try {
-            CallContext context = new DefaultCallContext(clock, "Transition", CallOrigin.INTERNAL, UserType.SYSTEM);
+            CallContext context = factory.createCallContext("Transition", CallOrigin.INTERNAL, UserType.SYSTEM);
         	dispatcher.processSubscription(transition, context);
         } catch (InvoiceApiException e) {
             log.error(e.getMessage());
@@ -55,7 +54,7 @@ public class InvoiceListener {
 
     public void handleNextBillingDateEvent(final UUID subscriptionId, final DateTime eventDateTime) {
         try {
-            CallContext context = new DefaultCallContext(clock, "Next Billing Date", CallOrigin.INTERNAL, UserType.SYSTEM);
+            CallContext context = factory.createCallContext("Next Billing Date", CallOrigin.INTERNAL, UserType.SYSTEM);
         	dispatcher.processSubscription(subscriptionId, eventDateTime, context);
         } catch (InvoiceApiException e) {
             log.error(e.getMessage());
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java
index 8f93a2d..0e62345 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java
@@ -16,18 +16,20 @@
 
 package com.ning.billing.invoice.model;
 
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+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.InvoicePayment;
 import com.ning.billing.util.entity.EntityBase;
-import org.joda.time.DateTime;
-
-import javax.annotation.Nullable;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
 
 public class DefaultInvoice extends EntityBase implements Invoice {
     private final InvoiceItemList invoiceItems = new InvoiceItemList();
@@ -37,21 +39,23 @@ public class DefaultInvoice extends EntityBase implements Invoice {
     private final DateTime invoiceDate;
     private final DateTime targetDate;
     private final Currency currency;
+    private final boolean migrationInvoice;
 
     // used to create a new invoice
     public DefaultInvoice(UUID accountId, DateTime invoiceDate, DateTime targetDate, Currency currency) {
-        this(UUID.randomUUID(), accountId, null, invoiceDate, targetDate, currency, null, null);
+        this(UUID.randomUUID(), accountId, null, invoiceDate, targetDate, currency, false, null, null);
     }
 
     // used to hydrate invoice from persistence layer
     public DefaultInvoice(UUID invoiceId, UUID accountId, @Nullable Integer invoiceNumber, DateTime invoiceDate,
-                          DateTime targetDate, Currency currency, @Nullable String createdBy, @Nullable DateTime createdDate) {
+                          DateTime targetDate, Currency currency, boolean isMigrationInvoice, @Nullable String createdBy, @Nullable DateTime createdDate) {
         super(invoiceId, createdBy, createdDate);
         this.accountId = accountId;
         this.invoiceNumber = invoiceNumber;
         this.invoiceDate = invoiceDate;
         this.targetDate = targetDate;
         this.currency = currency;
+        this.migrationInvoice = isMigrationInvoice;
     }
 
     @Override
@@ -70,10 +74,10 @@ public class DefaultInvoice extends EntityBase implements Invoice {
     }
 
     @Override
-    public List<InvoiceItem> getInvoiceItems(Class clazz) {
+    public <T extends InvoiceItem> List<InvoiceItem> getInvoiceItems(Class<T> clazz) {
         List<InvoiceItem> results = new ArrayList<InvoiceItem>();
         for (InvoiceItem item : invoiceItems) {
-            if (item.getClass() == clazz) {
+            if ( clazz.isInstance(item) ) {
                 results.add(item);
             }
         }
@@ -138,8 +142,13 @@ public class DefaultInvoice extends EntityBase implements Invoice {
     public Currency getCurrency() {
         return currency;
     }
-
+    
     @Override
+    public boolean isMigrationInvoice() {
+		return migrationInvoice;
+	}
+
+	@Override
     public DateTime getLastPaymentAttempt() {
         DateTime lastPaymentAttempt = null;
 
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java b/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java
new file mode 100644
index 0000000..8d654fd
--- /dev/null
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java
@@ -0,0 +1,35 @@
+/*
+ * 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.invoice.model;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.MigrationPlan;
+import com.ning.billing.util.clock.Clock;
+
+public class MigrationInvoiceItem extends FixedPriceInvoiceItem {
+	private final static UUID MIGRATION_SUBSCRIPTION_ID = UUID.fromString("ed25f954-3aa2-4422-943b-c3037ad7257c"); //new UUID(0L,0L);
+
+	public MigrationInvoiceItem(UUID invoiceId, DateTime startDate, BigDecimal amount, Currency currency) {
+		super(invoiceId, MIGRATION_SUBSCRIPTION_ID, MigrationPlan.MIGRATION_PLAN_NAME, MigrationPlan.MIGRATION_PLAN_PHASE_NAME,
+              startDate, startDate, amount, currency);
+	}
+}
\ No newline at end of file
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
index 87f9293..5c18a30 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
@@ -6,7 +6,8 @@ invoiceFetchFields(prefix) ::= <<
     <prefix>account_id,
     <prefix>invoice_date,
     <prefix>target_date,
-    <prefix>currency
+    <prefix>currency,
+  	<prefix>migrated
 >>
 
 invoiceSetFields(prefix) ::= <<
@@ -15,6 +16,7 @@ invoiceSetFields(prefix) ::= <<
     <prefix>invoice_date,
     <prefix>target_date,
     <prefix>currency,
+    <prefix>migrated,
     <prefix>updated_by
 >>
 
@@ -27,6 +29,13 @@ get() ::= <<
 getInvoicesByAccount() ::= <<
   SELECT <invoiceFetchFields()>
   FROM invoices
+  WHERE account_id = :accountId AND migrated = 'FALSE'
+  ORDER BY target_date ASC;
+>>
+
+getAllInvoicesByAccount() ::= <<
+  SELECT <invoiceFetchFields()>
+  FROM invoices
   WHERE account_id = :accountId
   ORDER BY target_date ASC;
 >>
@@ -34,7 +43,7 @@ getInvoicesByAccount() ::= <<
 getInvoicesByAccountAfterDate() ::= <<
   SELECT <invoiceFetchFields()>
   FROM invoices
-  WHERE account_id = :accountId AND target_date >= :fromDate
+  WHERE account_id = :accountId AND target_date >= :fromDate AND migrated = 'FALSE'
   ORDER BY target_date ASC;
 >>
 
@@ -42,18 +51,7 @@ getInvoicesBySubscription() ::= <<
   SELECT <invoiceFetchFields("i.")>
   FROM invoices i
   LEFT JOIN recurring_invoice_items rii ON i.id = rii.invoice_id
-  WHERE rii.subscription_id = :subscriptionId
-  GROUP BY <invoiceFetchFields("i.")>;
->>
-
-getInvoicesForPayment() ::= <<
-  SELECT i.id
-  FROM invoices i
-  LEFT JOIN invoice_payment_summary ips ON ips.invoice_id = i.id
-  LEFT JOIN invoice_item_summary iis ON iis.invoice_id = i.id
-  WHERE ((ips.last_payment_date IS NULL) OR (DATEDIFF(:targetDate, ips.last_payment_date) >= :numberOfDays))
-        AND ((ips.total_paid IS NULL) OR (iis.amount_invoiced >= ips.total_paid))
-        AND ((iis.amount_invoiced IS NOT NULL) AND (iis.amount_invoiced > 0))
+  WHERE rii.subscription_id = :subscriptionId  AND migrated = 'FALSE'
   GROUP BY <invoiceFetchFields("i.")>;
 >>
 
@@ -75,7 +73,7 @@ getAccountBalance() ::= <<
 
 create() ::= <<
   INSERT INTO invoices(<invoiceSetFields()>)
-  VALUES (:id, :accountId, :invoiceDate, :targetDate, :currency, :userName);
+  VALUES (:id, :accountId, :invoiceDate, :targetDate, :currency, :migrated, :userName);
 >>
 
 getInvoiceIdByPaymentAttemptId() ::= <<
@@ -90,7 +88,7 @@ getUnpaidInvoicesByAccountId() ::= <<
   FROM invoices i
   LEFT JOIN invoice_payment_summary ips ON i.id = ips.invoice_id
   LEFT JOIN invoice_item_summary iis ON i.id = iis.invoice_id
-  WHERE i.account_id = :accountId AND NOT (i.target_date > :upToDate)
+  WHERE i.account_id = :accountId AND NOT (i.target_date > :upToDate) AND migrated = 'FALSE'
   GROUP BY i.id, i.account_id, i.invoice_date, i.target_date, i.currency
   HAVING (SUM(iis.amount_invoiced) > SUM(ips.total_paid)) OR (SUM(ips.total_paid) IS NULL)
   ORDER BY i.target_date ASC;
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 dfae5bc..9c80513 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
@@ -45,6 +45,7 @@ CREATE TABLE invoices (
   invoice_date datetime NOT NULL,
   target_date datetime NOT NULL,
   currency char(3) NOT NULL,
+  migrated bool NOT NULL,
   updated_by varchar(30) NOT NULL,
   PRIMARY KEY(invoice_number)
 ) ENGINE=innodb;
@@ -74,7 +75,11 @@ GROUP BY invoice_id;
 
 DROP VIEW IF EXISTS invoice_item_summary;
 CREATE VIEW invoice_item_summary AS
-SELECT invoice_id,
-       CASE WHEN SUM(amount) IS NULL THEN 0 ELSE SUM(amount) END AS amount_invoiced
-FROM recurring_invoice_items
+SELECT i.id as invoice_id, 
+    CASE WHEN SUM(rii.amount) IS NULL THEN 0 ELSE SUM(rii.amount) END 
+    + CASE WHEN SUM(fii.amount) IS NULL THEN 0 ELSE SUM(fii.amount) END AS amount_invoiced
+FROM invoices i 
+LEFT JOIN recurring_invoice_items rii ON i.id = rii.invoice_id
+LEFT JOIN fixed_invoice_items fii ON i.id = fii.invoice_id
 GROUP BY invoice_id;
+
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
new file mode 100644
index 0000000..4701bc8
--- /dev/null
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java
@@ -0,0 +1,59 @@
+/*
+ * 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.invoice.api.migration;
+
+import com.ning.billing.entitlement.api.billing.EntitlementBillingApi;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
+import com.ning.billing.invoice.MockModule;
+import com.ning.billing.invoice.glue.InvoiceModule;
+import com.ning.billing.invoice.notification.DefaultNextBillingDateNotifier;
+import com.ning.billing.invoice.notification.DefaultNextBillingDatePoster;
+import com.ning.billing.invoice.notification.NextBillingDateNotifier;
+import com.ning.billing.invoice.notification.NextBillingDatePoster;
+import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
+
+public class MockModuleNoEntitlement extends MockModule {
+
+	@Override
+	protected void installEntitlementModule() {
+		EntitlementBillingApi entitlementApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementBillingApi.class);
+		((ZombieControl)entitlementApi).addResult("setChargedThroughDateFromTransaction", BrainDeadProxyFactory.ZOMBIE_VOID);
+		bind(EntitlementBillingApi.class).toInstance(entitlementApi);
+		bind(EntitlementDao.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementDao.class));
+
+	}
+
+	@Override
+	protected void installInvoiceModule() {
+		install(new InvoiceModule(){
+
+			@Override
+			protected void installNotifier() {
+				 bind(NextBillingDateNotifier.class).toInstance(BrainDeadProxyFactory.createBrainDeadProxyFor(NextBillingDateNotifier.class));
+				 NextBillingDatePoster poster = BrainDeadProxyFactory.createBrainDeadProxyFor(NextBillingDatePoster.class);
+				 ((ZombieControl)poster).addResult("insertNextBillingNotification",BrainDeadProxyFactory.ZOMBIE_VOID);
+			     bind(NextBillingDatePoster.class).toInstance(poster);
+			}
+			
+			
+		});
+		
+		
+	}
+
+}
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
new file mode 100644
index 0000000..119a987
--- /dev/null
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
@@ -0,0 +1,256 @@
+/*
+ * 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.invoice.api.migration;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import com.ning.billing.util.CallContext;
+import com.ning.billing.util.CallOrigin;
+import com.ning.billing.util.UserType;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.entity.CallContextFactory;
+import org.apache.commons.io.IOUtils;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import com.google.inject.Inject;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.catalog.MockPlan;
+import com.ning.billing.catalog.MockPlanPhase;
+import com.ning.billing.catalog.api.BillingPeriod;
+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.dbi.MysqlTestingHelper;
+import com.ning.billing.entitlement.api.billing.BillingEvent;
+import com.ning.billing.entitlement.api.billing.BillingModeType;
+import com.ning.billing.entitlement.api.billing.DefaultBillingEvent;
+import com.ning.billing.entitlement.api.billing.EntitlementBillingApi;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition.SubscriptionTransitionType;
+import com.ning.billing.invoice.InvoiceDispatcher;
+import com.ning.billing.invoice.TestInvoiceDispatcher;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceMigrationApi;
+import com.ning.billing.invoice.api.InvoicePaymentApi;
+import com.ning.billing.invoice.api.InvoiceUserApi;
+import com.ning.billing.invoice.dao.InvoiceDao;
+import com.ning.billing.invoice.model.InvoiceGenerator;
+import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
+import com.ning.billing.util.bus.BusService;
+import com.ning.billing.util.bus.DefaultBusService;
+import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.globallocker.GlobalLocker;
+
+@Guice(modules = {MockModuleNoEntitlement.class})
+public class TestDefaultInvoiceMigrationApi {
+	Logger log = LoggerFactory.getLogger(TestDefaultInvoiceMigrationApi.class);
+
+	@Inject
+	InvoiceUserApi invoiceUserApi;
+
+	@Inject
+	InvoicePaymentApi invoicePaymentApi;
+
+	@Inject
+	private InvoiceGenerator generator;
+	@Inject
+	private InvoiceDao invoiceDao;
+	@Inject
+	private GlobalLocker locker;
+
+	@Inject
+	private MysqlTestingHelper helper;
+
+	@Inject
+	private BusService busService;
+
+	@Inject
+	private InvoiceMigrationApi migrationApi;
+
+
+
+	private UUID accountId ;
+	private UUID subscriptionId ;
+	private DateTime date_migrated;
+	private DateTime date_regular;
+
+	private UUID migrationInvoiceId;
+	private UUID regularInvoiceId;
+
+	private static final BigDecimal MIGRATION_INVOICE_AMOUNT =  new BigDecimal("100.00");
+	private static final Currency MIGRATION_INVOICE_CURRENCY =  Currency.USD;
+
+    private final Clock clock = new ClockMock();
+
+	@BeforeClass(alwaysRun = true)
+	public void setup() throws Exception
+	{
+		log.info("Starting set up");
+		accountId = UUID.randomUUID();
+		subscriptionId = UUID.randomUUID();
+		date_migrated = clock.getUTCNow().minusYears(1);
+		date_regular = clock.getUTCNow();
+
+		final String invoiceDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
+		final String utilDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+
+		helper.startMysql();
+
+		helper.initDb(invoiceDdl);
+		helper.initDb(utilDdl);
+
+		busService.getBus().start();
+
+		migrationInvoiceId = createAndCheckMigrationInvoice();
+		regularInvoiceId = generateRegularInvoice();
+	}
+
+	@AfterClass(alwaysRun = true)
+	public void tearDown() {
+		try {
+			((DefaultBusService) busService).stopBus();
+			helper.stopMysql();
+		} catch (Exception e) {
+			log.warn("Failed to tearDown test properly ", e);
+		}
+	}
+
+	private UUID createAndCheckMigrationInvoice(){
+		UUID migrationInvoiceId = migrationApi.createMigrationInvoice(accountId, date_migrated, MIGRATION_INVOICE_AMOUNT, MIGRATION_INVOICE_CURRENCY);
+		Assert.assertNotNull(migrationInvoiceId);
+		//Double check it was created and values are correct
+
+		Invoice invoice = invoiceDao.getById(migrationInvoiceId);
+		Assert.assertNotNull(invoice);
+
+		Assert.assertEquals(invoice.getAccountId(), accountId);
+		Assert.assertEquals(invoice.getTargetDate().compareTo(date_migrated), 0); //temp to avoid tz test artifact
+		//		Assert.assertEquals(invoice.getTargetDate(),now);
+		Assert.assertEquals(invoice.getNumberOfItems(), 1);
+		Assert.assertEquals(invoice.getInvoiceItems().get(0).getAmount().compareTo(MIGRATION_INVOICE_AMOUNT), 0 );
+		Assert.assertEquals(invoice.getBalance().compareTo(MIGRATION_INVOICE_AMOUNT),0);
+		Assert.assertEquals(invoice.getCurrency(), MIGRATION_INVOICE_CURRENCY);
+		Assert.assertTrue(invoice.isMigrationInvoice());
+
+		return migrationInvoiceId;
+	}
+
+	private UUID generateRegularInvoice()  throws Exception {
+		AccountUserApi accountUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+		Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+		((ZombieControl)accountUserApi).addResult("getAccountById", account);
+		((ZombieControl)account).addResult("getCurrency", Currency.USD);
+		((ZombieControl)account).addResult("getId", accountId);
+
+		Subscription subscription =  BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+		((ZombieControl)subscription).addResult("getId", subscriptionId);
+		SortedSet<BillingEvent> events = new TreeSet<BillingEvent>();
+		Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
+		PlanPhase planPhase = MockPlanPhase.create1USDMonthlyEvergreen();
+		DateTime effectiveDate = new DateTime().minusDays(1);
+		Currency currency = Currency.USD;
+		BigDecimal fixedPrice = null;
+		events.add(new DefaultBillingEvent(subscription, effectiveDate,plan, planPhase,
+				fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1,
+				BillingModeType.IN_ADVANCE, "", 1L, SubscriptionTransitionType.CREATE));
+
+		EntitlementBillingApi entitlementBillingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementBillingApi.class);
+		((ZombieControl)entitlementBillingApi).addResult("getBillingEventsForAccount", events);
+
+		InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, entitlementBillingApi, invoiceDao, locker);
+
+        CallContext context = new CallContextFactory(clock).createCallContext("Migration test", CallOrigin.TEST, UserType.TEST);
+		Invoice invoice = dispatcher.processAccount(accountId, date_regular, true, context);
+		Assert.assertNotNull(invoice);
+
+		List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
+		Assert.assertEquals(invoices.size(),0);
+
+		invoice = dispatcher.processAccount(accountId, date_regular, false, context);
+		Assert.assertNotNull(invoice);
+
+		invoices = invoiceDao.getInvoicesByAccount(accountId);
+		Assert.assertEquals(invoices.size(),1);
+
+		return invoice.getId();
+	}
+
+	// Check migration invoice is NOT returned for all user api invoice calls
+	@Test(groups={"slow"},enabled=true)
+	public void testUserApiAccess(){
+		List<Invoice> byAccount = invoiceUserApi.getInvoicesByAccount(accountId);
+		Assert.assertEquals(byAccount.size(),1);
+		Assert.assertEquals(byAccount.get(0).getId(), regularInvoiceId);
+
+		List<Invoice> byAccountAndDate = invoiceUserApi.getInvoicesByAccount(accountId, date_migrated.minusDays(1));
+		Assert.assertEquals(byAccountAndDate.size(),1);
+		Assert.assertEquals(byAccountAndDate.get(0).getId(), regularInvoiceId);
+
+		Collection<Invoice> unpaid = invoiceUserApi.getUnpaidInvoicesByAccountId(accountId, date_regular.plusDays(1));
+		Assert.assertEquals(unpaid.size(), 1);
+		Assert.assertEquals(regularInvoiceId, unpaid.iterator().next().getId());
+
+	}
+
+
+	// Check migration invoice IS returned for payment api calls
+	@Test(groups={"slow"},enabled=true)
+	public void testPaymentApi(){
+		List<Invoice> allByAccount = invoicePaymentApi.getAllInvoicesByAccount(accountId);
+		Assert.assertEquals(allByAccount.size(),2);
+		Assert.assertTrue(checkContains(allByAccount, regularInvoiceId));
+		Assert.assertTrue(checkContains(allByAccount, migrationInvoiceId));
+	}
+
+
+	// Account balance should reflect total of migration and non-migration invoices
+	@Test(groups={"slow"},enabled=true)
+	public void testBalance(){
+		Invoice migrationInvoice = invoiceDao.getById(migrationInvoiceId);
+		Invoice regularInvoice = invoiceDao.getById(regularInvoiceId);
+		BigDecimal balanceOfAllInvoices = migrationInvoice.getBalance().add(regularInvoice.getBalance());
+
+		BigDecimal accountBalance = invoiceUserApi.getAccountBalance(accountId);
+		System.out.println("Account balance: " + accountBalance + " should equal the Balance Of All Invoices: " + balanceOfAllInvoices);
+		Assert.assertEquals(accountBalance.compareTo(balanceOfAllInvoices), 0);
+
+
+	}
+
+	private boolean checkContains(List<Invoice> invoices, UUID invoiceId) {
+		for(Invoice invoice : invoices) {
+			if(invoice.getId().equals(invoiceId)) {
+				return true;
+			}
+		}
+		return false;		
+	}
+}
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 11e6ead..3384274 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
@@ -47,7 +47,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
     }
 
     @Override
-    public List<Invoice> getInvoicesByAccount(UUID accountId) {
+    public List<Invoice> getAllInvoicesByAccount(UUID accountId) {
         ArrayList<Invoice> result = new ArrayList<Invoice>();
 
         for (Invoice invoice : invoices) {
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 dc4a9e6..0352be4 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
@@ -29,6 +29,7 @@ import com.ning.billing.util.CallContext;
 import com.ning.billing.util.CallOrigin;
 import com.ning.billing.util.UserType;
 import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.entity.CallContextFactory;
 import com.ning.billing.util.entity.DefaultCallContext;
 import org.apache.commons.io.IOUtils;
 import org.skife.jdbi.v2.Handle;
@@ -53,6 +54,7 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
     protected Clock clock;
     protected CallContext context;
     protected InvoiceGenerator generator;
+    private BusService busService;
 
     private final InvoiceConfig invoiceConfig = new InvoiceConfig() {
         @Override
@@ -89,7 +91,7 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
 
             invoicePaymentDao = module.getInvoicePaymentSqlDao();
             clock = injector.getInstance(Clock.class);
-            context = new DefaultCallContext(clock, "Count Rogan", CallOrigin.TEST, UserType.TEST);
+            context = new CallContextFactory(clock).createCallContext("Count Rogan", CallOrigin.TEST, UserType.TEST);
             generator = new DefaultInvoiceGenerator(clock, invoiceConfig);
 
             BusService busService = injector.getInstance(BusService.class);
@@ -131,6 +133,7 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
 
     @AfterClass(alwaysRun = true)
     protected void tearDown() {
+    	((DefaultBusService) busService).stopBus();
         module.stopDb();
         assertTrue(true);
     }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
index c23cf92..435ba21 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
@@ -26,7 +26,6 @@ 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.config.InvoiceConfig;
 import com.ning.billing.entitlement.api.billing.BillingEvent;
 import com.ning.billing.entitlement.api.billing.BillingModeType;
 import com.ning.billing.entitlement.api.billing.DefaultBillingEvent;
@@ -38,9 +37,7 @@ import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.model.BillingEventSet;
 import com.ning.billing.invoice.model.DefaultInvoice;
-import com.ning.billing.invoice.model.DefaultInvoiceGenerator;
 import com.ning.billing.invoice.model.DefaultInvoicePayment;
-import com.ning.billing.invoice.model.InvoiceGenerator;
 import com.ning.billing.invoice.model.RecurringInvoiceItem;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
@@ -60,8 +57,6 @@ import static org.testng.Assert.assertTrue;
 
 @Test(groups = {"invoicing", "invoicing-invoiceDao"})
 public class InvoiceDaoTests extends InvoiceDaoTestBase {
-    private final int NUMBER_OF_DAY_BETWEEN_RETRIES = 8;
-
     @Test
     public void testCreationAndRetrievalByAccount() {
         UUID accountId = UUID.randomUUID();
@@ -155,114 +150,6 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
     }
 
     @Test
-    public void testGetInvoicesForPaymentWithNoResults() {
-        DateTime notionalDate = new DateTime();
-        DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
-
-        // determine the number of existing invoices available for payment (to avoid side effects from other tests)
-        List<UUID> invoices = invoiceDao.getInvoicesForPayment(notionalDate, NUMBER_OF_DAY_BETWEEN_RETRIES);
-        int existingInvoiceCount = invoices.size();
-
-        UUID accountId = UUID.randomUUID();
-        Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate, Currency.USD);
-
-        invoiceDao.create(invoice, context);
-        invoices = invoiceDao.getInvoicesForPayment(notionalDate, NUMBER_OF_DAY_BETWEEN_RETRIES);
-        assertEquals(invoices.size(), existingInvoiceCount);
-    }
-
-    @Test
-    public void testGetInvoicesForPayment() {
-        List<UUID> invoices;
-        DateTime notionalDate = clock.getUTCNow();
-
-        // create a new invoice with one item
-        UUID accountId = UUID.randomUUID();
-        DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
-        Invoice invoice = new DefaultInvoice(accountId, clock.getUTCNow(), targetDate, Currency.USD);
-
-        UUID invoiceId = invoice.getId();
-        UUID subscriptionId = UUID.randomUUID();
-        DateTime endDate = targetDate.plusMonths(3);
-        BigDecimal rate = new BigDecimal("9.0");
-        BigDecimal amount = rate.multiply(new BigDecimal("3.0"));
-
-        RecurringInvoiceItem item = new RecurringInvoiceItem(invoiceId, subscriptionId, "test plan", "test phase", targetDate, endDate,
-                amount, rate, Currency.USD);
-        invoice.addInvoiceItem(item);
-        invoiceDao.create(invoice, context);
-
-        // ensure that the number of invoices for payment has increased by 1
-        int count;
-        invoices = invoiceDao.getInvoicesForPayment(notionalDate, NUMBER_OF_DAY_BETWEEN_RETRIES);
-        List<Invoice> invoicesDue = getInvoicesDueForPaymentAttempt(invoiceDao.get(), notionalDate);
-        count = invoicesDue.size();
-        assertEquals(invoices.size(), count);
-
-        // attempt a payment; ensure that the number of invoices for payment has decreased by 1
-        // (no retries for NUMBER_OF_DAYS_BETWEEN_RETRIES days)
-        invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(invoice.getId(), notionalDate));
-        invoices = invoiceDao.getInvoicesForPayment(notionalDate, NUMBER_OF_DAY_BETWEEN_RETRIES);
-        count = getInvoicesDueForPaymentAttempt(invoiceDao.get(), notionalDate).size();
-        assertEquals(invoices.size(), count);
-
-        // advance clock by NUMBER_OF_DAYS_BETWEEN_RETRIES days
-        // ensure that number of invoices for payment has increased by 1 (retry)
-        notionalDate = notionalDate.plusDays(NUMBER_OF_DAY_BETWEEN_RETRIES);
-        invoices = invoiceDao.getInvoicesForPayment(notionalDate, NUMBER_OF_DAY_BETWEEN_RETRIES);
-        count = getInvoicesDueForPaymentAttempt(invoiceDao.get(), notionalDate).size();
-        assertEquals(invoices.size(), count);
-
-        // post successful partial payment; ensure that number of invoices for payment has decreased by 1
-        invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(UUID.randomUUID(), invoice.getId(), notionalDate, new BigDecimal("22.0000"), Currency.USD));
-
-        invoices = invoiceDao.getInvoicesForPayment(notionalDate, NUMBER_OF_DAY_BETWEEN_RETRIES);
-        count = getInvoicesDueForPaymentAttempt(invoiceDao.get(), notionalDate).size();
-        assertEquals(invoices.size(), count);
-
-        // get invoice; verify amount paid is correct
-        invoice = invoiceDao.getById(invoiceId);
-        assertEquals(invoice.getAmountPaid().compareTo(new BigDecimal("22.0")), 0);
-
-        // advance clock NUMBER_OF_DAYS_BETWEEN_RETRIES days
-        // ensure that number of invoices for payment has increased by 1 (retry)
-        notionalDate = notionalDate.plusDays(NUMBER_OF_DAY_BETWEEN_RETRIES);
-        invoices = invoiceDao.getInvoicesForPayment(notionalDate, NUMBER_OF_DAY_BETWEEN_RETRIES);
-        count = getInvoicesDueForPaymentAttempt(invoiceDao.get(), notionalDate).size();
-        assertEquals(invoices.size(), count);
-
-        // post completed payment; ensure that the number of invoices for payment has decreased by 1
-        invoiceDao.notifyOfPaymentAttempt(new DefaultInvoicePayment(UUID.randomUUID(), invoice.getId(), notionalDate, new BigDecimal("5.0000"), Currency.USD));
-
-        invoices = invoiceDao.getInvoicesForPayment(notionalDate, NUMBER_OF_DAY_BETWEEN_RETRIES);
-        count = getInvoicesDueForPaymentAttempt(invoiceDao.get(), notionalDate).size();
-        assertEquals(invoices.size(), count);
-
-        // get invoice; verify amount paid is correct
-        invoice = invoiceDao.getById(invoiceId);
-        assertEquals(invoice.getAmountPaid().compareTo(new BigDecimal("27.0")), 0);
-
-        // advance clock by NUMBER_OF_DAYS_BETWEEN_RETRIES days
-        // ensure that the number of invoices for payment hasn't changed
-        notionalDate = notionalDate.plusDays(NUMBER_OF_DAY_BETWEEN_RETRIES);
-        invoices = invoiceDao.getInvoicesForPayment(notionalDate, NUMBER_OF_DAY_BETWEEN_RETRIES);
-        count = getInvoicesDueForPaymentAttempt(invoiceDao.get(), notionalDate).size();
-        assertEquals(invoices.size(), count);
-    }
-
-    private List<Invoice> getInvoicesDueForPaymentAttempt(final List<Invoice> invoices, final DateTime date) {
-        List<Invoice> invoicesDue = new ArrayList<Invoice>();
-
-        for (final Invoice invoice : invoices) {
-            if (invoice.isDueForPayment(date, NUMBER_OF_DAY_BETWEEN_RETRIES)) {
-                invoicesDue.add(invoice);
-            }
-        }
-
-        return invoicesDue;
-    }
-
-    @Test
     public void testGetInvoicesBySubscription() {
         UUID accountId = UUID.randomUUID();
 
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 742dbf3..a5c53e3 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
@@ -78,7 +78,7 @@ public class MockInvoiceDao implements InvoiceDao {
 
         synchronized (monitor) {
             for (Invoice invoice : invoices.values()) {
-                if (accountId.equals(invoice.getAccountId())) {
+                if (accountId.equals(invoice.getAccountId()) && !invoice.isMigrationInvoice()) {
                     result.add(invoice);
                 }
             }
@@ -92,7 +92,7 @@ public class MockInvoiceDao implements InvoiceDao {
 
         synchronized (monitor) {
             for (Invoice invoice : get()) {
-                if (accountId.equals(invoice.getAccountId()) && !invoice.getTargetDate().isBefore(fromDate)) {
+                if (accountId.equals(invoice.getAccountId()) && !invoice.getTargetDate().isBefore(fromDate) && !invoice.isMigrationInvoice()) {
                     invoicesForAccount.add(invoice);
                 }
             }
@@ -108,7 +108,7 @@ public class MockInvoiceDao implements InvoiceDao {
         synchronized (monitor) {
             for (Invoice invoice : invoices.values()) {
                 for (InvoiceItem item : invoice.getInvoiceItems()) {
-                    if (subscriptionId.equals(item.getSubscriptionId())) {
+                    if (subscriptionId.equals(item.getSubscriptionId()) && !invoice.isMigrationInvoice()) {
                         result.add(invoice);
                         break;
                     }
@@ -119,21 +119,6 @@ public class MockInvoiceDao implements InvoiceDao {
     }
 
     @Override
-    public List<UUID> getInvoicesForPayment(DateTime targetDate, int numberOfDays) {
-        List<UUID> result = new ArrayList<UUID>();
-
-        synchronized (monitor) {
-            for (Invoice invoice : invoices.values()) {
-                if (invoice.isDueForPayment(targetDate, numberOfDays)) {
-                    result.add(invoice.getId());
-                }
-            }
-        }
-
-        return result;
-    }
-
-    @Override
     public void test() {
     }
 
@@ -194,11 +179,25 @@ public class MockInvoiceDao implements InvoiceDao {
         List<Invoice> unpaidInvoices = new ArrayList<Invoice>();
 
         for (Invoice invoice : get()) {
-            if (accountId.equals(invoice.getAccountId()) && (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0)) {
+            if (accountId.equals(invoice.getAccountId()) && (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) && !invoice.isMigrationInvoice()) {
                 unpaidInvoices.add(invoice);
             }
         }
 
         return unpaidInvoices;
     }
+
+	@Override
+	public List<Invoice> getAllInvoicesByAccount(UUID accountId) {
+		  List<Invoice> result = new ArrayList<Invoice>();
+
+	        synchronized (monitor) {
+	            for (Invoice invoice : invoices.values()) {
+	                if (accountId.equals(invoice.getAccountId())) {
+	                    result.add(invoice);
+	                }
+	            }
+	        }
+	        return result;
+	}
 }
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 01f0eb2..4be12cc 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
@@ -49,4 +49,8 @@ public class InvoiceModuleWithMocks extends InvoiceModule {
     protected void installInvoiceService() {
 
     }
+    
+    protected void installInvoiceMigrationApi() {
+
+    }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/MockModule.java b/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
index ec96f60..db31602 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/MockModule.java
@@ -58,13 +58,20 @@ public class MockModule extends AbstractModule {
 
         install(new GlobalLockerModule());
         install(new NotificationQueueModule());
-        install(new InvoiceModule());
         install(new AccountModule());
-        install(new EntitlementModule());
+        installEntitlementModule();
         install(new CatalogModule());
         install(new BusModule());
+        installInvoiceModule();
 
     }
+    
+    protected void installEntitlementModule() {
+    	install(new EntitlementModule());
+    }
+
+    protected void installInvoiceModule() {
+    	install(new InvoiceModule());
+    }
 
- 
 }
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 c6c881a..1b7d821 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
@@ -25,6 +25,7 @@ import java.util.UUID;
 import java.util.concurrent.Callable;
 
 import com.ning.billing.invoice.InvoiceDispatcher;
+import com.ning.billing.util.entity.CallContextFactory;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.skife.config.ConfigurationObjectFactory;
@@ -32,6 +33,7 @@ import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.Transaction;
 import org.skife.jdbi.v2.TransactionStatus;
 import org.testng.Assert;
+import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
@@ -73,8 +75,8 @@ public class TestNextBillingDateNotifier {
 		int eventCount = 0;
 		UUID latestSubscriptionId = null;
 
-		public InvoiceListenerMock(Clock clock, InvoiceDispatcher dispatcher) {
-			super(clock, dispatcher);
+		public InvoiceListenerMock(CallContextFactory factory, InvoiceDispatcher dispatcher) {
+			super(factory, dispatcher);
 		}
 
 		@Override
@@ -131,7 +133,8 @@ public class TestNextBillingDateNotifier {
         notifier = new DefaultNextBillingDateNotifier(notificationQueueService,g.getInstance(InvoiceConfig.class), entitlementDao, listener);
         startMysql();
 
-        listener = new InvoiceListenerMock(clock, dispatcher);
+        CallContextFactory factory = new CallContextFactory(clock);
+        listener = new InvoiceListenerMock(factory, dispatcher);
 	}
 
 	private void startMysql() throws IOException, ClassNotFoundException, SQLException {
@@ -182,4 +185,10 @@ public class TestNextBillingDateNotifier {
 		Assert.assertEquals(listener.getEventCount(), 1);
 		Assert.assertEquals(listener.getLatestSubscriptionId(), subscriptionId);
 	}
+
+	@AfterClass(alwaysRun = true)
+    public void tearDown() {
+    	helper.stopMysql();
+    }
+
 }
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 61b828c..70603de 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
@@ -27,10 +27,13 @@ import com.ning.billing.util.CallContext;
 import com.ning.billing.util.CallOrigin;
 import com.ning.billing.util.UserType;
 import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.entity.DefaultCallContext;
+import com.ning.billing.util.entity.CallContextFactory;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.testng.Assert;
+import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeSuite;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
@@ -38,10 +41,12 @@ import org.testng.annotations.Test;
 import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.catalog.MockInternationalPrice;
 import com.ning.billing.catalog.MockPlan;
 import com.ning.billing.catalog.MockPlanPhase;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.InternationalPrice;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.dbi.MysqlTestingHelper;
@@ -60,106 +65,123 @@ import com.ning.billing.invoice.notification.NextBillingDateNotifier;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 import com.ning.billing.util.bus.BusService;
+import com.ning.billing.util.bus.DefaultBusService;
 import com.ning.billing.util.globallocker.GlobalLocker;
+import sun.security.util.BigInt;
 
 @Guice(modules = {MockModule.class})
 public class TestInvoiceDispatcher {
+	Logger log = LoggerFactory.getLogger(TestInvoiceDispatcher.class);
 
-    @Inject
-    InvoiceUserApi invoiceUserApi;
-    @Inject
- 	private InvoiceGenerator generator;
-    @Inject
-    private InvoiceDao invoiceDao;
-    @Inject
-    private GlobalLocker locker;
+	@Inject
+	InvoiceUserApi invoiceUserApi;
+	@Inject
+	private InvoiceGenerator generator;
+	@Inject
+	private InvoiceDao invoiceDao;
+	@Inject
+	private GlobalLocker locker;
 
-    @Inject
-    private MysqlTestingHelper helper;
+	@Inject
+	private MysqlTestingHelper helper;
 
-    @Inject
-    NextBillingDateNotifier notifier;
+	@Inject
+	NextBillingDateNotifier notifier;
 
-    @Inject
-    private BusService busService;
+	@Inject
+	private BusService busService;
 
     @Inject
     private Clock clock;
 
-    private final CallContext context = new DefaultCallContext(clock, "Miracle Max", CallOrigin.TEST, UserType.TEST);
+    private final CallContext context = new CallContextFactory(clock).createCallContext("Miracle Max", CallOrigin.TEST, UserType.TEST);
+
+	@BeforeSuite(alwaysRun = true)
+	public void setup() throws IOException
+	{
+
+
+		final String accountDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
+		final String entitlementDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
+		final String invoiceDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
+		//        final String paymentDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/payment/ddl.sql"));
+		final String utilDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+
+		helper.startMysql();
 
-    @BeforeSuite(alwaysRun = true)
-    public void setup() throws IOException
-    {
-        final String accountDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
-        final String entitlementDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
-        final String invoiceDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
-//        final String paymentDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/payment/ddl.sql"));
-        final String utilDdl = IOUtils.toString(TestInvoiceDispatcher.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+		helper.initDb(accountDdl);
+		helper.initDb(entitlementDdl);
+		helper.initDb(invoiceDdl);
+		//        helper.initDb(paymentDdl);
+		helper.initDb(utilDdl);
+		notifier.initialize();
+		notifier.start();
 
-        helper.startMysql();
+		busService.getBus().start();
+	}
 
-        helper.initDb(accountDdl);
-        helper.initDb(entitlementDdl);
-        helper.initDb(invoiceDdl);
-//        helper.initDb(paymentDdl);
-        helper.initDb(utilDdl);
-        notifier.initialize();
-        notifier.start();
+	@AfterClass(alwaysRun = true)
+	public void tearDown() {
+		try {
+			((DefaultBusService) busService).stopBus();
+			notifier.stop();
+			helper.stopMysql();
+		} catch (Exception e) {
+			log.warn("Failed to tearDown test properly ", e);
+		}
 
-        busService.getBus().start();
-    }
+	}
 
+	@Test(groups={"fast"}, enabled=true)
+	public void testDryrunInvoice() throws InvoiceApiException {
+		UUID accountId = UUID.randomUUID();
+		UUID subscriptionId = UUID.randomUUID();
 
-	    @Test(groups={"fast"}, enabled=true)
-	    public void testDryRunInvoice() throws InvoiceApiException {
-	    	UUID accountId = UUID.randomUUID();
-	    	UUID subscriptionId = UUID.randomUUID();
+		AccountUserApi accountUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
+		Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
+		((ZombieControl)accountUserApi).addResult("getAccountById", account);
+		((ZombieControl)account).addResult("getCurrency", Currency.USD);
+		((ZombieControl)account).addResult("getId", accountId);
 
-	    	AccountUserApi accountUserApi = BrainDeadProxyFactory.createBrainDeadProxyFor(AccountUserApi.class);
-	    	Account account = BrainDeadProxyFactory.createBrainDeadProxyFor(Account.class);
-	    	((ZombieControl)accountUserApi).addResult("getAccountById", account);
-	    	((ZombieControl)account).addResult("getCurrency", Currency.USD);
-	    	((ZombieControl)account).addResult("getId", accountId);
+		Subscription subscription =  BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
+		((ZombieControl)subscription).addResult("getId", subscriptionId);
+		SortedSet<BillingEvent> events = new TreeSet<BillingEvent>();
+		Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
+		PlanPhase planPhase = MockPlanPhase.create1USDMonthlyEvergreen();
+		DateTime effectiveDate = new DateTime().minusDays(1);
+		Currency currency = Currency.USD;
+		BigDecimal fixedPrice = null;
+		events.add(new DefaultBillingEvent(subscription, effectiveDate,plan, planPhase,
+				fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1,
+				BillingModeType.IN_ADVANCE, "", 1L, SubscriptionTransitionType.CREATE));
 
-	    	Subscription subscription =  BrainDeadProxyFactory.createBrainDeadProxyFor(Subscription.class);
-	    	((ZombieControl)subscription).addResult("getId", subscriptionId);
-	    	SortedSet<BillingEvent> events = new TreeSet<BillingEvent>();
-	    	Plan plan = MockPlan.createBicycleNoTrialEvergreen1USD();
-	    	PlanPhase planPhase = MockPlanPhase.create1USDMonthlyEvergreen();
-			DateTime effectiveDate = new DateTime().minusDays(1);
-            Currency currency = Currency.USD;
-			BigDecimal fixedPrice = null;
-			events.add(new DefaultBillingEvent(subscription, effectiveDate,plan, planPhase,
-                                               fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1,
-                                               BillingModeType.IN_ADVANCE, "", 1L, SubscriptionTransitionType.CREATE));
+		EntitlementBillingApi entitlementBillingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementBillingApi.class);
+		((ZombieControl)entitlementBillingApi).addResult("getBillingEventsForAccount", events);
 
-	    	EntitlementBillingApi entitlementBillingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementBillingApi.class);
-	    	((ZombieControl)entitlementBillingApi).addResult("getBillingEventsForAccount", events);
+		DateTime target = new DateTime();
 
-	    	DateTime target = new DateTime();
+		InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, entitlementBillingApi, invoiceDao, locker);
 
-	    	InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, entitlementBillingApi, invoiceDao, locker);
+		Invoice invoice = dispatcher.processAccount(accountId, target, true, context);
+		Assert.assertNotNull(invoice);
 
-	    	Invoice invoice = dispatcher.processAccount(accountId, target, true, context);
-	    	Assert.assertNotNull(invoice);
+		List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
+		Assert.assertEquals(invoices.size(), 0);
 
-	    	List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
-	    	Assert.assertEquals(invoices.size(),0);
+		// Try it again to double check
+		invoice = dispatcher.processAccount(accountId, target, true, context);
+		Assert.assertNotNull(invoice);
 
-	    	// Try it again to double check
-	    	invoice = dispatcher.processAccount(accountId, target, true, context);
-	    	Assert.assertNotNull(invoice);
+		invoices = invoiceDao.getInvoicesByAccount(accountId);
+		Assert.assertEquals(invoices.size(), 0);
 
-	    	invoices = invoiceDao.getInvoicesByAccount(accountId);
-	    	Assert.assertEquals(invoices.size(),0);
+		// This time no dry run
+		invoice = dispatcher.processAccount(accountId, target, false, context);
+		Assert.assertNotNull(invoice);
 
-	    	// This time no dry run
-	    	invoice = dispatcher.processAccount(accountId, target, false, context);
-	    	Assert.assertNotNull(invoice);
+		invoices = invoiceDao.getInvoicesByAccount(accountId);
+		Assert.assertEquals(invoices.size(),1);
 
-	    	invoices = invoiceDao.getInvoicesByAccount(accountId);
-	    	Assert.assertEquals(invoices.size(),1);
+	}
 
-	    }
 }

payment/pom.xml 2(+1 -1)

diff --git a/payment/pom.xml b/payment/pom.xml
index 41218d1..398a6cc 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.7-SNAPSHOT</version>
+        <version>0.1.8-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-payment</artifactId>
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 5d7daca..63bc87e 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
@@ -188,6 +188,14 @@ public class DefaultPaymentApi implements PaymentApi {
                                                                                         UUID.fromString(invoiceId)));
                 processedPaymentsOrErrors.add(result);
             }
+            else if (invoice.isMigrationInvoice()) {
+            	log.info("Received invoice for payment that is a migration invoice - don't know how to handle those yet: {}", invoice);
+            	Either<PaymentError, PaymentInfo> result = Either.left(new PaymentError("migration invoice",
+                        "Invoice balance was a migration invoice",
+                        account.getId(),
+                        UUID.fromString(invoiceId)));
+            			processedPaymentsOrErrors.add(result);
+            }
             else {
                 PaymentAttempt paymentAttempt = paymentDao.createPaymentAttempt(invoice);
 
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 c5a40cf..7f3a5c2 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
@@ -108,7 +108,15 @@ public abstract class TestPaymentApi {
         assertTrue(paymentInfos.size() > 0);
 
         PaymentInfo paymentInfoFromGet = paymentInfos.get(0);
-        assertEquals(paymentInfo, paymentInfoFromGet);
+        assertEquals(paymentInfo.getAmount(), paymentInfoFromGet.getAmount());
+        assertEquals(paymentInfo.getRefundAmount(), paymentInfoFromGet.getRefundAmount());
+        assertEquals(paymentInfo.getPaymentId(), paymentInfoFromGet.getPaymentId());
+        assertEquals(paymentInfo.getPaymentNumber(), paymentInfoFromGet.getPaymentNumber());
+        assertEquals(paymentInfo.getStatus(), paymentInfoFromGet.getStatus());
+        assertEquals(paymentInfo.getBankIdentificationNumber(), paymentInfoFromGet.getBankIdentificationNumber());
+        assertEquals(paymentInfo.getReferenceId(), paymentInfoFromGet.getReferenceId());
+        assertEquals(paymentInfo.getPaymentMethodId(), paymentInfoFromGet.getPaymentMethodId());
+        assertEquals(paymentInfo.getEffectiveDate(), paymentInfoFromGet.getEffectiveDate());
 
         PaymentAttempt paymentAttemptFromGet = paymentApi.getPaymentAttemptForInvoiceId(invoice.getId().toString());
         assertEquals(paymentAttempt, paymentAttemptFromGet);
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 08c2a6d..600c64d 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestHelper.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
@@ -22,8 +22,7 @@ import java.util.UUID;
 import com.ning.billing.util.CallContext;
 import com.ning.billing.util.CallOrigin;
 import com.ning.billing.util.UserType;
-import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.entity.DefaultCallContext;
+import com.ning.billing.util.entity.CallContextFactory;
 import com.ning.billing.util.entity.EntityPersistenceException;
 import org.apache.commons.lang.RandomStringUtils;
 import org.joda.time.DateTime;
@@ -46,10 +45,10 @@ public class TestHelper {
     private final CallContext context;
 
     @Inject
-    public TestHelper(Clock clock, AccountDao accountDao, InvoiceDao invoiceDao) {
+    public TestHelper(CallContextFactory factory, AccountDao accountDao, InvoiceDao invoiceDao) {
         this.accountDao = accountDao;
         this.invoiceDao = invoiceDao;
-        context = new DefaultCallContext(clock, "Princess Buttercup", CallOrigin.TEST, UserType.TEST);
+        context = factory.createCallContext("Princess Buttercup", CallOrigin.TEST, UserType.TEST);
     }
 
     // These helper methods can be overridden in a plugin implementation

pom.xml 71(+46 -25)

diff --git a/pom.xml b/pom.xml
index c961bf5..9a6662e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,8 @@
     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">
     <parent>
         <groupId>org.sonatype.oss</groupId>
         <artifactId>oss-parent</artifactId>
@@ -17,7 +18,7 @@
     <groupId>com.ning.billing</groupId>
     <artifactId>killbill</artifactId>
     <packaging>pom</packaging>
-    <version>0.1.7-SNAPSHOT</version>
+    <version>0.1.8-SNAPSHOT</version>
     <name>killbill</name>
     <description>Library for managing recurring subscriptions and the associated billing</description>
     <url>http://github.com/ning/killbill</url>
@@ -332,16 +333,16 @@
                 </configuration>
             </plugin>
             <plugin>
-              <groupId>org.apache.maven.plugins</groupId>
-              <artifactId>maven-jar-plugin</artifactId>
-              <version>2.2</version>
-              <executions>
-                <execution>
-                  <goals>
-                    <goal>test-jar</goal>
-                  </goals>
-               </execution>
-              </executions>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.2</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
@@ -453,24 +454,44 @@
                 </configuration>
             </plugin>
             <plugin>
-              <groupId>org.apache.maven.plugins</groupId>
-              <artifactId>maven-source-plugin</artifactId>
-              <version>2.1.2</version>
-              <executions>
-                <execution>
-                  <id>attach-sources</id>
-                  <phase>verify</phase>
-                  <goals>
-                    <goal>jar</goal>
-                    <goal>test-jar</goal>
-                  </goals>
-                </execution>
-              </executions>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>2.1.2</version>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>jar</goal>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
             </plugin>
         </plugins>
     </build>
     <profiles>
         <profile>
+            <id>localtest</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <version>2.11</version>
+                        <configuration>
+                            <useManifestOnlyJar>false</useManifestOnlyJar>
+                            <systemPropertyVariables>
+                                <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/test_killbill</com.ning.billing.dbi.jdbc.url>
+                            </systemPropertyVariables>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
             <id>sonatype-oss-release</id>
             <build>
                 <plugins>

util/pom.xml 12(+1 -11)

diff --git a/util/pom.xml b/util/pom.xml
index cb834db..10cb192 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.7-SNAPSHOT</version>
+        <version>0.1.8-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-util</artifactId>
@@ -33,13 +33,8 @@
             <artifactId>jdbi</artifactId>
         </dependency>
         <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-        </dependency>
-        <dependency>
             <groupId>com.google.inject</groupId>
             <artifactId>guice</artifactId>
-            <version>3.0</version>
         </dependency>
         <dependency>
             <groupId>org.skife.config</groupId>
@@ -93,11 +88,6 @@
             <scope>runtime</scope>
         </dependency>
         <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>management-dbfiles</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>com.jayway.awaitility</groupId>
             <artifactId>awaitility</artifactId>
             <scope>test</scope>
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 ca8061f..318f3ba 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,8 +39,8 @@ public class AuditedCustomFieldDao {
         customFieldSqlDao.batchDeleteFromTransaction(objectId.toString(), objectType, existingFields, context);
 
         CustomFieldAuditSqlDao auditDao = dao.become(CustomFieldAuditSqlDao.class);
-  //      auditDao.batchInsertFromTransaction(objectId.toString(), objectType, fields, context);
-//        auditDao.batchUpdateFromTransaction(objectId.toString(), objectType, fieldsToUpdate, context);
+        auditDao.batchInsertFromTransaction(objectId.toString(), objectType, fields, context);
+        auditDao.batchUpdateFromTransaction(objectId.toString(), objectType, fieldsToUpdate, context);
         auditDao.batchDeleteFromTransaction(objectId.toString(), objectType, existingFields, context);
     }
 }
diff --git a/util/src/main/java/com/ning/billing/util/entity/CallContextBase.java b/util/src/main/java/com/ning/billing/util/entity/CallContextBase.java
new file mode 100644
index 0000000..0fec889
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/entity/CallContextBase.java
@@ -0,0 +1,32 @@
+package com.ning.billing.util.entity;
+
+import com.ning.billing.util.CallContext;
+import com.ning.billing.util.CallOrigin;
+import com.ning.billing.util.UserType;
+
+public abstract class CallContextBase implements CallContext {
+    private final String userName;
+    private final CallOrigin callOrigin;
+    private final UserType userType;
+
+    public CallContextBase(String userName, CallOrigin callOrigin, UserType userType) {
+        this.userName = userName;
+        this.callOrigin = callOrigin;
+        this.userType = userType;
+    }
+
+    @Override
+    public String getUserName() {
+        return userName;
+    }
+
+    @Override
+    public CallOrigin getCallOrigin() {
+        return callOrigin;
+    }
+
+    @Override
+    public UserType getUserType() {
+        return userType;
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/entity/CallContextBinder.java b/util/src/main/java/com/ning/billing/util/entity/CallContextBinder.java
index fb4ca6c..4c901bd 100644
--- a/util/src/main/java/com/ning/billing/util/entity/CallContextBinder.java
+++ b/util/src/main/java/com/ning/billing/util/entity/CallContextBinder.java
@@ -39,7 +39,8 @@ public @interface CallContextBinder {
                 @Override
                 public void bind(SQLStatement q, CallContextBinder bind, CallContext callContext) {
                     q.bind("userName", callContext.getUserName());
-                    q.bind("date", callContext.getUTCNow().toDate());
+                    q.bind("createdDate", callContext.getCreatedDate().toDate());
+                    q.bind("updatedDate", callContext.getUpdatedDate().toDate());
                 }
             };
         }
diff --git a/util/src/main/java/com/ning/billing/util/entity/CallContextFactory.java b/util/src/main/java/com/ning/billing/util/entity/CallContextFactory.java
new file mode 100644
index 0000000..231f345
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/entity/CallContextFactory.java
@@ -0,0 +1,29 @@
+package com.ning.billing.util.entity;
+
+import com.google.inject.Inject;
+import com.ning.billing.util.CallContext;
+import com.ning.billing.util.CallOrigin;
+import com.ning.billing.util.UserType;
+import com.ning.billing.util.clock.Clock;
+import org.joda.time.DateTime;
+
+public class CallContextFactory {
+    private final Clock clock;
+
+    @Inject
+    public CallContextFactory(Clock clock) {
+        this.clock = clock;
+    }
+
+    public CallContext createCallContext(String userName, CallOrigin callOrigin, UserType userType) {
+        return new DefaultCallContext(userName, callOrigin, userType, clock);
+    }
+
+    public CallContext createMigrationCallContext(String userName, CallOrigin callOrigin, UserType userType, DateTime createdDate, DateTime updatedDate) {
+        return new MigrationCallContext(userName, callOrigin, userType, createdDate, updatedDate);
+    }
+
+    public CallContext toMigrationCallContext(CallContext callContext, DateTime createdDate, DateTime updatedDate) {
+        return new MigrationCallContext(callContext, createdDate, updatedDate);
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/entity/DefaultCallContext.java b/util/src/main/java/com/ning/billing/util/entity/DefaultCallContext.java
index fea87c6..008cfb1 100644
--- a/util/src/main/java/com/ning/billing/util/entity/DefaultCallContext.java
+++ b/util/src/main/java/com/ning/billing/util/entity/DefaultCallContext.java
@@ -16,42 +16,28 @@
 
 package com.ning.billing.util.entity;
 
+import com.ning.billing.ErrorCode;
 import com.ning.billing.util.CallContext;
 import com.ning.billing.util.CallOrigin;
 import com.ning.billing.util.UserType;
 import com.ning.billing.util.clock.Clock;
 import org.joda.time.DateTime;
 
-public class DefaultCallContext implements CallContext {
+public class DefaultCallContext extends CallContextBase {
     private final Clock clock;
-    private final String userName;
-    private final CallOrigin callOrigin;
-    private final UserType userType;
 
-    public DefaultCallContext(Clock clock, String userName, CallOrigin callOrigin, UserType userType) {
+    public DefaultCallContext(String userName, CallOrigin callOrigin, UserType userType, Clock clock) {
+        super(userName, callOrigin, userType);
         this.clock = clock;
-        this.userName = userName;
-        this.callOrigin = callOrigin;
-        this.userType = userType;
     }
 
     @Override
-    public String getUserName() {
-        return userName;
-    }
-
-    @Override
-    public CallOrigin getCallOrigin() {
-        return callOrigin;
-    }
-
-    @Override
-    public UserType getUserType() {
-        return userType;
+    public DateTime getCreatedDate() {
+        return clock.getUTCNow();
     }
 
     @Override
-    public DateTime getUTCNow() {
+    public DateTime getUpdatedDate() {
         return clock.getUTCNow();
     }
-}
+}
\ No newline at end of file
diff --git a/util/src/main/java/com/ning/billing/util/entity/MigrationCallContext.java b/util/src/main/java/com/ning/billing/util/entity/MigrationCallContext.java
new file mode 100644
index 0000000..af0cb5c
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/entity/MigrationCallContext.java
@@ -0,0 +1,33 @@
+package com.ning.billing.util.entity;
+
+import com.ning.billing.util.CallContext;
+import com.ning.billing.util.CallOrigin;
+import com.ning.billing.util.UserType;
+import org.joda.time.DateTime;
+
+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) {
+        super(userName, callOrigin, userType);
+        this.createdDate = createdDate;
+        this.updatedDate = updatedDate;
+    }
+
+    public MigrationCallContext(CallContext context, DateTime createdDate, DateTime updatedDate) {
+        super(context.getUserName(), context.getCallOrigin(), context.getUserType());
+        this.createdDate = createdDate;
+        this.updatedDate = updatedDate;
+    }
+
+    @Override
+    public DateTime getCreatedDate() {
+        return createdDate;
+    }
+
+    @Override
+    public DateTime getUpdatedDate() {
+        return updatedDate;
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java
index 42d0f15..0c6ce0c 100644
--- a/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/tag/api/DefaultTagDefinitionUserApi.java
@@ -52,4 +52,10 @@ public class DefaultTagDefinitionUserApi implements TagDefinitionUserApi {
     public void deleteTagDefinition(final String definitionName, final CallContext context) throws TagDefinitionApiException {
         dao.deleteAllTagsForDefinition(definitionName, context);
     }
+
+	@Override
+	public TagDefinition getTagDefinition(String name)
+			throws TagDefinitionApiException {
+		return dao.getByName(name);
+	}
 }
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
index 74a998f..fb6d827 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/DefaultTagDefinitionDao.java
@@ -20,10 +20,10 @@ import java.util.ArrayList;
 import java.util.List;
 
 import com.ning.billing.util.CallContext;
+import com.ning.billing.util.tag.ControlTagType;
 import org.skife.jdbi.v2.IDBI;
 import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
-import com.ning.billing.account.api.ControlTagType;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.tag.DefaultTagDefinition;
 import com.ning.billing.util.tag.TagDefinition;
diff --git a/util/src/main/java/com/ning/billing/util/tag/dao/TagMapper.java b/util/src/main/java/com/ning/billing/util/tag/dao/TagMapper.java
index 1721550..e134f9c 100644
--- a/util/src/main/java/com/ning/billing/util/tag/dao/TagMapper.java
+++ b/util/src/main/java/com/ning/billing/util/tag/dao/TagMapper.java
@@ -24,7 +24,8 @@ import com.ning.billing.util.entity.MapperBase;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
-import com.ning.billing.account.api.ControlTagType;
+
+import com.ning.billing.util.tag.ControlTagType;
 import com.ning.billing.util.tag.DefaultControlTag;
 import com.ning.billing.util.tag.DescriptiveTag;
 import com.ning.billing.util.tag.Tag;
diff --git a/util/src/main/java/com/ning/billing/util/tag/DefaultControlTag.java b/util/src/main/java/com/ning/billing/util/tag/DefaultControlTag.java
index 8a2af8f..662de60 100644
--- a/util/src/main/java/com/ning/billing/util/tag/DefaultControlTag.java
+++ b/util/src/main/java/com/ning/billing/util/tag/DefaultControlTag.java
@@ -17,7 +17,6 @@
 package com.ning.billing.util.tag;
 
 import java.util.UUID;
-import com.ning.billing.account.api.ControlTagType;
 import org.joda.time.DateTime;
 
 public class DefaultControlTag extends DescriptiveTag implements ControlTag {
diff --git a/util/src/main/java/com/ning/billing/util/tag/DefaultTagStore.java b/util/src/main/java/com/ning/billing/util/tag/DefaultTagStore.java
index 2fd8144..eace017 100644
--- a/util/src/main/java/com/ning/billing/util/tag/DefaultTagStore.java
+++ b/util/src/main/java/com/ning/billing/util/tag/DefaultTagStore.java
@@ -17,7 +17,6 @@
 package com.ning.billing.util.tag;
 
 import java.util.UUID;
-import com.ning.billing.account.api.ControlTagType;
 import com.ning.billing.util.entity.EntityCollectionBase;
 
 public class DefaultTagStore extends EntityCollectionBase<Tag> implements TagStore {
@@ -39,7 +38,7 @@ public class DefaultTagStore extends EntityCollectionBase<Tag> implements TagSto
         for (Tag tag : entities.values()) {
             if (tag instanceof ControlTag) {
                 ControlTag controlTag = (ControlTag) tag;
-                if (controlTag.getControlTagType() == ControlTagType.AUTO_BILLING_OFF) {
+                if (controlTag.getControlTagType() == ControlTagType.AUTO_PAY_OFF) {
                     return false;
                 }
             }
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 a0878d8..f693848 100644
--- a/util/src/main/resources/com/ning/billing/util/ddl.sql
+++ b/util/src/main/resources/com/ning/billing/util/ddl.sql
@@ -42,7 +42,7 @@ CREATE UNIQUE INDEX tag_definitions_name ON tag_definitions(name);
 DROP TABLE IF EXISTS tag_definition_history;
 CREATE TABLE tag_definition_history (
   id char(36) NOT NULL,
-  name varchar(20) NOT NULL,
+  name varchar(30) NOT NULL,
   created_by varchar(50),
   description varchar(200),
   change_type char(6) NOT NULL,
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 d83c033..68566d2 100644
--- a/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
+++ b/util/src/test/java/com/ning/billing/dbi/DBIProvider.java
@@ -57,6 +57,7 @@ public class DBIProvider implements Provider<IDBI>
         dbConfig.setPartitionCount(1);
         dbConfig.setDefaultTransactionIsolation("REPEATABLE_READ");
         dbConfig.setDisableJMX(false);
+        dbConfig.setLazyInit(true);
 
         final BoneCPDataSource ds = new BoneCPDataSource(dbConfig);
         final DBI dbi = new DBI(ds);
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 93b62df..866289e 100644
--- a/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
+++ b/util/src/test/java/com/ning/billing/dbi/MysqlTestingHelper.java
@@ -110,11 +110,6 @@ public class MysqlTestingHelper
             return;
         }
 
-        if (mysqldResource == null || !mysqldResource.isRunning()) {
-            log.error("Asked to cleanup table " + table + " but MySQL is not running!");
-            return;
-        }
-
         log.info("Deleting table: " + table);
         final IDBI dbi = getDBI();
         dbi.withHandle(new HandleCallback<Void>()
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 2998d07..7404331 100644
--- a/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
+++ b/util/src/test/java/com/ning/billing/mock/BrainDeadProxyFactory.java
@@ -27,6 +27,8 @@ import org.slf4j.LoggerFactory;
 
 public class BrainDeadProxyFactory {
     private static final Logger log = LoggerFactory.getLogger(BrainDeadProxyFactory.class);
+    
+    public static final Object ZOMBIE_VOID = new Object(); 
 
     public static interface ZombieControl {
 
@@ -59,7 +61,12 @@ public class BrainDeadProxyFactory {
                 } else {
 
                     Object result = results.get(method.getName());
-                    if (result != null) {
+                    if (result == ZOMBIE_VOID) {
+                    	return (Void) null;
+                    } else if (result != null) {
+                    	if(result instanceof Throwable) {
+                    		throw ((Throwable) result);
+                    	}
                         return result;
                     } else {
                         log.error(String.format("No result for Method: '%s' on Class '%s'",method.getName(), method.getDeclaringClass().getName()));
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 d748e1a..bd650d5 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
@@ -28,7 +28,7 @@ import com.ning.billing.util.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.MockClockModule;
 import com.ning.billing.util.customfield.dao.AuditedCustomFieldDao;
-import com.ning.billing.util.entity.DefaultCallContext;
+import com.ning.billing.util.entity.CallContextFactory;
 import com.ning.billing.util.glue.FieldStoreModule;
 import org.apache.commons.io.IOUtils;
 import org.skife.jdbi.v2.IDBI;
@@ -64,7 +64,7 @@ public class TestFieldStore {
             FieldStoreModule module = new FieldStoreModule();
             final Injector injector = Guice.createInjector(Stage.DEVELOPMENT, module, new MockClockModule());
             Clock clock = injector.getInstance(Clock.class);
-            context = new DefaultCallContext(clock, "Fezzik", CallOrigin.TEST, UserType.TEST);
+            context = new CallContextFactory(clock).createCallContext("Fezzik", CallOrigin.TEST, UserType.TEST);
 
         }
         catch (Throwable t) {
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 f693103..9f60162 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,6 +19,7 @@ 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;
@@ -49,8 +50,9 @@ public class TestMysqlGlobalLocker {
 
     @BeforeClass(alwaysRun=true)
     public void setup() throws IOException  {
+        final String testDdl = IOUtils.toString(TestMysqlGlobalLocker.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
         helper.startMysql();
-        createSimpleTable(dbi);
+        helper.initDb(testDdl);
     }
 
     @AfterClass(alwaysRun=true)
@@ -71,7 +73,7 @@ public class TestMysqlGlobalLocker {
             @Override
             public Void inTransaction(Handle conn, TransactionStatus status)
                     throws Exception {
-                conn.execute("insert into dummy (dummy_id, value) values ('" + UUID.randomUUID().toString()  + "', 'test')");
+                conn.execute("insert into dummy2 (dummy_id) values ('" + UUID.randomUUID().toString()  + "')");
                 return null;
             }
         });
@@ -90,25 +92,6 @@ public class TestMysqlGlobalLocker {
         Assert.assertEquals(locker.isFree(LockerService.INVOICE, lockName), Boolean.TRUE);
     }
 
-    private void createSimpleTable(IDBI dbi) {
-        dbi.inTransaction(new TransactionCallback<Void>() {
-
-            @Override
-            public Void inTransaction(Handle h, TransactionStatus status)
-                    throws Exception {
-                h.execute("DROP TABLE IF EXISTS dummy;");
-
-                h.execute("create table dummy " +
-                        "(id int(11) unsigned NOT NULL AUTO_INCREMENT, " +
-                        "dummy_id char(36) NOT NULL, " +
-                        "value varchar(256) NOT NULL," +
-                        "PRIMARY KEY(id)" +
-                		") ENGINE=innodb;");
-                return null;
-            }
-        });
-    }
-
     public final static class TestMysqlGlobalLockerModule extends AbstractModule {
 
         @Override
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 cb01e00..4c812cb 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
@@ -59,8 +59,6 @@ public class TestNotificationSqlDao {
     private NotificationSqlDao dao;
 
     private void startMysql() throws IOException, ClassNotFoundException, SQLException {
-
-
         final String ddl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
         helper.startMysql();
         helper.initDb(ddl);
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 9a94721..1c40988 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
@@ -89,15 +89,16 @@ public class MockNotificationQueue extends NotificationQueueBase implements Noti
                     readyNotifications.add(cur);
                 }
             }
+        }
 
-            result = readyNotifications.size();
-            for (Notification cur : readyNotifications) {
-                handler.handleReadyNotification(cur.getNotificationKey(), cur.getEffectiveDate());
-                DefaultNotification processedNotification = new DefaultNotification(-1L, cur.getUUID(), hostname, "MockQueue", clock.getUTCNow().plus(config.getDaoClaimTimeMs()), NotificationLifecycleState.PROCESSED, cur.getNotificationKey(), cur.getEffectiveDate());
-                oldNotifications.add(cur);
-                processedNotifications.add(processedNotification);
-
-            }
+        result = readyNotifications.size();
+        for (Notification cur : readyNotifications) {
+            handler.handleReadyNotification(cur.getNotificationKey(), cur.getEffectiveDate());
+            DefaultNotification processedNotification = new DefaultNotification(-1L, cur.getUUID(), hostname, "MockQueue", clock.getUTCNow().plus(config.getDaoClaimTimeMs()), NotificationLifecycleState.PROCESSED, cur.getNotificationKey(), cur.getEffectiveDate());
+            oldNotifications.add(cur);
+            processedNotifications.add(processedNotification);
+        }
+        synchronized(notifications) {
             if (oldNotifications.size() > 0) {
                 notifications.removeAll(oldNotifications);
             }
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 fbcf8f9..09862e9 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
@@ -39,6 +39,7 @@ import org.skife.jdbi.v2.tweak.HandleCallback;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
+import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeSuite;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Guice;
@@ -86,6 +87,11 @@ public class TestNotificationQueue {
 		startMysql();
 		dao = dbi.onDemand(DummySqlTest.class);
 	}
+	
+    @AfterClass(alwaysRun = true)
+    public void tearDown() {
+    	helper.stopMysql();
+    }
 
 	@BeforeTest
 	public void beforeTest() {
@@ -373,7 +379,7 @@ public class TestNotificationQueue {
 
 		Assert.assertTrue(expectedNotificationsFred.get(notificationKeyFred.toString()));
 		Assert.assertFalse(expectedNotificationsFred.get(notificationKeyBarney.toString()));
-
+		queueFred.stopQueue();
 	}
 
 	NotificationConfig getNotificationConfig(final boolean off,
diff --git a/util/src/test/java/com/ning/billing/util/tag/TagStoreModuleMock.java b/util/src/test/java/com/ning/billing/util/tag/TagStoreModuleMock.java
index a3a8b5a..6c972d4 100644
--- a/util/src/test/java/com/ning/billing/util/tag/TagStoreModuleMock.java
+++ b/util/src/test/java/com/ning/billing/util/tag/TagStoreModuleMock.java
@@ -16,33 +16,24 @@
 
 package com.ning.billing.util.tag;
 
-import java.io.IOException;
 
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
 
 import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.util.clock.MockClockModule;
 import com.ning.billing.util.glue.TagStoreModule;
 import org.skife.jdbi.v2.tweak.HandleCallback;
 
 public class TagStoreModuleMock extends TagStoreModule {
-    private final MysqlTestingHelper helper = new MysqlTestingHelper();
-
-    public void startDb() throws IOException {
-        helper.startMysql();
-    }
-
-    public void initDb(String ddl) throws IOException {
-        helper.initDb(ddl);
-    }
-
-    public void stopDb() {
-        helper.stopMysql();
-    }
+    private MysqlTestingHelper helper;
 
     @Override
     protected void configure() {
+        helper = new MysqlTestingHelper();
         bind(IDBI.class).toInstance(helper.getDBI());
+        bind(MysqlTestingHelper.class).toInstance(helper);
+        install(new MockClockModule());
         super.configure();
     }
 
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 618dc14..6e9dcfd 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
@@ -23,27 +23,25 @@ import java.util.Map;
 import java.util.UUID;
 
 import com.ning.billing.util.CallContext;
-import com.ning.billing.util.CallOrigin;
-import com.ning.billing.util.UserType;
 import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.entity.DefaultCallContext;
 import com.ning.billing.util.tag.dao.AuditedTagDao;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.joda.time.Seconds;
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
+import org.skife.jdbi.v2.tweak.HandleCallback;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testng.annotations.Guice;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
-import com.ning.billing.account.api.ControlTagType;
+
+import com.google.inject.Inject;
+import com.ning.billing.dbi.MysqlTestingHelper;
+
 import com.ning.billing.util.api.TagDefinitionApiException;
-import com.ning.billing.util.clock.MockClockModule;
 import com.ning.billing.util.tag.dao.TagDefinitionDao;
 import com.ning.billing.util.tag.dao.TagSqlDao;
 
@@ -53,15 +51,31 @@ import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
-@Test(groups={"util"})
+
+@Test(groups={"slow"})
+@Guice(modules = TagStoreModuleMock.class)
 public class TestTagStore {
     private final static String ACCOUNT_TYPE = "ACCOUNT";
+
+    @Inject
+    private MysqlTestingHelper helper;
+
+    @Inject
     private IDBI dbi;
-    private TagDefinition tag1;
-    private TagDefinition tag2;
-    private TagStoreModuleMock module;
+
+    @Inject
     private TagSqlDao tagSqlDao;
+
+    @Inject
     private TagDefinitionDao tagDefinitionDao;
+
+    @Inject
+    private Clock clock;
+
+    private TagDefinition tag1;
+    private TagDefinition tag2;
+
+
     private final Logger log = LoggerFactory.getLogger(TestTagStore.class);
     private CallContext context;
 
@@ -69,26 +83,16 @@ public class TestTagStore {
     protected void setup() throws IOException {
         // Health check test to make sure MySQL is setup properly
         try {
-            module = new TagStoreModuleMock();
             final String utilDdl = IOUtils.toString(TestTagStore.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
 
-            module.startDb();
-            module.initDb(utilDdl);
-
-            final Injector injector = Guice.createInjector(Stage.DEVELOPMENT, module, new MockClockModule());
-            dbi = injector.getInstance(IDBI.class);
-
-            tagSqlDao = injector.getInstance(TagSqlDao.class);
+            helper.startMysql();
+            helper.initDb(utilDdl);
             tagSqlDao.test();
 
-            module.execute("truncate tag_definitions;");
-
-            Clock clock = injector.getInstance(Clock.class);
-            context = new DefaultCallContext(clock, "Inigo Montoya", CallOrigin.TEST, UserType.TEST);
-
-            tagDefinitionDao = injector.getInstance(TagDefinitionDao.class);
+            cleanupTags();
             tag1 = tagDefinitionDao.create("tag1", "First tag", context);
             tag2 = tagDefinitionDao.create("tag2", "Second tag", context);
+
         }
         catch (Throwable t) {
             log.error("Failed to start tag store tests", t);
@@ -99,7 +103,7 @@ public class TestTagStore {
     @AfterClass(alwaysRun = true)
     public void stopMysql()
     {
-        module.stopDb();
+        helper.stopMysql();
     }
 
     private void saveTags(final TagSqlDao dao, final String objectType, final UUID accountId,
@@ -108,6 +112,22 @@ public class TestTagStore {
         auditedTagDao.saveTags(dao, accountId, objectType, tagList, context);
     }
 
+
+    private void cleanupTags() {
+        try {
+            helper.getDBI().withHandle(new HandleCallback<Void>() {
+                @Override
+                public Void withHandle(Handle handle) throws Exception {
+                    handle.createScript("delete from tag_definitions").execute();
+                    handle.createScript("delete from tag_definition_history").execute();
+                    handle.createScript("delete from tags").execute();
+                    handle.createScript("delete from tag_history").execute();
+                    return null;
+                }
+            });
+        } catch (Throwable ignore) {
+        }
+    }
     @Test
     public void testTagCreationAndRetrieval() {
         UUID accountId = UUID.randomUUID();
@@ -225,7 +245,7 @@ public class TestTagStore {
         assertEquals(tagStore.generateInvoice(), false);
         assertEquals(tagStore.processPayment(), true);
 
-        ControlTag paymentTag = new DefaultControlTag(ControlTagType.AUTO_BILLING_OFF);
+        ControlTag paymentTag = new DefaultControlTag(ControlTagType.AUTO_PAY_OFF);
         tagStore.add(paymentTag);
         assertEquals(tagStore.generateInvoice(), false);
         assertEquals(tagStore.processPayment(), false);
@@ -233,7 +253,7 @@ public class TestTagStore {
 
     @Test(expectedExceptions = TagDefinitionApiException.class)
     public void testTagDefinitionCreationWithControlTagName() throws TagDefinitionApiException {
-        String definitionName = ControlTagType.AUTO_BILLING_OFF.toString();
+        String definitionName = ControlTagType.AUTO_PAY_OFF.toString();
         tagDefinitionDao.create(definitionName, "This should break", context);
     }
 
@@ -388,7 +408,7 @@ public class TestTagStore {
         assertEquals(result.get(0).get("change_type"), "INSERT");
         assertNotNull(result.get(0).get("change_date"));
         DateTime changeDate = new DateTime(result.get(0).get("change_date"));
-        assertTrue(Seconds.secondsBetween(changeDate, context.getUTCNow()).getSeconds() < 2);
+        assertTrue(Seconds.secondsBetween(changeDate, context.getCreatedDate()).getSeconds() < 2);
         assertEquals(result.get(0).get("changed_by"), context.getUserName());
     }
 
@@ -415,7 +435,7 @@ public class TestTagStore {
         assertEquals(result.size(), 1);
         assertNotNull(result.get(0).get("change_date"));
         DateTime changeDate = new DateTime(result.get(0).get("change_date"));
-        assertTrue(Seconds.secondsBetween(changeDate, context.getUTCNow()).getSeconds() < 2);
+        assertTrue(Seconds.secondsBetween(changeDate, context.getUpdatedDate()).getSeconds() < 2);
         assertEquals(result.get(0).get("changed_by"), context.getUserName());
     }
 
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 b7e5bc6..bb7ac85 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
@@ -17,7 +17,10 @@
 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 org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.IDBI;
 import org.testng.annotations.AfterClass;
@@ -38,7 +41,7 @@ public class TestValidationManager {
     private static final String TABLE_NAME = "validation_test";
 
     private ValidationManager vm;
-    
+
     @BeforeClass(alwaysRun = true)
     public void setup() throws IOException {
         setupDatabase();
@@ -53,11 +56,9 @@ public class TestValidationManager {
     }
 
     private void setupDatabase() throws IOException {
+        final String testDdl = IOUtils.toString(TestMysqlGlobalLocker.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
         helper.startMysql();
-        StringBuilder ddl = new StringBuilder();
-        ddl.append(String.format("DROP TABLE IF EXISTS %s;", TABLE_NAME));
-        ddl.append(String.format("CREATE TABLE %s (column1 varchar(25), column2 char(2) NOT NULL, column3 numeric(10,4), column4 datetime) ENGINE = innodb;", TABLE_NAME));
-        helper.initDb(ddl.toString());
+        helper.initDb(testDdl);
     }
 
     @AfterClass(alwaysRun = true)
diff --git a/util/src/test/resources/com/ning/billing/util/ddl_test.sql b/util/src/test/resources/com/ning/billing/util/ddl_test.sql
index 50de498..1322a02 100644
--- a/util/src/test/resources/com/ning/billing/util/ddl_test.sql
+++ b/util/src/test/resources/com/ning/billing/util/ddl_test.sql
@@ -4,3 +4,18 @@ CREATE TABLE dummy (
     value varchar(256) NOT NULL,
     PRIMARY KEY(dummy_id)
 ) ENGINE = innodb;
+
+DROP TABLE IF EXISTS dummy2;
+CREATE TABLE dummy2 (
+    id int(11) unsigned NOT NULL AUTO_INCREMENT,
+    dummy_id char(36) NOT NULL,
+    PRIMARY KEY(id)
+) ENGINE = innodb;
+
+DROP TABLE IF EXISTS validation_test;
+CREATE TABLE validation_test (
+    column1 varchar(25),
+    column2 char(2) NOT NULL,
+    column3 numeric(10,4),
+    column4 datetime
+) ENGINE = innodb;