killbill-memoizeit

Changes

api/src/main/java/org/killbill/billing/junction/BillingModeType.java 21(+0 -21)

Details

diff --git a/api/src/main/java/org/killbill/billing/junction/BillingEvent.java b/api/src/main/java/org/killbill/billing/junction/BillingEvent.java
index a916829..e75e6ce 100644
--- a/api/src/main/java/org/killbill/billing/junction/BillingEvent.java
+++ b/api/src/main/java/org/killbill/billing/junction/BillingEvent.java
@@ -22,6 +22,7 @@ import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
 import org.killbill.billing.account.api.Account;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.Plan;
@@ -71,7 +72,7 @@ public interface BillingEvent extends Comparable<BillingEvent> {
     /**
      * @return the billing mode for the current event
      */
-    public BillingModeType getBillingMode();
+    public BillingMode getBillingMode();
 
     /**
      * @return the description of the billing event
diff --git a/api/src/main/java/org/killbill/billing/junction/BillingEventSet.java b/api/src/main/java/org/killbill/billing/junction/BillingEventSet.java
index bfdbb0a..8cffd89 100644
--- a/api/src/main/java/org/killbill/billing/junction/BillingEventSet.java
+++ b/api/src/main/java/org/killbill/billing/junction/BillingEventSet.java
@@ -20,9 +20,13 @@ import java.util.List;
 import java.util.SortedSet;
 import java.util.UUID;
 
+import org.killbill.billing.catalog.api.BillingMode;
+
 public interface BillingEventSet extends SortedSet<BillingEvent> {
 
     public abstract boolean isAccountAutoInvoiceOff();
 
+    public abstract BillingMode getRecurringBillingMode();
+
     public abstract List<UUID> getSubscriptionIdsWithAutoInvoiceOff();
 }
diff --git a/beatrix/src/test/resources/catalogSample.xml b/beatrix/src/test/resources/catalogSample.xml
index 34cf332..0221374 100644
--- a/beatrix/src/test/resources/catalogSample.xml
+++ b/beatrix/src/test/resources/catalogSample.xml
@@ -29,6 +29,8 @@
     <effectiveDate>2011-01-01T00:00:00+00:00</effectiveDate>
     <catalogName>Firearms</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>EUR</currency>
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
index 6491591..42297ee 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
@@ -30,6 +30,7 @@ import javax.xml.bind.annotation.XmlRootElement;
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.catalog.api.BillingActionPolicy;
 import org.killbill.billing.catalog.api.BillingAlignment;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.Currency;
@@ -58,6 +59,9 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
     @XmlElement(required = true)
     private String catalogName;
 
+    @XmlElement(required = true)
+    private BillingMode recurringBillingMode;
+
     private URI catalogURI;
 
     @XmlElementWrapper(name = "currencies", required = true)
@@ -102,6 +106,11 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         return effectiveDate;
     }
 
+    @Override
+    public BillingMode getRecurringBillingMode() {
+        return recurringBillingMode;
+    }
+
     /* (non-Javadoc)
      * @see org.killbill.billing.catalog.ICatalog#getProducts()
      */
@@ -306,11 +315,21 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         return this;
     }
 
+    public StandaloneCatalog setCatalogName(final String catalogName) {
+        this.catalogName = catalogName;
+        return this;
+    }
+
     protected StandaloneCatalog setEffectiveDate(final Date effectiveDate) {
         this.effectiveDate = effectiveDate;
         return this;
     }
 
