killbill-aplcache

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

3/15/2012 10:13:21 PM

Changes

Details

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 3e9074f..e9f7f49 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
@@ -112,7 +112,7 @@ public class DefaultAccountUserApi implements com.ning.billing.account.api.Accou
 			List<CustomField> fields, List<Tag> tags)
 			throws AccountApiException {
 		
-		Account account = new DefaultAccount(data);
+		Account account = new DefaultAccount(data, data.getCreatedDate(), data.getUpdatedDate());
         account.addFields(fields);
         account.addTags(tags);
 
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
index 3fb159f..dfa9b89 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountSqlDao.java
@@ -27,7 +27,6 @@ import java.sql.Timestamp;
 import java.util.Date;
 import java.util.UUID;
 
-import com.ning.billing.util.entity.UpdatableEntityDao;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.SQLStatement;
@@ -48,7 +47,7 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.user.AccountBuilder;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.util.UuidMapper;
-import com.ning.billing.util.entity.EntityDao;
+import com.ning.billing.util.entity.UpdatableEntityDao;
 
 @ExternalizedSqlViaStringTemplate3
 @RegisterMapper({UuidMapper.class, AccountSqlDao.AccountMapper.class})
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/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 75337e3..0ee9cd8 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
@@ -24,8 +24,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 0bd985c..125eed1 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
@@ -17,7 +17,7 @@
 package com.ning.billing.util.api;
 
 import java.util.List;
-import java.util.UUID;
+
 import com.ning.billing.util.tag.TagDefinition;
 
 public interface TagDefinitionUserApi {
@@ -50,4 +50,13 @@ public interface TagDefinitionUserApi {
      * @throws TagDefinitionApiException
      */
     public void deleteTagDefinition(String definitionName) throws TagDefinitionApiException;
+
+    
+	/**
+	 * 
+	 * @param name
+	 * @return the tag with this definition
+     * @throws TagDefinitionApiException
+	 */
+	public TagDefinition getTagDefinition(String name) throws TagDefinitionApiException;
 }
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 78655e1..8b4cd27 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
@@ -169,6 +169,7 @@ public class TestIntegration {
         lifecycle.fireShutdownSequencePriorEventUnRegistration();
         busService.getBus().unregister(busHandler);
         lifecycle.fireShutdownSequencePostEventUnRegistration();
+        helper.stopMysql();
     }
 
 
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/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/TestApiBase.java
index 854e5b4..9bcb002 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
@@ -124,7 +124,7 @@ public abstract class TestApiBase {
         } catch (Exception e) {
             log.warn("Failed to tearDown test properly ", e);
         }
-
+        //if(helper != null) { helper.stopMysql(); }
     }
 
     @BeforeClass(alwaysRun=true)
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 085afb9..31879e0 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
@@ -29,11 +29,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;
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..6852b69
--- /dev/null
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/migration/DefaultInvoiceMigrationApi.java
@@ -0,0 +1,53 @@
+/*
+ * 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 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.DefaultInvoice;
+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) {
+		Invoice migrationInvoice = new DefaultInvoice(accountId, targetDate, currency, clock, true);
+		InvoiceItem migrationInvoiceItem = new MigrationInvoiceItem(migrationInvoice.getId(), targetDate, balance, currency, clock);
+		migrationInvoice.addInvoiceItem(migrationInvoiceItem);
+		dao.create(migrationInvoice);
+		return migrationInvoice.getId();
+	}
+}
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 1800154..8e34ec9 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
@@ -41,11 +41,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 f797ff5..03970d0 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
@@ -17,7 +17,6 @@
 package com.ning.billing.invoice.dao;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
@@ -47,8 +46,6 @@ public class DefaultInvoiceDao implements InvoiceDao {
     private final static Logger log = LoggerFactory.getLogger(DefaultInvoiceDao.class);
 
     private final InvoiceSqlDao invoiceSqlDao;
-    private final RecurringInvoiceItemSqlDao recurringInvoiceItemSqlDao;
-    private final FixedPriceInvoiceItemSqlDao fixedPriceInvoiceItemSqlDao;
     private final InvoicePaymentSqlDao invoicePaymentSqlDao;
     private final EntitlementBillingApi entitlementBillingApi;
 
@@ -61,8 +58,6 @@ public class DefaultInvoiceDao implements InvoiceDao {
                              final EntitlementBillingApi entitlementBillingApi,
                              NextBillingDatePoster nextBillingDatePoster) {
         this.invoiceSqlDao = dbi.onDemand(InvoiceSqlDao.class);
-        this.recurringInvoiceItemSqlDao = dbi.onDemand(RecurringInvoiceItemSqlDao.class);
-        this.fixedPriceInvoiceItemSqlDao = dbi.onDemand(FixedPriceInvoiceItemSqlDao.class);
         this.invoicePaymentSqlDao = dbi.onDemand(InvoicePaymentSqlDao.class);
         this.eventBus = eventBus;
         this.entitlementBillingApi = entitlementBillingApi;
@@ -85,6 +80,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
@@ -193,11 +203,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());
     }
@@ -306,4 +311,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 08f6e06..e09b9d2 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
@@ -38,9 +38,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);
@@ -52,4 +49,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 36a2ee3..61c3644 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
@@ -58,6 +58,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,
@@ -82,6 +85,8 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
     @SqlQuery
     List<Invoice> getUnpaidInvoicesByAccountId(@Bind("accountId") final String accountId,
                                                @Bind("upToDate") final Date upToDate);
+    
+    
 
     @BindingAnnotation(InvoiceBinder.InvoiceBinderFactory.class)
     @Retention(RetentionPolicy.RUNTIME)
@@ -98,6 +103,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());
                     }
                 };
             }
@@ -113,8 +119,9 @@ 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");
 
-            return new DefaultInvoice(id, accountId, invoiceNumber, invoiceDate, targetDate, currency);
+            return new DefaultInvoice(id, accountId, invoiceNumber, invoiceDate, targetDate, currency, isMigrationInvoice);
         }
     }
 
@@ -137,5 +144,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/model/DefaultInvoice.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoice.java
index 72921c3..ed8f42d 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,21 @@
 
 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.clock.Clock;
-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 implements Invoice {
     private final InvoiceItemList invoiceItems = new InvoiceItemList();
@@ -38,19 +41,30 @@ public class DefaultInvoice implements Invoice {
     private final DateTime invoiceDate;
     private final DateTime targetDate;
     private final Currency currency;
+    private final boolean migrationInvoice;
 
     public DefaultInvoice(UUID accountId, DateTime targetDate, Currency currency, Clock clock) {
         this(UUID.randomUUID(), accountId, null, clock.getUTCNow(), targetDate, currency);
     }
 
+    public DefaultInvoice(UUID accountId, DateTime targetDate, Currency currency, Clock clock, boolean migrationInvoice) {
+        this(UUID.randomUUID(), accountId, null, clock.getUTCNow(), targetDate, currency, migrationInvoice);
+    }
+
     public DefaultInvoice(UUID invoiceId, UUID accountId, @Nullable Integer invoiceNumber, DateTime invoiceDate, DateTime targetDate,
                           Currency currency) {
+    	this(invoiceId, accountId, invoiceNumber, invoiceDate, targetDate, currency, false);
+    }
+    
+    public DefaultInvoice(UUID invoiceId, UUID accountId, @Nullable Integer invoiceNumber,DateTime invoiceDate, DateTime targetDate,
+                Currency currency, boolean migrationInvoice) {
         this.id = invoiceId;
         this.accountId = accountId;
         this.invoiceNumber = invoiceNumber;
         this.invoiceDate = invoiceDate;
         this.targetDate = targetDate;
         this.currency = currency;
+        this.migrationInvoice = migrationInvoice;
     }
 
     @Override
@@ -69,10 +83,10 @@ public class DefaultInvoice 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);
             }
         }
@@ -137,8 +151,13 @@ public class DefaultInvoice 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..3910ad7
--- /dev/null
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/MigrationInvoiceItem.java
@@ -0,0 +1,37 @@
+/*
+ * 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, Clock clock) {
+		super(invoiceId, MIGRATION_SUBSCRIPTION_ID, MigrationPlan.MIGRATION_PLAN_NAME, MigrationPlan.MIGRATION_PLAN_PHASE_NAME, startDate, startDate,
+				amount, currency, clock.getUTCNow());
+	}
+
+	
+}
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 203be9e..51347fb 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) ::= <<
@@ -14,7 +15,8 @@ invoiceSetFields(prefix) ::= <<
     <prefix>account_id,
     <prefix>invoice_date,
     <prefix>target_date,
-    <prefix>currency
+    <prefix>currency,
+    <prefix>migrated
 >>
 
 get() ::= <<
@@ -26,6 +28,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;
 >>
@@ -33,7 +42,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;
 >>
 
@@ -41,18 +50,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.")>;
 >>
 
@@ -74,7 +72,7 @@ getAccountBalance() ::= <<
 
 create() ::= <<
   INSERT INTO invoices(<invoiceSetFields()>)
-  VALUES (:id, :accountId, :invoiceDate, :targetDate, :currency);
+  VALUES (:id, :accountId, :invoiceDate, :targetDate, :currency, :migrated);
 >>
 
 getInvoiceIdByPaymentAttemptId() ::= <<
@@ -89,7 +87,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 503ec7f..88f7595 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,
   PRIMARY KEY(invoice_number)
 ) ENGINE=innodb;
 CREATE INDEX invoices_invoice_number ON invoices(invoice_number ASC);
@@ -73,7 +74,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..ff60d06
--- /dev/null
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/TestDefaultInvoiceMigrationApi.java
@@ -0,0 +1,250 @@
+/*
+ * 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 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 now;
+
+	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;
+
+
+
+	@BeforeClass(alwaysRun = true)
+	public void setup() throws Exception
+	{
+		log.info("Starting set up");
+		accountId = UUID.randomUUID();
+		subscriptionId = UUID.randomUUID();
+		now = new ClockMock().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, now, 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(now), 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);
+
+		DateTime target = new DateTime();
+
+		InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, entitlementBillingApi, invoiceDao, locker);
+
+		Invoice invoice = dispatcher.processAccount(accountId, target, true);
+		Assert.assertNotNull(invoice);
+
+		List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
+		Assert.assertEquals(invoices.size(),0);
+
+		invoice = dispatcher.processAccount(accountId, target, false);
+		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, now.minusDays(1));
+		Assert.assertEquals(byAccountAndDate.size(),1);
+		Assert.assertEquals(byAccountAndDate.get(0).getId(), regularInvoiceId);
+
+		Collection<Invoice> unpaid = invoiceUserApi.getUnpaidInvoicesByAccountId(accountId, now.plusDays(1));
+		Assert.assertEquals(unpaid.size(),1);
+		Assert.assertEquals(unpaid.iterator().next().getId(), regularInvoiceId);
+
+	}
+
+
+	// 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 eabcc26..9249420 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
@@ -42,6 +42,7 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
     protected RecurringInvoiceItemSqlDao recurringInvoiceItemDao;
     protected InvoicePaymentSqlDao invoicePaymentDao;
     protected InvoiceModuleWithEmbeddedDb module;
+    private BusService busService;
 
     @BeforeClass(alwaysRun = true)
     protected void setup() throws IOException {
@@ -65,8 +66,8 @@ public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
             recurringInvoiceItemDao = module.getInvoiceItemSqlDao();
 
             invoicePaymentDao = module.getInvoicePaymentSqlDao();
-
-            BusService busService = injector.getInstance(BusService.class);
+            
+            busService = injector.getInstance(BusService.class);
             ((DefaultBusService) busService).startBus();
 
             assertTrue(true);
@@ -105,6 +106,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 2289a78..ef70c33 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
@@ -157,102 +157,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         assertEquals(invoice.getLastPaymentAttempt().compareTo(paymentAttemptDate), 0);
     }
 
-    @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, targetDate, Currency.USD, clock);
-
-        invoiceDao.create(invoice);
-        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, targetDate, Currency.USD, clock);
-
-        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, clock.getUTCNow());
-        invoice.addInvoiceItem(item);
-        invoiceDao.create(invoice);
-
-        // 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>();
 
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 893912f..031e02a 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
@@ -77,7 +77,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);
                 }
             }
@@ -91,7 +91,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);
                 }
             }
@@ -107,7 +107,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;
                     }
@@ -118,21 +118,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() {
     }
 
@@ -193,11 +178,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 fdc5076..d82c2d9 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
@@ -34,6 +34,7 @@ import org.skife.jdbi.v2.TransactionStatus;
 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.Test;
 
@@ -191,4 +192,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 209d889..e81b916 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/TestInvoiceDispatcher.java
@@ -25,7 +25,10 @@ import java.util.UUID;
 
 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;
@@ -33,12 +36,10 @@ 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;
@@ -57,106 +58,119 @@ 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;
 
 
 
-    @BeforeSuite(alwaysRun = true)
-    public void setup() throws IOException
-    {
+	@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"));
+		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();
+		helper.startMysql();
 
-        helper.initDb(accountDdl);
-        helper.initDb(entitlementDdl);
-        helper.initDb(invoiceDdl);
-//        helper.initDb(paymentDdl);
-        helper.initDb(utilDdl);
-        notifier.initialize();
-        notifier.start();
+		helper.initDb(accountDdl);
+		helper.initDb(entitlementDdl);
+		helper.initDb(invoiceDdl);
+		//        helper.initDb(paymentDdl);
+		helper.initDb(utilDdl);
+		notifier.initialize();
+		notifier.start();
 
-        busService.getBus().start();
-    }
+		busService.getBus().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);
+		}
 
-	    @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);
+	@Test(groups={"fast"}, enabled=true)
+	public void testDryrunInvoice() throws InvoiceApiException {
+		UUID accountId = UUID.randomUUID();
+		UUID subscriptionId = UUID.randomUUID();
 
-	    	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));
+		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);
 
-	    	EntitlementBillingApi entitlementBillingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementBillingApi.class);
-	    	((ZombieControl)entitlementBillingApi).addResult("getBillingEventsForAccount", events);
+		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));
 
-	    	DateTime target = new DateTime();
+		EntitlementBillingApi entitlementBillingApi = BrainDeadProxyFactory.createBrainDeadProxyFor(EntitlementBillingApi.class);
+		((ZombieControl)entitlementBillingApi).addResult("getBillingEventsForAccount", events);
 
-	    	InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, entitlementBillingApi, invoiceDao, locker);
+		DateTime target = new DateTime();
 
-	    	Invoice invoice = dispatcher.processAccount(accountId, target, true);
-	    	Assert.assertNotNull(invoice);
+		InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountUserApi, entitlementBillingApi, invoiceDao, locker);
 
-	    	List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
-	    	Assert.assertEquals(invoices.size(),0);
+		Invoice invoice = dispatcher.processAccount(accountId, target, true);
+		Assert.assertNotNull(invoice);
 
-	    	// Try it again to double check
-	    	invoice = dispatcher.processAccount(accountId, target, true);
-	    	Assert.assertNotNull(invoice);
+		List<Invoice> invoices = invoiceDao.getInvoicesByAccount(accountId);
+		Assert.assertEquals(invoices.size(),0);
 
-	    	invoices = invoiceDao.getInvoicesByAccount(accountId);
-	    	Assert.assertEquals(invoices.size(),0);
+		// Try it again to double check
+		invoice = dispatcher.processAccount(accountId, target, true);
+		Assert.assertNotNull(invoice);
 
-	    	// This time no dry run
-	    	invoice = dispatcher.processAccount(accountId, target, false);
-	    	Assert.assertNotNull(invoice);
+		invoices = invoiceDao.getInvoicesByAccount(accountId);
+		Assert.assertEquals(invoices.size(),0);
 
-	    	invoices = invoiceDao.getInvoicesByAccount(accountId);
-	    	Assert.assertEquals(invoices.size(),1);
+		// This time no dry run
+		invoice = dispatcher.processAccount(accountId, target, false);
+		Assert.assertNotNull(invoice);
+
+		invoices = invoiceDao.getInvoicesByAccount(accountId);
+		Assert.assertEquals(invoices.size(),1);
+
+	}
 
-	    }
 }
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 452eb5e..8489993 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
@@ -50,4 +50,10 @@ public class DefaultTagDefinitionUserApi implements TagDefinitionUserApi {
     public void deleteTagDefinition(final String definitionName) throws TagDefinitionApiException {
         dao.deleteAllTagsForDefinition(definitionName);
     }
+
+	@Override
+	public TagDefinition getTagDefinition(String name)
+			throws TagDefinitionApiException {
+		return dao.getByName(name);
+	}
 }
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 f76795a..f7db1db 100644
--- a/util/src/main/resources/com/ning/billing/util/ddl.sql
+++ b/util/src/main/resources/com/ning/billing/util/ddl.sql
@@ -55,7 +55,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),
   date datetime NOT NULL,
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/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/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,