+    public StandaloneCatalog setRecurringBillingMode(final BillingMode recurringBillingMode) {
+        this.recurringBillingMode = recurringBillingMode;
+        return this;
+    }
+
     protected StandaloneCatalog setPlanRules(final PlanRules planRules) {
         this.planRules = planRules;
         return this;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java b/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java
index 754b3f7..81affbf 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java
@@ -33,6 +33,7 @@ import org.joda.time.DateTime;
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.catalog.api.BillingActionPolicy;
 import org.killbill.billing.catalog.api.BillingAlignment;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.Catalog;
 import org.killbill.billing.catalog.api.CatalogApiException;
@@ -60,6 +61,7 @@ public class VersionedCatalog extends ValidatingConfig<StandaloneCatalog> implem
 
     private final Clock clock;
     private String catalogName;
+    private BillingMode recurringBillingMode;
 
     @XmlElement(name = "catalogVersion", required = true)
     private final List<StandaloneCatalog> versions = new ArrayList<StandaloneCatalog>();
@@ -168,10 +170,17 @@ public class VersionedCatalog extends ValidatingConfig<StandaloneCatalog> implem
         if (catalogName == null) {
             catalogName = e.getCatalogName();
         } else {
-            if (!catalogName.equals(getCatalogName())) {
+            if (!catalogName.equals(e.getCatalogName())) {
                 throw new CatalogApiException(ErrorCode.CAT_CATALOG_NAME_MISMATCH, catalogName, e.getCatalogName());
             }
         }
+        if (recurringBillingMode == null) {
+            recurringBillingMode = e.getRecurringBillingMode();
+        } else {
+            if (!recurringBillingMode.equals(e.getRecurringBillingMode())) {
+                throw new CatalogApiException(ErrorCode.CAT_CATALOG_RECURRING_MODE_MISMATCH, recurringBillingMode, e.getRecurringBillingMode());
+            }
+        }
         versions.add(e);
         Collections.sort(versions, new Comparator<StandaloneCatalog>() {
             @Override
@@ -358,6 +367,11 @@ public class VersionedCatalog extends ValidatingConfig<StandaloneCatalog> implem
     }
 
     @Override
+    public BillingMode getRecurringBillingMode() {
+        return recurringBillingMode;
+    }
+
+    @Override
     public Currency[] getCurrentSupportedCurrencies() throws CatalogApiException {
         return versionForDate(clock.getUTCNow()).getCurrentSupportedCurrencies();
     }
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLReader.java b/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLReader.java
index 91bb637..1361c88 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLReader.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLReader.java
@@ -29,10 +29,10 @@ public class TestXMLReader extends CatalogTestSuiteNoDB {
     @Test(groups = "fast")
     public void testCatalogLoad() {
         try {
-            XMLLoader.getObjectFromString(Resources.getResource("WeaponsHire.xml").toExternalForm(), StandaloneCatalog.class);
-            XMLLoader.getObjectFromString(Resources.getResource("WeaponsHireSmall.xml").toExternalForm(), StandaloneCatalog.class);
             XMLLoader.getObjectFromString(Resources.getResource("SpyCarBasic.xml").toExternalForm(), StandaloneCatalog.class);
             XMLLoader.getObjectFromString(Resources.getResource("SpyCarAdvanced.xml").toExternalForm(), StandaloneCatalog.class);
+            XMLLoader.getObjectFromString(Resources.getResource("WeaponsHire.xml").toExternalForm(), StandaloneCatalog.class);
+            XMLLoader.getObjectFromString(Resources.getResource("WeaponsHireSmall.xml").toExternalForm(), StandaloneCatalog.class);
         } catch (Exception e) {
             Assert.fail(e.toString());
         }
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/TestVersionedCatalog.java b/catalog/src/test/java/org/killbill/billing/catalog/TestVersionedCatalog.java
index 5c5fab0..da2cfc2 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/TestVersionedCatalog.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/TestVersionedCatalog.java
@@ -51,7 +51,7 @@ public class TestVersionedCatalog extends CatalogTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testAddCatalog() throws IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException, CatalogApiException {
-        vc.add(new StandaloneCatalog(new Date()));
+        vc.add((new StandaloneCatalog(new Date()).setCatalogName(vc.getCatalogName()).setRecurringBillingMode(vc.getRecurringBillingMode())));
         Assert.assertEquals(vc.size(), 4);
     }
 
diff --git a/catalog/src/test/resources/SpyCarAdvanced.xml b/catalog/src/test/resources/SpyCarAdvanced.xml
index de7d4a6..99eecee 100644
--- a/catalog/src/test/resources/SpyCarAdvanced.xml
+++ b/catalog/src/test/resources/SpyCarAdvanced.xml
@@ -21,6 +21,8 @@
     <effectiveDate>2013-02-08T00:00:00+00:00</effectiveDate>
     <catalogName>SpyCarAdvanced</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>GBP</currency>
diff --git a/catalog/src/test/resources/SpyCarBasic.xml b/catalog/src/test/resources/SpyCarBasic.xml
index 9e59993..e69cfed 100644
--- a/catalog/src/test/resources/SpyCarBasic.xml
+++ b/catalog/src/test/resources/SpyCarBasic.xml
@@ -21,6 +21,8 @@
     <effectiveDate>2013-02-08T00:00:00+00:00</effectiveDate>
     <catalogName>SpyCarBasic</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>GBP</currency>
diff --git a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-1.xml b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-1.xml
index 82aaaaa..978b238 100644
--- a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-1.xml
+++ b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-1.xml
@@ -21,6 +21,8 @@
     <effectiveDate>2011-01-01T00:00:00+00:00</effectiveDate>
     <catalogName>WeaponsHireSmall</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>EUR</currency>
diff --git a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-2.xml b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-2.xml
index 5ec6a46..9801e42 100644
--- a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-2.xml
+++ b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-2.xml
@@ -21,6 +21,8 @@
     <effectiveDate>2011-02-02T00:00:00+00:00</effectiveDate>
     <catalogName>WeaponsHireSmall</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>EUR</currency>
diff --git a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-3.xml b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-3.xml
index 987d211..453a143 100644
--- a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-3.xml
+++ b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-3.xml
@@ -21,6 +21,8 @@
     <effectiveDate>2011-03-03T00:00:00+00:00</effectiveDate>
     <catalogName>WeaponsHireSmall</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>EUR</currency>
diff --git a/catalog/src/test/resources/WeaponsHire.xml b/catalog/src/test/resources/WeaponsHire.xml
index 90f36a2..bdf37bb 100644
--- a/catalog/src/test/resources/WeaponsHire.xml
+++ b/catalog/src/test/resources/WeaponsHire.xml
@@ -42,6 +42,8 @@ Use Cases to do:
     <effectiveDate>2011-10-08T00:00:00+00:00</effectiveDate>
     <catalogName>Firearms</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>EUR</currency>
diff --git a/catalog/src/test/resources/WeaponsHireSmall.xml b/catalog/src/test/resources/WeaponsHireSmall.xml
index 212dd75..04bc40c 100644
--- a/catalog/src/test/resources/WeaponsHireSmall.xml
+++ b/catalog/src/test/resources/WeaponsHireSmall.xml
@@ -21,6 +21,8 @@
     <effectiveDate>2011-10-08T00:00:00+00:00</effectiveDate>
     <catalogName>WeaponsHireSmall</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>EUR</currency>
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
index 10d8bc8..5818562 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/generator/DefaultInvoiceGenerator.java
@@ -26,6 +26,8 @@ import javax.annotation.Nullable;
 
 import org.joda.time.LocalDate;
 import org.joda.time.Months;
+import org.killbill.billing.catalog.api.BillingMode;
+import org.killbill.billing.invoice.model.BillingModeGenerator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,7 +38,6 @@ import org.killbill.clock.Clock;
 import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.invoice.api.InvoiceItem;
-import org.killbill.billing.invoice.model.BillingMode;
 import org.killbill.billing.invoice.model.DefaultInvoice;
 import org.killbill.billing.invoice.model.FixedPriceInvoiceItem;
 import org.killbill.billing.invoice.model.InAdvanceBillingMode;
@@ -46,7 +47,6 @@ import org.killbill.billing.invoice.model.RecurringInvoiceItemData;
 import org.killbill.billing.invoice.tree.AccountItemTree;
 import org.killbill.billing.junction.BillingEvent;
 import org.killbill.billing.junction.BillingEventSet;
-import org.killbill.billing.junction.BillingModeType;
 import org.killbill.billing.util.config.InvoiceConfig;
 import org.killbill.billing.util.currency.KillBillMoney;
 
@@ -182,7 +182,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         // Handle recurring items
         final BillingPeriod billingPeriod = thisEvent.getBillingPeriod();
         if (billingPeriod != BillingPeriod.NO_BILLING_PERIOD) {
-            final BillingMode billingMode = instantiateBillingMode(thisEvent.getBillingMode());
+            final BillingModeGenerator billingModeGenerator = instantiateBillingMode(thisEvent.getBillingMode());
             final LocalDate startDate = new LocalDate(thisEvent.getEffectiveDate(), thisEvent.getTimeZone());
 
             if (!startDate.isAfter(targetDate)) {
@@ -192,7 +192,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
 
                 final List<RecurringInvoiceItemData> itemData;
                 try {
-                    itemData = billingMode.calculateInvoiceItemData(startDate, endDate, targetDate, billCycleDayLocal, billingPeriod);
+                    itemData = billingModeGenerator.generateInvoiceItemData(startDate, endDate, targetDate, billCycleDayLocal, billingPeriod);
                 } catch (InvalidDateSequenceException e) {
                     throw new InvoiceApiException(ErrorCode.INVOICE_INVALID_DATE_SEQUENCE, startDate, endDate, targetDate);
                 }
@@ -228,7 +228,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         return items;
     }
 
-    private BillingMode instantiateBillingMode(final BillingModeType billingMode) {
+    private BillingModeGenerator instantiateBillingMode(final BillingMode billingMode) {
         switch (billingMode) {
             case IN_ADVANCE:
                 return new InAdvanceBillingMode();
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/InAdvanceBillingMode.java b/invoice/src/main/java/org/killbill/billing/invoice/model/InAdvanceBillingMode.java
index 11d5aa6..31663ef 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/InAdvanceBillingMode.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/InAdvanceBillingMode.java
@@ -33,14 +33,14 @@ import static org.killbill.billing.invoice.generator.InvoiceDateUtils.calculateN
 import static org.killbill.billing.invoice.generator.InvoiceDateUtils.calculateProRationAfterLastBillingCycleDate;
 import static org.killbill.billing.invoice.generator.InvoiceDateUtils.calculateProRationBeforeFirstBillingPeriod;
 
-public class InAdvanceBillingMode implements BillingMode {
+public class InAdvanceBillingMode implements BillingModeGenerator {
 
     private static final Logger log = LoggerFactory.getLogger(InAdvanceBillingMode.class);
 
     @Override
-    public List<RecurringInvoiceItemData> calculateInvoiceItemData(final LocalDate startDate, @Nullable final LocalDate endDate,
-                                                                   final LocalDate targetDate,
-                                                                   final int billingCycleDayLocal, final BillingPeriod billingPeriod) throws InvalidDateSequenceException {
+    public List<RecurringInvoiceItemData> generateInvoiceItemData(final LocalDate startDate, @Nullable final LocalDate endDate,
+                                                                  final LocalDate targetDate,
+                                                                  final int billingCycleDayLocal, final BillingPeriod billingPeriod) throws InvalidDateSequenceException {
         if (endDate != null && endDate.isBefore(startDate)) {
             throw new InvalidDateSequenceException();
         }
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
index 4954538..ac44bc7 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
@@ -26,6 +26,7 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.mockito.Mockito;
 import org.skife.jdbi.v2.exceptions.TransactionFailedException;
 import org.testng.Assert;
@@ -64,7 +65,6 @@ import org.killbill.billing.invoice.model.RecurringInvoiceItem;
 import org.killbill.billing.invoice.model.RepairAdjInvoiceItem;
 import org.killbill.billing.junction.BillingEvent;
 import org.killbill.billing.junction.BillingEventSet;
-import org.killbill.billing.junction.BillingModeType;
 import org.killbill.billing.subscription.api.SubscriptionBase;
 import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
 import org.killbill.billing.util.currency.KillBillMoney;
@@ -1093,7 +1093,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         final DateTime effectiveDate1 = new DateTime(2011, 2, 1, 0, 0, 0);
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate1, plan1, phase1, null,
-                                                                       recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                                       recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingMode.IN_ADVANCE,
                                                                        "testEvent1", 1L, SubscriptionBaseTransitionType.CREATE);
 
         final BillingEventSet events = new MockBillingEventSet();
@@ -1111,7 +1111,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         final DateTime effectiveDate2 = new DateTime(2011, 2, 15, 0, 0, 0);
         final BillingEvent event2 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate2, plan2, phase2, null,
-                                                                       recurringPrice2.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                                       recurringPrice2.getPrice(currency), currency, BillingPeriod.MONTHLY, 1, BillingMode.IN_ADVANCE,
                                                                        "testEvent2", 2L, SubscriptionBaseTransitionType.CREATE);
         events.add(event2);
 
@@ -1143,7 +1143,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         final DateTime effectiveDate = invoiceUtil.buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
 
         final BillingEvent event = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate, plan, phase, null,
-                                                                      recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
+                                                                      recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 15, BillingMode.IN_ADVANCE,
                                                                       "testEvent", 1L, SubscriptionBaseTransitionType.CREATE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event);
@@ -1186,7 +1186,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         final DateTime effectiveDate1 = invoiceUtil.buildDate(2011, 1, 1).toDateTimeAtStartOfDay();
 
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate1, plan, phase1, fixedPrice.getPrice(currency),
-                                                                       null, currency, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                                       null, currency, BillingPeriod.MONTHLY, 1, BillingMode.IN_ADVANCE,
                                                                        "testEvent1", 1L, SubscriptionBaseTransitionType.CREATE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
@@ -1204,7 +1204,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         final DateTime effectiveDate2 = effectiveDate1.plusDays(30);
         final BillingEvent event2 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate2, plan, phase2, null,
-                                                                       recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                                       recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingMode.IN_ADVANCE,
                                                                        "testEvent2", 2L, SubscriptionBaseTransitionType.PHASE);
         events.add(event2);
 
@@ -1252,14 +1252,14 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate1, plan, phase1,
                                                                        fixedPrice.getPrice(currency), null, currency,
-                                                                       BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                                       BillingPeriod.MONTHLY, 1, BillingMode.IN_ADVANCE,
                                                                        "testEvent1", 1L, SubscriptionBaseTransitionType.CREATE);
         final BillingEventSet events = new MockBillingEventSet();
         events.add(event1);
 
         final DateTime effectiveDate2 = effectiveDate1.plusDays(30);
         final BillingEvent event2 = invoiceUtil.createMockBillingEvent(null, subscription, effectiveDate2, plan, phase2, null,
-                                                                       recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                                       recurringPrice.getPrice(currency), currency, BillingPeriod.MONTHLY, 31, BillingMode.IN_ADVANCE,
                                                                        "testEvent2", 2L, SubscriptionBaseTransitionType.CHANGE);
         events.add(event2);
 
@@ -1331,7 +1331,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, recuringStartDate.toDateTimeAtStartOfDay(), plan, phase1, null,
                                                                        TEN, Currency.USD,
-                                                                       BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                                       BillingPeriod.MONTHLY, 31, BillingMode.IN_ADVANCE,
                                                                        "new-event", 1L, SubscriptionBaseTransitionType.CREATE);
         events.add(event1);
         final Invoice newInvoice = generator.generateInvoice(UUID.randomUUID(), events, invoices, targetDate, Currency.USD);
@@ -1365,7 +1365,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, targetDate1, plan, phase1, null,
                                                                        TEN, currency,
-                                                                       BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                                       BillingPeriod.MONTHLY, 31, BillingMode.IN_ADVANCE,
                                                                        "testEvent1", 1L, SubscriptionBaseTransitionType.CHANGE);
         events.add(event1);
 
@@ -1377,7 +1377,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
 
         final BillingEvent event2 = invoiceUtil.createMockBillingEvent(null, subscription, targetDate1, plan, phase2, null,
                                                                        TWENTY, currency,
-                                                                       BillingPeriod.MONTHLY, 31, BillingModeType.IN_ADVANCE,
+                                                                       BillingPeriod.MONTHLY, 31, BillingMode.IN_ADVANCE,
                                                                        "testEvent2", 2L, SubscriptionBaseTransitionType.CHANGE);
         events.add(event2);
         Invoice invoice2 = generator.generateInvoice(UUID.randomUUID(), events, invoices, new LocalDate(targetDate2), Currency.USD);
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java b/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
index 67b9683..d030c81 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/generator/TestDefaultInvoiceGenerator.java
@@ -28,6 +28,7 @@ import javax.annotation.Nullable;
 
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.mockito.Mockito;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -56,7 +57,6 @@ import org.killbill.billing.invoice.model.FixedPriceInvoiceItem;
 import org.killbill.billing.invoice.model.RecurringInvoiceItem;
 import org.killbill.billing.junction.BillingEvent;
 import org.killbill.billing.junction.BillingEventSet;
-import org.killbill.billing.junction.BillingModeType;
 import org.killbill.billing.subscription.api.SubscriptionBase;
 import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
 import org.killbill.billing.util.config.InvoiceConfig;
@@ -564,13 +564,13 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
         final BillingEvent event1 = invoiceUtil.createMockBillingEvent(null, subscription, new DateTime("2012-01-1"),
                                                                        plan, phase1,
                                                                        ZERO, null, Currency.USD, BillingPeriod.NO_BILLING_PERIOD, 1,
-                                                                       BillingModeType.IN_ADVANCE, "Test Event 1", 1L,
+                                                                       BillingMode.IN_ADVANCE, "Test Event 1", 1L,
                                                                        SubscriptionBaseTransitionType.CREATE);
 
         final BillingEvent event2 = invoiceUtil.createMockBillingEvent(null, subscription, changeDate,
                                                                        plan, phase2,
                                                                        ZERO, null, Currency.USD, BillingPeriod.NO_BILLING_PERIOD, 1,
-                                                                       BillingModeType.IN_ADVANCE, "Test Event 2", 2L,
+                                                                       BillingMode.IN_ADVANCE, "Test Event 2", 2L,
                                                                        SubscriptionBaseTransitionType.PHASE);
 
         events.add(event2);
@@ -766,7 +766,7 @@ public class TestDefaultInvoiceGenerator extends InvoiceTestSuiteNoDB {
                                                   planPhase.getFixed().getPrice() == null ? null : planPhase.getFixed().getPrice().getPrice(currency),
                                                   planPhase.getRecurring().getRecurringPrice() == null ? null : planPhase.getRecurring().getRecurringPrice().getPrice(currency),
                                                   currency, planPhase.getRecurring().getBillingPeriod(),
-                                                  billCycleDayLocal, BillingModeType.IN_ADVANCE, "Test", 1L, SubscriptionBaseTransitionType.CREATE);
+                                                  billCycleDayLocal, BillingMode.IN_ADVANCE, "Test", 1L, SubscriptionBaseTransitionType.CREATE);
     }
 
     private void testInvoiceGeneration(final UUID accountId, final BillingEventSet events, final List<Invoice> existingInvoices,
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/MockBillingEventSet.java b/invoice/src/test/java/org/killbill/billing/invoice/MockBillingEventSet.java
index 615acc0..261122f 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/MockBillingEventSet.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/MockBillingEventSet.java
@@ -21,6 +21,7 @@ import java.util.List;
 import java.util.TreeSet;
 import java.util.UUID;
 
+import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.junction.BillingEvent;
 import org.killbill.billing.junction.BillingEventSet;
 
@@ -41,6 +42,11 @@ public class MockBillingEventSet extends TreeSet<BillingEvent> implements Billin
     }
 
     @Override
+    public BillingMode getRecurringBillingMode() {
+        return BillingMode.IN_ADVANCE;
+    }
+
+    @Override
     public List<UUID> getSubscriptionIdsWithAutoInvoiceOff() {
         return subscriptionIdsWithAutoInvoiceOff;
     }
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/model/TestInAdvanceBillingMode.java b/invoice/src/test/java/org/killbill/billing/invoice/model/TestInAdvanceBillingMode.java
index 693537d..c5c35b9 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/model/TestInAdvanceBillingMode.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/model/TestInAdvanceBillingMode.java
@@ -150,7 +150,7 @@ public class TestInAdvanceBillingMode extends InvoiceTestSuiteNoDB {
                                     final LinkedHashMap<LocalDate, LocalDate> expectedDates) throws InvalidDateSequenceException {
         final InAdvanceBillingMode billingMode = new InAdvanceBillingMode();
 
-        final List<RecurringInvoiceItemData> invoiceItems = billingMode.calculateInvoiceItemData(startDate, endDate, targetDate, billingCycleDayLocal, billingPeriod);
+        final List<RecurringInvoiceItemData> invoiceItems = billingMode.generateInvoiceItemData(startDate, endDate, targetDate, billingCycleDayLocal, billingPeriod);
 
         int i = 0;
         for (final LocalDate periodStartDate : expectedDates.keySet()) {
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java
index 42d69de..dd313de 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceDispatcher.java
@@ -25,6 +25,7 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
@@ -52,7 +53,6 @@ import org.killbill.billing.subscription.api.SubscriptionBase;
 import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.junction.BillingEventSet;
-import org.killbill.billing.junction.BillingModeType;
 import org.killbill.billing.util.timezone.DateAndTimeZoneContext;
 
 public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
@@ -82,7 +82,7 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
         final BigDecimal fixedPrice = null;
         events.add(invoiceUtil.createMockBillingEvent(account, subscription, effectiveDate, plan, planPhase,
                                                       fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1,
-                                                      BillingModeType.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.CREATE));
+                                                      BillingMode.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.CREATE));
 
         Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
 
@@ -122,23 +122,23 @@ public class TestInvoiceDispatcher extends InvoiceTestSuiteWithEmbeddedDB {
         final MockPlan bicycleTrialEvergreen1USD = MockPlan.createBicycleTrialEvergreen1USD();
         events.add(invoiceUtil.createMockBillingEvent(account, subscription, new DateTime("2012-05-01T00:03:42.000Z"), bicycleTrialEvergreen1USD,
                                                       new MockPlanPhase(bicycleTrialEvergreen1USD, PhaseType.TRIAL), BigDecimal.ZERO, null, account.getCurrency(), BillingPeriod.NO_BILLING_PERIOD,
-                                                      31, BillingModeType.IN_ADVANCE, "CREATE", 1L, SubscriptionBaseTransitionType.CREATE));
+                                                      31, BillingMode.IN_ADVANCE, "CREATE", 1L, SubscriptionBaseTransitionType.CREATE));
         // Phase change to evergreen
         events.add(invoiceUtil.createMockBillingEvent(account, subscription, new DateTime("2012-05-31T00:03:42.000Z"), bicycleTrialEvergreen1USD,
                                                       new MockPlanPhase(bicycleTrialEvergreen1USD, PhaseType.EVERGREEN), null, new BigDecimal("249.95"), account.getCurrency(), BillingPeriod.MONTHLY,
-                                                      31, BillingModeType.IN_ADVANCE, "PHASE", 2L, SubscriptionBaseTransitionType.PHASE));
+                                                      31, BillingMode.IN_ADVANCE, "PHASE", 2L, SubscriptionBaseTransitionType.PHASE));
         // Overdue period
         events.add(invoiceUtil.createMockBillingEvent(account, subscription, new DateTime("2012-07-15T00:00:00.000Z"), bicycleTrialEvergreen1USD,
                                                       new MockPlanPhase(bicycleTrialEvergreen1USD, PhaseType.EVERGREEN), null, null, account.getCurrency(), BillingPeriod.NO_BILLING_PERIOD,
-                                                      31, BillingModeType.IN_ADVANCE, "", 0L, SubscriptionBaseTransitionType.START_BILLING_DISABLED));
+                                                      31, BillingMode.IN_ADVANCE, "", 0L, SubscriptionBaseTransitionType.START_BILLING_DISABLED));
         events.add(invoiceUtil.createMockBillingEvent(account, subscription, new DateTime("2012-07-25T00:00:00.000Z"), bicycleTrialEvergreen1USD,
                                                       new MockPlanPhase(bicycleTrialEvergreen1USD, PhaseType.EVERGREEN), null, new BigDecimal("249.95"), account.getCurrency(), BillingPeriod.MONTHLY,
-                                                      31, BillingModeType.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.END_BILLING_DISABLED));
+                                                      31, BillingMode.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.END_BILLING_DISABLED));
         // Upgrade after the overdue period
         final MockPlan jetTrialEvergreen1000USD = MockPlan.createJetTrialEvergreen1000USD();
         events.add(invoiceUtil.createMockBillingEvent(account, subscription, new DateTime("2012-07-25T00:04:00.000Z"), jetTrialEvergreen1000USD,
                                                       new MockPlanPhase(jetTrialEvergreen1000USD, PhaseType.EVERGREEN), null, new BigDecimal("1000"), account.getCurrency(), BillingPeriod.MONTHLY,
-                                                      31, BillingModeType.IN_ADVANCE, "CHANGE", 3L, SubscriptionBaseTransitionType.CHANGE));
+                                                      31, BillingMode.IN_ADVANCE, "CHANGE", 3L, SubscriptionBaseTransitionType.CHANGE));
 
         Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
         final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier();
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
index 376f5c8..5194fb8 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java
@@ -26,6 +26,7 @@ import javax.inject.Inject;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.mockito.Mockito;
 import org.skife.jdbi.v2.IDBI;
 import org.testng.Assert;
@@ -63,7 +64,6 @@ import org.killbill.billing.invoice.notification.NullInvoiceNotifier;
 import org.killbill.billing.junction.BillingEvent;
 import org.killbill.billing.junction.BillingEventSet;
 import org.killbill.billing.junction.BillingInternalApi;
-import org.killbill.billing.junction.BillingModeType;
 import org.killbill.billing.mock.MockAccountBuilder;
 import org.killbill.billing.subscription.api.SubscriptionBase;
 import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
@@ -182,7 +182,7 @@ public class TestInvoiceHelper {
         final BigDecimal fixedPrice = null;
         events.add(createMockBillingEvent(account, subscription, effectiveDate, plan, planPhase,
                                           fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1,
-                                          BillingModeType.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.CREATE));
+                                          BillingMode.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.CREATE));
 
         Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.<UUID>any(), Mockito.<InternalCallContext>any())).thenReturn(events);
 
@@ -308,7 +308,7 @@ public class TestInvoiceHelper {
                                                @Nullable final BigDecimal fixedPrice, @Nullable final BigDecimal recurringPrice,
                                                final Currency currency, final BillingPeriod billingPeriod,
                                                final int billCycleDayLocal,
-                                               final BillingModeType billingModeType, final String description,
+                                               final BillingMode billingMode, final String description,
                                                final long totalOrdering,
                                                final SubscriptionBaseTransitionType type) {
         return new BillingEvent() {
@@ -348,8 +348,8 @@ public class TestInvoiceHelper {
             }
 
             @Override
-            public BillingModeType getBillingMode() {
-                return billingModeType;
+            public BillingMode getBillingMode() {
+                return billingMode;
             }
 
             @Override
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/tests/inAdvance/ProRationInAdvanceTestBase.java b/invoice/src/test/java/org/killbill/billing/invoice/tests/inAdvance/ProRationInAdvanceTestBase.java
index f3913fc..6fd8e15 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/tests/inAdvance/ProRationInAdvanceTestBase.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/tests/inAdvance/ProRationInAdvanceTestBase.java
@@ -16,14 +16,14 @@
 
 package org.killbill.billing.invoice.tests.inAdvance;
 
-import org.killbill.billing.invoice.model.BillingMode;
+import org.killbill.billing.invoice.model.BillingModeGenerator;
 import org.killbill.billing.invoice.model.InAdvanceBillingMode;
 import org.killbill.billing.invoice.tests.ProRationTestBase;
 
 public abstract class ProRationInAdvanceTestBase extends ProRationTestBase {
 
     @Override
-    protected BillingMode getBillingMode() {
+    protected BillingModeGenerator getBillingMode() {
         return new InAdvanceBillingMode();
     }
 }
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/tests/inAdvance/TestValidationProRation.java b/invoice/src/test/java/org/killbill/billing/invoice/tests/inAdvance/TestValidationProRation.java
index c647604..741316e 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/tests/inAdvance/TestValidationProRation.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/tests/inAdvance/TestValidationProRation.java
@@ -16,15 +16,11 @@
 
 package org.killbill.billing.invoice.tests.inAdvance;
 
-import static org.killbill.billing.invoice.TestInvoiceHelper.*;
-
-import java.math.BigDecimal;
-
 import org.joda.time.LocalDate;
+import org.killbill.billing.invoice.model.BillingModeGenerator;
 import org.testng.annotations.Test;
 
 import org.killbill.billing.catalog.api.BillingPeriod;
-import org.killbill.billing.invoice.model.BillingMode;
 import org.killbill.billing.invoice.model.InAdvanceBillingMode;
 import org.killbill.billing.invoice.model.InvalidDateSequenceException;
 import org.killbill.billing.invoice.tests.ProRationTestBase;
@@ -39,7 +35,7 @@ public class TestValidationProRation extends ProRationTestBase {
     }
 
     @Override
-    protected BillingMode getBillingMode() {
+    protected BillingModeGenerator getBillingMode() {
         return new InAdvanceBillingMode();
     }
 
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/tests/ProRationTestBase.java b/invoice/src/test/java/org/killbill/billing/invoice/tests/ProRationTestBase.java
index 2785e4f..4ce38af 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/tests/ProRationTestBase.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/tests/ProRationTestBase.java
@@ -25,7 +25,7 @@ import org.joda.time.LocalDate;
 
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.invoice.InvoiceTestSuiteNoDB;
-import org.killbill.billing.invoice.model.BillingMode;
+import org.killbill.billing.invoice.model.BillingModeGenerator;
 import org.killbill.billing.invoice.model.InvalidDateSequenceException;
 import org.killbill.billing.invoice.model.RecurringInvoiceItemData;
 
@@ -34,7 +34,7 @@ import static org.testng.Assert.fail;
 
 public abstract class ProRationTestBase extends InvoiceTestSuiteNoDB {
 
-    protected abstract BillingMode getBillingMode();
+    protected abstract BillingModeGenerator getBillingMode();
 
     protected abstract BillingPeriod getBillingPeriod();
 
@@ -65,7 +65,7 @@ public abstract class ProRationTestBase extends InvoiceTestSuiteNoDB {
     }
 
     protected BigDecimal calculateNumberOfBillingCycles(final LocalDate startDate, final LocalDate endDate, final LocalDate targetDate, final int billingCycleDay) throws InvalidDateSequenceException {
-        final List<RecurringInvoiceItemData> items = getBillingMode().calculateInvoiceItemData(startDate, endDate, targetDate, billingCycleDay, getBillingPeriod());
+        final List<RecurringInvoiceItemData> items = getBillingMode().generateInvoiceItemData(startDate, endDate, targetDate, billingCycleDay, getBillingPeriod());
 
         BigDecimal numberOfBillingCycles = ZERO;
         for (final RecurringInvoiceItemData item : items) {
@@ -76,7 +76,7 @@ public abstract class ProRationTestBase extends InvoiceTestSuiteNoDB {
     }
 
     protected BigDecimal calculateNumberOfBillingCycles(final LocalDate startDate, final LocalDate targetDate, final int billingCycleDay) throws InvalidDateSequenceException {
-        final List<RecurringInvoiceItemData> items = getBillingMode().calculateInvoiceItemData(startDate, null, targetDate, billingCycleDay, getBillingPeriod());
+        final List<RecurringInvoiceItemData> items = getBillingMode().generateInvoiceItemData(startDate, null, targetDate, billingCycleDay, getBillingPeriod());
 
         BigDecimal numberOfBillingCycles = ZERO;
         for (final RecurringInvoiceItemData item : items) {
diff --git a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/BlockingCalculator.java b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/BlockingCalculator.java
index c651e18..ad95690 100644
--- a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/BlockingCalculator.java
+++ b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/BlockingCalculator.java
@@ -32,13 +32,13 @@ import org.joda.time.DateTimeZone;
 
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.Plan;
 import org.killbill.billing.catalog.api.PlanPhase;
 import org.killbill.billing.entitlement.api.BlockingState;
 import org.killbill.billing.junction.BillingEvent;
-import org.killbill.billing.junction.BillingModeType;
 import org.killbill.billing.junction.BlockingInternalApi;
 import org.killbill.billing.subscription.api.SubscriptionBase;
 import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
@@ -204,14 +204,14 @@ public class BlockingCalculator {
 
         final Currency currency = previousEvent.getCurrency();
         final String description = "";
-        final BillingModeType billingModeType = previousEvent.getBillingMode();
+        final BillingMode billingMode = previousEvent.getBillingMode();
         final SubscriptionBaseTransitionType type = SubscriptionBaseTransitionType.START_BILLING_DISABLED;
         final Long totalOrdering = globaltotalOrder.getAndIncrement();
         final DateTimeZone tz = previousEvent.getTimeZone();
 
         return new DefaultBillingEvent(account, subscription, effectiveDate, plan, planPhase,
                                        fixedPrice, recurringPrice, currency,
-                                       billingPeriod, billCycleDay, billingModeType,
+                                       billingPeriod, billCycleDay, billingMode,
                                        description, totalOrdering, type, tz);
     }
 
@@ -227,7 +227,7 @@ public class BlockingCalculator {
         final BigDecimal recurringPrice = previousEvent.getRecurringPrice();
         final Currency currency = previousEvent.getCurrency();
         final String description = "";
-        final BillingModeType billingModeType = previousEvent.getBillingMode();
+        final BillingMode billingMode  = previousEvent.getBillingMode();
         final BillingPeriod billingPeriod = previousEvent.getBillingPeriod();
         final SubscriptionBaseTransitionType type = SubscriptionBaseTransitionType.END_BILLING_DISABLED;
         final Long totalOrdering = globaltotalOrder.getAndIncrement();
@@ -235,7 +235,7 @@ public class BlockingCalculator {
 
         return new DefaultBillingEvent(account, subscription, effectiveDate, plan, planPhase,
                                        fixedPrice, recurringPrice, currency,
-                                       billingPeriod, billCycleDay, billingModeType,
+                                       billingPeriod, billCycleDay, billingMode,
                                        description, totalOrdering, type, tz);
     }
 
diff --git a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEvent.java b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEvent.java
index faf7fbd..2394b96 100644
--- a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEvent.java
+++ b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEvent.java
@@ -24,6 +24,7 @@ import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
 import org.killbill.billing.account.api.Account;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.Catalog;
 import org.killbill.billing.catalog.api.CatalogApiException;
@@ -34,7 +35,6 @@ import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
 import org.killbill.billing.subscription.api.SubscriptionBase;
 import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
 import org.killbill.billing.junction.BillingEvent;
-import org.killbill.billing.junction.BillingModeType;
 
 public class DefaultBillingEvent implements BillingEvent {
     private final Account account;
@@ -47,7 +47,7 @@ public class DefaultBillingEvent implements BillingEvent {
     private final BigDecimal recurringPrice;
     private final Currency currency;
     private final String description;
-    private final BillingModeType billingModeType;
+    private final BillingMode billingMode;
     private final BillingPeriod billingPeriod;
     private final SubscriptionBaseTransitionType type;
     private final Long totalOrdering;
@@ -79,7 +79,7 @@ public class DefaultBillingEvent implements BillingEvent {
 
         this.currency = currency;
         description = transition.getTransitionType().toString();
-        billingModeType = BillingModeType.IN_ADVANCE;
+        billingMode = BillingMode.IN_ADVANCE;
         billingPeriod = getRecurringBillingPeriod((transition.getTransitionType() != SubscriptionBaseTransitionType.CANCEL) ? nextPhase : prevPhase);
         type = transition.getTransitionType();
         totalOrdering = transition.getTotalOrdering();
@@ -89,7 +89,7 @@ public class DefaultBillingEvent implements BillingEvent {
 
     public DefaultBillingEvent(final Account account, final SubscriptionBase subscription, final DateTime effectiveDate, final Plan plan, final PlanPhase planPhase,
                                final BigDecimal fixedPrice, final BigDecimal recurringPrice, final Currency currency,
-                               final BillingPeriod billingPeriod, final int billCycleDayLocal, final BillingModeType billingModeType,
+                               final BillingPeriod billingPeriod, final int billCycleDayLocal, final BillingMode billingMode,
                                final String description, final long totalOrdering, final SubscriptionBaseTransitionType type, final DateTimeZone timeZone) {
         this.account = account;
         this.subscription = subscription;
@@ -101,7 +101,7 @@ public class DefaultBillingEvent implements BillingEvent {
         this.currency = currency;
         this.billingPeriod = billingPeriod;
         this.billCycleDayLocal = billCycleDayLocal;
-        this.billingModeType = billingModeType;
+        this.billingMode = billingMode;
         this.description = description;
         this.type = type;
         this.totalOrdering = totalOrdering;
@@ -190,8 +190,8 @@ public class DefaultBillingEvent implements BillingEvent {
     }
 
     @Override
-    public BillingModeType getBillingMode() {
-        return billingModeType;
+    public BillingMode getBillingMode() {
+        return billingMode;
     }
 
     @Override
@@ -257,7 +257,7 @@ public class DefaultBillingEvent implements BillingEvent {
         if (account != null ? !account.equals(that.account) : that.account != null) {
             return false;
         }
-        if (billingModeType != that.billingModeType) {
+        if (billingMode != that.billingMode) {
             return false;
         }
         if (billingPeriod != that.billingPeriod) {
@@ -312,7 +312,7 @@ public class DefaultBillingEvent implements BillingEvent {
         result = 31 * result + (recurringPrice != null ? recurringPrice.hashCode() : 0);
         result = 31 * result + (currency != null ? currency.hashCode() : 0);
         result = 31 * result + (description != null ? description.hashCode() : 0);
-        result = 31 * result + (billingModeType != null ? billingModeType.hashCode() : 0);
+        result = 31 * result + (billingMode != null ? billingMode.hashCode() : 0);
         result = 31 * result + (billingPeriod != null ? billingPeriod.hashCode() : 0);
         result = 31 * result + (type != null ? type.hashCode() : 0);
         result = 31 * result + (totalOrdering != null ? totalOrdering.hashCode() : 0);
diff --git a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEventSet.java b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEventSet.java
index 4b59c9b..87b8231 100644
--- a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEventSet.java
+++ b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultBillingEventSet.java
@@ -22,14 +22,17 @@ import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.UUID;
 
+import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.junction.BillingEvent;
 import org.killbill.billing.junction.BillingEventSet;
 
 public class DefaultBillingEventSet extends TreeSet<BillingEvent> implements SortedSet<BillingEvent>, BillingEventSet {
+
     private static final long serialVersionUID = 1L;
 
     private boolean accountAutoInvoiceOff = false;
     private List<UUID> subscriptionIdsWithAutoInvoiceOff = new ArrayList<UUID>();
+    private BillingMode recurrringBillingMode;
 
     /* (non-Javadoc)
     * @see org.killbill.billing.junction.plumbing.billing.BillingEventSet#isAccountAutoInvoiceOff()
@@ -39,6 +42,11 @@ public class DefaultBillingEventSet extends TreeSet<BillingEvent> implements Sor
         return accountAutoInvoiceOff;
     }
 
+    @Override
+    public BillingMode getRecurringBillingMode() {
+        return null;
+    }
+
     /* (non-Javadoc)
     * @see org.killbill.billing.junction.plumbing.billing.BillingEventSet#getSubscriptionIdsWithAutoInvoiceOff()
     */
@@ -51,16 +59,19 @@ public class DefaultBillingEventSet extends TreeSet<BillingEvent> implements Sor
         this.accountAutoInvoiceOff = accountAutoInvoiceIsOff;
     }
 
-    public void setSubscriptionIdsWithAutoInvoiceOff(final List<UUID> subscriptionIdsWithAutoInvoiceOff) {
-        this.subscriptionIdsWithAutoInvoiceOff = subscriptionIdsWithAutoInvoiceOff;
+    public BillingMode getRecurrringBillingMode() {
+        return recurrringBillingMode;
+    }
+
+    public void setRecurrringBillingMode(final BillingMode recurrringBillingMode) {
+        this.recurrringBillingMode = recurrringBillingMode;
     }
 
     @Override
     public String toString() {
         return "DefaultBillingEventSet [accountAutoInvoiceOff=" + accountAutoInvoiceOff
-                + ", subscriptionIdsWithAutoInvoiceOff=" + subscriptionIdsWithAutoInvoiceOff + ", Events="
-                + super.toString() + "]";
+               + ", subscriptionIdsWithAutoInvoiceOff=" + subscriptionIdsWithAutoInvoiceOff + ", Events="
+               + super.toString() + "]";
     }
 
-
 }
diff --git a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
index 01d1d3c..1cbcbf6 100644
--- a/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
+++ b/junction/src/main/java/org/killbill/billing/junction/plumbing/billing/DefaultInternalBillingApi.java
@@ -76,6 +76,7 @@ public class DefaultInternalBillingApi implements BillingInternalApi {
     public BillingEventSet getBillingEventsForAccountAndUpdateAccountBCD(final UUID accountId, final InternalCallContext context) {
         final List<SubscriptionBaseBundle> bundles = subscriptionApi.getBundlesForAccount(accountId, context);
         final DefaultBillingEventSet result = new DefaultBillingEventSet();
+        result.setRecurrringBillingMode(catalogService.getCurrentCatalog().getRecurringBillingMode());
 
         try {
             final Account account = accountApi.getAccountById(accountId, context);
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
index bcb4cd0..6cd947f 100644
--- a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
@@ -22,6 +22,7 @@ import org.killbill.billing.account.api.Account;
 import org.killbill.billing.account.api.AccountApiException;
 import org.killbill.billing.catalog.MockCatalog;
 import org.killbill.billing.catalog.api.BillingAlignment;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.InternationalPrice;
@@ -33,7 +34,6 @@ import org.killbill.billing.entitlement.api.BlockingStateType;
 import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
 import org.killbill.billing.entitlement.dao.MockBlockingStateDao;
 import org.killbill.billing.junction.JunctionTestSuiteNoDB;
-import org.killbill.billing.entitlement.api.BlockingState;
 import org.killbill.billing.mock.MockEffectiveSubscriptionEvent;
 import org.killbill.billing.mock.MockSubscription;
 import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType;
@@ -44,7 +44,6 @@ import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
 import org.killbill.billing.junction.BillingEvent;
 import org.killbill.billing.junction.BillingEventSet;
-import org.killbill.billing.junction.BillingModeType;
 import org.killbill.billing.junction.DefaultBlockingState;
 import org.killbill.billing.util.tag.ControlTagType;
 import org.killbill.billing.util.tag.dao.MockTagDao;
@@ -55,7 +54,6 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -255,7 +253,7 @@ public class TestBillingApi extends JunctionTestSuiteNoDB {
         if (!SubscriptionBaseTransitionType.START_BILLING_DISABLED.equals(event.getTransitionType())) {
             Assert.assertEquals(nextPhase.getRecurring().getBillingPeriod(), event.getBillingPeriod());
         }
-        Assert.assertEquals(BillingModeType.IN_ADVANCE, event.getBillingMode());
+        Assert.assertEquals(BillingMode.IN_ADVANCE, event.getBillingMode());
         Assert.assertEquals(desc, event.getTransitionType().toString());
     }
 
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBlockingCalculator.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBlockingCalculator.java
index 7425e0f..867ba4f 100644
--- a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBlockingCalculator.java
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBlockingCalculator.java
@@ -28,6 +28,7 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.mockito.Mockito;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -43,7 +44,6 @@ import org.killbill.billing.entitlement.api.BlockingState;
 import org.killbill.billing.entitlement.api.BlockingStateType;
 import org.killbill.billing.entitlement.dao.MockBlockingStateDao;
 import org.killbill.billing.junction.BillingEvent;
-import org.killbill.billing.junction.BillingModeType;
 import org.killbill.billing.junction.DefaultBlockingState;
 import org.killbill.billing.junction.JunctionTestSuiteNoDB;
 import org.killbill.billing.junction.plumbing.billing.BlockingCalculator.DisabledDuration;
@@ -532,7 +532,7 @@ public class TestBlockingCalculator extends JunctionTestSuiteNoDB {
         final BigDecimal recurringPrice = BigDecimal.TEN;
         final Currency currency = Currency.USD;
         final String description = "";
-        final BillingModeType billingModeType = BillingModeType.IN_ADVANCE;
+        final BillingMode billingModeType = BillingMode.IN_ADVANCE;
         final BillingPeriod billingPeriod = BillingPeriod.MONTHLY;
         final Long totalOrdering = 0L;
         final DateTimeZone tz = DateTimeZone.UTC;
@@ -610,7 +610,7 @@ public class TestBlockingCalculator extends JunctionTestSuiteNoDB {
 
         public MockBillingEvent() {
             super(account, subscription1, clock.getUTCNow(), null, null, BigDecimal.ZERO, BigDecimal.TEN, Currency.USD, BillingPeriod.ANNUAL,
-                  4, BillingModeType.IN_ADVANCE, "", 3L, SubscriptionBaseTransitionType.CREATE, DateTimeZone.UTC);
+                  4, BillingMode.IN_ADVANCE, "", 3L, SubscriptionBaseTransitionType.CREATE, DateTimeZone.UTC);
         }
     }
 
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultBillingEvent.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultBillingEvent.java
index cb25cc1..79b50ea 100644
--- a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultBillingEvent.java
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestDefaultBillingEvent.java
@@ -26,6 +26,7 @@ import javax.annotation.Nullable;
 
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
+import org.killbill.billing.catalog.api.BillingMode;
 import org.mockito.Mockito;
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -45,7 +46,6 @@ import org.killbill.billing.subscription.api.SubscriptionBase;
 import org.killbill.billing.junction.JunctionTestSuiteNoDB;
 import org.killbill.billing.mock.MockAccountBuilder;
 import org.killbill.billing.junction.BillingEvent;
-import org.killbill.billing.junction.BillingModeType;
 
 public class TestDefaultBillingEvent extends JunctionTestSuiteNoDB {
 
@@ -190,7 +190,7 @@ public class TestDefaultBillingEvent extends JunctionTestSuiteNoDB {
         return new DefaultBillingEvent(account, sub, effectiveDate,
                                        shotgun, shotgunMonthly,
                                        BigDecimal.ZERO, null, Currency.USD, BillingPeriod.NO_BILLING_PERIOD, billCycleDay,
-                                       BillingModeType.IN_ADVANCE, "Test Event 1", totalOrdering, type, DateTimeZone.UTC);
+                                       BillingMode.IN_ADVANCE, "Test Event 1", totalOrdering, type, DateTimeZone.UTC);
     }
 
     private MockPlanPhase createMockMonthlyPlanPhase(@Nullable final BigDecimal recurringRate,
diff --git a/server/src/main/resources/SpyCarAdvanced.xml b/server/src/main/resources/SpyCarAdvanced.xml
index de7d4a6..99eecee 100644
--- a/server/src/main/resources/SpyCarAdvanced.xml
+++ b/server/src/main/resources/SpyCarAdvanced.xml
@@ -21,6 +21,8 @@
     <effectiveDate>2013-02-08T00:00:00+00:00</effectiveDate>
     <catalogName>SpyCarAdvanced</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>GBP</currency>
diff --git a/server/src/main/resources/SpyCarBasic.xml b/server/src/main/resources/SpyCarBasic.xml
index 9e59993..e69cfed 100644
--- a/server/src/main/resources/SpyCarBasic.xml
+++ b/server/src/main/resources/SpyCarBasic.xml
@@ -21,6 +21,8 @@
     <effectiveDate>2013-02-08T00:00:00+00:00</effectiveDate>
     <catalogName>SpyCarBasic</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>GBP</currency>
diff --git a/server/src/test/resources/catalog-weapons.xml b/server/src/test/resources/catalog-weapons.xml
index e72d2b2..64ed400 100644
--- a/server/src/test/resources/catalog-weapons.xml
+++ b/server/src/test/resources/catalog-weapons.xml
@@ -42,7 +42,9 @@ Use Cases to do:
 	<effectiveDate>2011-01-01T00:00:00+00:00</effectiveDate>
 	<catalogName>Firearms</catalogName>
 
-	<currencies>
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
+    <currencies>
 		<currency>USD</currency>
 		<currency>EUR</currency>
 		<currency>GBP</currency>
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimeline.java b/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimeline.java
index 3517577..af2acc8 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimeline.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/api/timeline/DefaultSubscriptionBaseTimeline.java
@@ -137,7 +137,7 @@ public class DefaultSubscriptionBaseTimeline implements SubscriptionBaseTimeline
                     final Plan plan = (userEV.getEventPlan() != null) ? catalog.findPlan(userEV.getEventPlan(), cur.getRequestedDate(), startDate) : null;
                     phaseType = (userEV.getEventPlanPhase() != null) ? catalog.findPhase(userEV.getEventPlanPhase(), cur.getEffectiveDate(), startDate).getPhaseType() : prevPhaseType;
                     productName = (plan != null) ? plan.getProduct().getName() : prevProductName;
-                    billingPeriod = getBillingPeriod(catalog, userEV.getEventPlanPhase(), cur.getEffectiveDate(), startDate);
+                    billingPeriod = (userEV.getEventPlanPhase() != null) ? getBillingPeriod(catalog, userEV.getEventPlanPhase(), cur.getEffectiveDate(), startDate) : prevBillingPeriod;
                     priceListName = (userEV.getPriceList() != null) ? userEV.getPriceList() : prevPriceListName;
                     break;
             }
diff --git a/subscription/src/test/resources/testInput.xml b/subscription/src/test/resources/testInput.xml
index 7a4f468..e4bd693 100644
--- a/subscription/src/test/resources/testInput.xml
+++ b/subscription/src/test/resources/testInput.xml
@@ -22,6 +22,8 @@
     <effectiveDate>2011-01-01T00:00:00+00:00</effectiveDate>
     <catalogName>Firearms</catalogName>
 
+    <recurringBillingMode>IN_ADVANCE</recurringBillingMode>
+
     <currencies>
         <currency>USD</currency>
         <currency>EUR</currency>