killbill-aplcache

Merge branch 'inv-ent-integration' of git@github.com:ning/killbill

1/27/2012 6:49:50 PM

Changes

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

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

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

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

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

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

pom.xml 2(+1 -1)

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

Details

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

diff --git a/account/pom.xml b/account/pom.xml
index 0146205..153f0bd 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.3-SNAPSHOT</version>
+        <version>0.1.4-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-account</artifactId>
diff --git a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
index 2b787f0..2e264c0 100644
--- a/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/DefaultAccountDao.java
@@ -31,7 +31,7 @@ import com.ning.billing.account.api.user.DefaultAccountChangeNotification;
 import com.ning.billing.account.api.user.DefaultAccountCreationEvent;
 import com.ning.billing.util.customfield.CustomField;
 import com.ning.billing.util.customfield.dao.FieldStoreDao;
-import com.ning.billing.util.eventbus.Bus;
+import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.tag.Tag;
 import com.ning.billing.util.tag.dao.TagStoreSqlDao;
 
diff --git a/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java b/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
index b6d0ab9..f4f530e 100644
--- a/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
+++ b/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
@@ -29,8 +29,8 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
 import com.ning.billing.account.glue.AccountModuleWithEmbeddedDb;
-import com.ning.billing.util.eventbus.DefaultEventBusService;
-import com.ning.billing.util.eventbus.BusService;
+import com.ning.billing.util.bus.DefaultBusService;
+import com.ning.billing.util.bus.BusService;
 
 public abstract class AccountDaoTestBase {
     protected AccountModuleWithEmbeddedDb module;
@@ -56,7 +56,7 @@ public abstract class AccountDaoTestBase {
             accountDao.test();
 
             BusService busService = injector.getInstance(BusService.class);
-            ((DefaultEventBusService) busService).startBus();
+            ((DefaultBusService) busService).startBus();
         }
         catch (Throwable t) {
             fail(t.toString());
diff --git a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
index 71a1793..b351709 100644
--- a/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/MockAccountDao.java
@@ -28,8 +28,8 @@ import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountChangeNotification;
 import com.ning.billing.account.api.user.DefaultAccountChangeNotification;
 import com.ning.billing.account.api.user.DefaultAccountCreationEvent;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.Bus.EventBusException;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
 
 public class MockAccountDao implements AccountDao {
     private final Bus eventBus;
diff --git a/analytics/pom.xml b/analytics/pom.xml
index 4cd7332..7368654 100644
--- a/analytics/pom.xml
+++ b/analytics/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.3-SNAPSHOT</version>
+        <version>0.1.4-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-analytics</artifactId>
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/AnalyticsService.java b/analytics/src/main/java/com/ning/billing/analytics/api/AnalyticsService.java
index e537841..4adb21e 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/api/AnalyticsService.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/AnalyticsService.java
@@ -19,7 +19,7 @@ package com.ning.billing.analytics.api;
 import com.google.inject.Inject;
 import com.ning.billing.analytics.AnalyticsListener;
 import com.ning.billing.lifecycle.LifecycleHandlerType;
-import com.ning.billing.util.eventbus.Bus;
+import com.ning.billing.util.bus.Bus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
index 79bf994..395d694 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
@@ -47,7 +47,7 @@ import com.ning.billing.entitlement.api.user.SubscriptionTransition;
 import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
-import com.ning.billing.util.eventbus.Bus;
+import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.tag.DescriptiveTag;
 import com.ning.billing.util.tag.DefaultTagDefinition;
 import com.ning.billing.util.tag.Tag;

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

diff --git a/api/pom.xml b/api/pom.xml
index 89f3a43..7c0dcd7 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.3-SNAPSHOT</version>
+        <version>0.1.4-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-api</artifactId>
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountChangeNotification.java b/api/src/main/java/com/ning/billing/account/api/AccountChangeNotification.java
index 2bc40f8..4102447 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountChangeNotification.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountChangeNotification.java
@@ -16,7 +16,7 @@
 
 package com.ning.billing.account.api;
 
-import com.ning.billing.util.eventbus.BusEvent;
+import com.ning.billing.util.bus.BusEvent;
 
 import java.util.List;
 import java.util.UUID;
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountCreationNotification.java b/api/src/main/java/com/ning/billing/account/api/AccountCreationNotification.java
index 22a1752..b30d290 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountCreationNotification.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountCreationNotification.java
@@ -16,7 +16,7 @@
 
 package com.ning.billing.account.api;
 
-import com.ning.billing.util.eventbus.BusEvent;
+import com.ning.billing.util.bus.BusEvent;
 
 import java.util.UUID;
 
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java b/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
index 5a23528..e208c83 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountUserApi.java
@@ -19,7 +19,6 @@ package com.ning.billing.account.api;
 import java.util.List;
 import java.util.UUID;
 import com.ning.billing.util.customfield.CustomField;
-import com.ning.billing.util.eventbus.Bus;
 import com.ning.billing.util.tag.Tag;
 
 public interface AccountUserApi {
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransition.java b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransition.java
index 449c368..f4c971d 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransition.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionTransition.java
@@ -19,7 +19,7 @@ package com.ning.billing.entitlement.api.user;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
-import com.ning.billing.util.eventbus.BusEvent;
+import com.ning.billing.util.bus.BusEvent;
 import org.joda.time.DateTime;
 
 import java.util.UUID;
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceCreationNotification.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceCreationNotification.java
index 86f2f23..478a1fb 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceCreationNotification.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceCreationNotification.java
@@ -22,7 +22,7 @@ import java.util.UUID;
 import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.util.eventbus.BusEvent;
+import com.ning.billing.util.bus.BusEvent;
 
 public interface InvoiceCreationNotification extends BusEvent {
     public UUID getInvoiceId();
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
index 1d62eb5..8e665ed 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
@@ -42,9 +42,9 @@ public interface PaymentApi {
 
     Either<PaymentError, PaymentProviderAccount> getPaymentProviderAccount(String accountKey);
 
-    Either<PaymentError, PaymentProviderAccount> createPaymentProviderAccount(PaymentProviderAccount account);
+    Either<PaymentError, String> createPaymentProviderAccount(Account account);
 
-    Either<PaymentError, PaymentProviderAccount> updatePaymentProviderAccount(PaymentProviderAccount account);
+    Either<PaymentError, PaymentProviderAccount> updatePaymentProviderAccount(Account account);
 
     PaymentAttempt getPaymentAttemptForPaymentId(String id);
 
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentError.java b/api/src/main/java/com/ning/billing/payment/api/PaymentError.java
index 2eba03d..f1474c8 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentError.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentError.java
@@ -18,7 +18,7 @@ package com.ning.billing.payment.api;
 import org.codehaus.jackson.annotate.JsonTypeInfo;
 import org.codehaus.jackson.annotate.JsonTypeInfo.Id;
 
-import com.ning.billing.util.eventbus.BusEvent;
+import com.ning.billing.util.bus.BusEvent;
 
 @JsonTypeInfo(use = Id.NAME, property = "error")
 public class PaymentError implements BusEvent {
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java b/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
index 6fa5c60..b8dc8cd 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
@@ -23,7 +23,7 @@ import org.codehaus.jackson.annotate.JsonProperty;
 import org.joda.time.DateTime;
 
 import com.google.common.base.Objects;
-import com.ning.billing.util.eventbus.BusEvent;
+import com.ning.billing.util.bus.BusEvent;
 
 public class PaymentInfo implements BusEvent {
     private final String paymentId;

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

diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index 62c43fc..792a09e 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.3-SNAPSHOT</version>
+        <version>0.1.4-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-beatrix</artifactId>
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/MockModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/MockModule.java
index 7841119..8816190 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/MockModule.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/MockModule.java
@@ -23,7 +23,6 @@ import java.net.URL;
 import java.util.Set;
 
 import org.skife.config.ConfigurationObjectFactory;
-import org.skife.jdbi.v2.DBI;
 import org.skife.jdbi.v2.IDBI;
 
 import com.google.common.collect.ImmutableSet;
@@ -44,7 +43,7 @@ import com.ning.billing.invoice.glue.InvoiceModule;
 import com.ning.billing.lifecycle.KillbillService;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
-import com.ning.billing.util.eventbus.BusService;
+import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.glue.BusModule;
 import com.ning.billing.util.glue.NotificationQueueModule;
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/TestBasic.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/TestBasic.java
index e6b7dcc..9753d7f 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/TestBasic.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/TestBasic.java
@@ -60,7 +60,7 @@ import com.ning.billing.invoice.api.InvoiceService;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 
 import com.ning.billing.util.clock.ClockMock;
-import com.ning.billing.util.eventbus.BusService;
+import com.ning.billing.util.bus.BusService;
 
 @Guice(modules = {MockModule.class})
 public class TestBasic {
@@ -191,6 +191,7 @@ public class TestBasic {
                 new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null);
         assertNotNull(subscription);
         assertTrue(busHandler.isCompleted(5000));
+        log.info("testSimple passed first busHandler checkpoint.");
 
         //
         // VERIFY CTD HAS BEEN SET
@@ -208,6 +209,7 @@ public class TestBasic {
         String newProductName = "Assault-Rifle";
         subscription.changePlan(newProductName, newTerm, newPlanSetName, clock.getUTCNow());
         assertTrue(busHandler.isCompleted(5000));
+        log.info("testSimple passed second busHandler checkpoint.");
 
         //
         // VERIFY AGAIN CTD HAS BEEN SET
@@ -230,6 +232,7 @@ public class TestBasic {
         clock.setDeltaFromReality(ctd.getMillis() - clock.getUTCNow().getMillis());
         //clock.setDeltaFromReality(AT_LEAST_ONE_MONTH_MS + 1000);
         assertTrue(busHandler.isCompleted(5000));
+        log.info("testSimple passed third busHandler checkpoint.");
 
         //
         // MOVE TIME AFTER NEXT BILL CYCLE DAY AND EXPECT EVENT : NextEvent.INVOICE
@@ -239,6 +242,7 @@ public class TestBasic {
         do {
             clock.addDeltaFromReality(AT_LEAST_ONE_MONTH_MS + 1000);
             busHandler.pushExpectedEvent(NextEvent.INVOICE);
+            busHandler.pushExpectedEvent(NextEvent.INVOICE);
             assertTrue(busHandler.isCompleted(5000));
             lastCtd = checkAndGetCTD(subscription.getId());
         } while (maxCycles-- > 0);
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/TestBusHandler.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/TestBusHandler.java
index 0c3e035..58074c6 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/TestBusHandler.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/inv_ent/TestBusHandler.java
@@ -143,13 +143,13 @@ public class TestBusHandler {
         log.debug("notifyIfStackEmpty EXIT");
     }
 
-    private void assertEqualsNicely(NextEvent expected) {
+    private void assertEqualsNicely(NextEvent received) {
 
         boolean foundIt = false;
         Iterator<NextEvent> it = nextExpectedEvent.iterator();
         while (it.hasNext()) {
             NextEvent ev = it.next();
-            if (ev == expected) {
+            if (ev == received) {
                 it.remove();
                 foundIt = true;
                 break;
@@ -157,7 +157,7 @@ public class TestBusHandler {
         }
         if (!foundIt) {
             Joiner joiner = Joiner.on(" ");
-            System.err.println("Expected event " + expected + " got " + joiner.join(nextExpectedEvent));
+            System.err.println("Received event " + received + "; expected " + joiner.join(nextExpectedEvent));
             System.exit(1);
         }
     }

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

diff --git a/catalog/pom.xml b/catalog/pom.xml
index 1324140..09e0e48 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.3-SNAPSHOT</version>
+        <version>0.1.4-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-catalog</artifactId>
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultInternationalPrice.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultInternationalPrice.java
index 6990d3c..1c505f9 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultInternationalPrice.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultInternationalPrice.java
@@ -42,7 +42,7 @@ public class DefaultInternationalPrice extends ValidatingConfig<StandaloneCatalo
 
 
 	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IInternationalPrice#getPrices()
+	 * @see com.ning.billing.catalog.InternationalPrice#getPrices()
 	 */
 	@Override
 	public Price[] getPrices() {
diff --git a/catalog/src/main/java/com/ning/billing/catalog/DefaultPrice.java b/catalog/src/main/java/com/ning/billing/catalog/DefaultPrice.java
index d9d26a6..9b5f00b 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/DefaultPrice.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/DefaultPrice.java
@@ -35,6 +35,16 @@ public class DefaultPrice extends ValidatingConfig<StandaloneCatalog> implements
 	@XmlElement(required=true,nillable=true)
 	private BigDecimal value;
 
+    public DefaultPrice() {
+        // for serialization support
+    }
+
+    public DefaultPrice(final BigDecimal value, final Currency currency) {
+        // for sanity support
+        this.value = value;
+        this.currency = currency;
+    }
+
 	/* (non-Javadoc)
 	 * @see com.ning.billing.catalog.IPrice#getCurrency()
 	 */
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java b/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java
index 773c58b..c290979 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java
@@ -22,14 +22,14 @@ import java.math.BigDecimal;
 import java.util.Date;
 
 public class MockInternationalPrice extends DefaultInternationalPrice {
-	
-	MockInternationalPrice() {
+
+	public MockInternationalPrice() {
 		setPrices(new DefaultPrice[] {
-			new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(1))	
+			new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(1))
 		});
 	}
-	
-	MockInternationalPrice(DefaultPrice... price) {
+
+	public MockInternationalPrice(DefaultPrice... price) {
 		setPrices(price);
 	}
 
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java b/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
index fb244eb..2ef5768 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
@@ -20,6 +20,8 @@ import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.TimeUnit;
 
+import javax.annotation.Nullable;
+
 public class MockPlanPhase extends DefaultPlanPhase {
 
     public MockPlanPhase(
@@ -36,11 +38,29 @@ public class MockPlanPhase extends DefaultPlanPhase {
 	}
     
     public MockPlanPhase() {
-		setBillingPeriod(BillingPeriod.MONTHLY);
-		setPhaseType(PhaseType.EVERGREEN);
+        this(new MockInternationalPrice(), null);
+	}
+
+    public MockPlanPhase(@Nullable MockInternationalPrice recurringPrice,
+                         @Nullable MockInternationalPrice fixedPrice) {
+        this(recurringPrice, fixedPrice, BillingPeriod.MONTHLY);
+	}
+
+    public MockPlanPhase(@Nullable MockInternationalPrice recurringPrice,
+                         @Nullable MockInternationalPrice fixedPrice,
+                         BillingPeriod billingPeriod) {
+		this(recurringPrice, fixedPrice, billingPeriod, PhaseType.EVERGREEN);
+	}
+
+    public MockPlanPhase(@Nullable MockInternationalPrice recurringPrice,
+                         @Nullable MockInternationalPrice fixedPrice,
+                         BillingPeriod billingPeriod,
+                         PhaseType phaseType) {
+		setBillingPeriod(billingPeriod);
+		setPhaseType(phaseType);
 		setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
-		setReccuringPrice(new MockInternationalPrice());
-		setFixedPrice(null);
+		setReccuringPrice(recurringPrice);
+		setFixedPrice(fixedPrice);
 		setPlan(new MockPlan(this));
 	}
 
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 4ed28e9..b75837c 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.3-SNAPSHOT</version>
+        <version>0.1.4-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-entitlement</artifactId>
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
index c3563bb..ce70ba7 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/Engine.java
@@ -45,8 +45,8 @@ import com.ning.billing.entitlement.exceptions.EntitlementError;
 import com.ning.billing.lifecycle.LifecycleHandlerType;
 import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
 import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.Bus.EventBusException;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
 import com.ning.billing.util.notificationq.NotificationConfig;
 import com.ning.billing.util.notificationq.NotificationQueue;
 import com.ning.billing.util.notificationq.NotificationQueueService;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
index 154acb5..e5f15ed 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
@@ -220,9 +220,9 @@ public class EntitlementSqlDao implements EntitlementDao {
 
                 dao.insertSubscription(subscription);
                 // STEPH batch as well
-                EventSqlDao eventsDaoFromSameTranscation = dao.become(EventSqlDao.class);
+                EventSqlDao eventsDaoFromSameTransaction = dao.become(EventSqlDao.class);
                 for (final EntitlementEvent cur : initialEvents) {
-                    eventsDaoFromSameTranscation.insertEvent(cur);
+                    eventsDaoFromSameTransaction.insertEvent(cur);
                     recordFutureNotificationFromTransaction(dao,
                             cur.getEffectiveDate(),
                             new NotificationKey() {
@@ -443,9 +443,9 @@ public class EntitlementSqlDao implements EntitlementDao {
 
     private void recordFutureNotificationFromTransaction(final Transmogrifier transactionalDao, final DateTime effectiveDate, final NotificationKey notificationKey) {
         try {
-            NotificationQueue subscritionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
+            NotificationQueue subscriptionEventQueue = notificationQueueService.getNotificationQueue(Engine.ENTITLEMENT_SERVICE_NAME,
                 Engine.NOTIFICATION_QUEUE_NAME);
-            subscritionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, notificationKey);
+            subscriptionEventQueue.recordFutureNotificationFromTransaction(transactionalDao, effectiveDate, notificationKey);
         } catch (NoSuchNotificationQueue e) {
             throw new RuntimeException(e);
         }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java
index 7241611..39f6c48 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java
@@ -19,7 +19,7 @@ package com.ning.billing.entitlement.api;
 import com.google.common.base.Joiner;
 import com.google.common.eventbus.Subscribe;
 import com.ning.billing.entitlement.api.user.SubscriptionTransition;
-import com.ning.billing.util.eventbus.Bus;
+import com.ning.billing.util.bus.Bus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
index 75d2ab9..46ad9a2 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/billing/TestDefaultEntitlementBillingApi.java
@@ -59,6 +59,8 @@ import com.ning.billing.lifecycle.KillbillService.ServiceException;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
+import static org.testng.Assert.assertTrue;
+
 public class TestDefaultEntitlementBillingApi {
 	private static final UUID zeroId = new UUID(0L,0L);
 	private static final UUID oneId = new UUID(1L,0L);
@@ -138,6 +140,7 @@ public class TestDefaultEntitlementBillingApi {
 			}
 		};
 
+        assertTrue(true);
 	}
 	
     @Test(enabled=true, groups="fast")
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 4018002..c00b4e7 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
@@ -67,8 +67,8 @@ import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.lifecycle.KillbillService.ServiceException;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
-import com.ning.billing.util.eventbus.DefaultEventBusService;
-import com.ning.billing.util.eventbus.BusService;
+import com.ning.billing.util.bus.DefaultBusService;
+import com.ning.billing.util.bus.BusService;
 
 
 public abstract class TestApiBase {
@@ -110,7 +110,7 @@ public abstract class TestApiBase {
     public void tearDown() {
         try {
             busService.getBus().register(testListener);
-            ((DefaultEventBusService) busService).stopBus();
+            ((DefaultBusService) busService).stopBus();
         } catch (Exception e) {
             log.warn("Failed to tearDown test properly ", e);
         }
@@ -131,7 +131,7 @@ public abstract class TestApiBase {
         clock = (ClockMock) g.getInstance(Clock.class);
         try {
             ((DefaultCatalogService) catalogService).loadCatalog();
-            ((DefaultEventBusService) busService).startBus();
+            ((DefaultBusService) busService).startBus();
             ((Engine) entitlementService).initialize();
             init();
         } catch (EntitlementUserApiException e) {

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

diff --git a/invoice/pom.xml b/invoice/pom.xml
index f153db0..6b7cb14 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.3-SNAPSHOT</version>
+        <version>0.1.4-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-invoice</artifactId>
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/DefaultInvoiceService.java b/invoice/src/main/java/com/ning/billing/invoice/api/DefaultInvoiceService.java
index df43d71..6f033db 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/DefaultInvoiceService.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/DefaultInvoiceService.java
@@ -21,7 +21,7 @@ import com.ning.billing.invoice.InvoiceListener;
 import com.ning.billing.invoice.notification.NextBillingDateNotifier;
 import com.ning.billing.lifecycle.LifecycleHandlerType;
 import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
-import com.ning.billing.util.eventbus.Bus;
+import com.ning.billing.util.bus.Bus;
 
 public class DefaultInvoiceService implements InvoiceService {
 
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 6e720f0..aa2cb63 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
@@ -33,7 +33,7 @@ import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.user.DefaultInvoiceCreationNotification;
 import com.ning.billing.invoice.notification.NextBillingDateNotifier;
-import com.ning.billing.util.eventbus.Bus;
+import com.ning.billing.util.bus.Bus;
 
 public class DefaultInvoiceDao implements InvoiceDao {
     private final InvoiceSqlDao invoiceSqlDao;
diff --git a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
index 487f181..54efe1b 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/InvoiceListener.java
@@ -62,7 +62,7 @@ public class InvoiceListener {
 
     @Subscribe
     public void handleSubscriptionTransition(final SubscriptionTransition transition) {
-        processSubscription(transition.getSubscriptionId(), transition.getEffectiveTransitionTime());
+        processSubscription(transition);
     }
 
     @Subscribe
@@ -70,9 +70,15 @@ public class InvoiceListener {
         processSubscription(event.getSubscriptionId(), new DateTime());
     }
 
-    private void processSubscription(final UUID subscriptionId, final DateTime targetDate) {
-        log.info("Got subscription transition from InvoiceListener.");
+    private void processSubscription(final SubscriptionTransition transition) {
+        UUID subscriptionId = transition.getSubscriptionId();
+        DateTime targetDate = transition.getEffectiveTransitionTime();
+        log.info("Got subscription transition from InvoiceListener. id: " + subscriptionId.toString() + "; targetDate: " + targetDate.toString());
+        log.info("Transition type: " + transition.getTransitionType().toString());
+        processSubscription(subscriptionId, targetDate);
+    }
 
+    private void processSubscription(final UUID subscriptionId, final DateTime targetDate) {
         if (subscriptionId == null) {
             log.error("Failed handling entitlement change.", new InvoiceApiException(ErrorCode.INVOICE_INVALID_TRANSITION));
             return;
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
index 2dc2144..899b4a5 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
@@ -42,20 +42,27 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
     public Invoice generateInvoice(final UUID accountId, final BillingEventSet events,
                                    final InvoiceItemList existingItems, final DateTime targetDate,
                                    final Currency targetCurrency) {
-        if (events == null) {return new DefaultInvoice(accountId, targetDate, targetCurrency);}
-        if (events.size() == 0) {return new DefaultInvoice(accountId, targetDate, targetCurrency);}
+        if (events == null) {return null;}
+        if (events.size() == 0) {return null;}
 
         DefaultInvoice invoice = new DefaultInvoice(accountId, targetDate, targetCurrency);
         InvoiceItemList currentItems = generateInvoiceItems(events, invoice.getId(), targetDate, targetCurrency);
         InvoiceItemList itemsToPost = reconcileInvoiceItems(invoice.getId(), currentItems, existingItems);
 
-        invoice.addInvoiceItems(itemsToPost);
-
-        return invoice;
+        if (itemsToPost.size() == 0) {
+            return null;
+        } else {
+            invoice.addInvoiceItems(itemsToPost);
+            return invoice;
+        }
     }
 
     private InvoiceItemList reconcileInvoiceItems(final UUID invoiceId, final InvoiceItemList currentInvoiceItems,
                                                   final InvoiceItemList existingInvoiceItems) {
+        if (existingInvoiceItems == null) {
+            return currentInvoiceItems;
+        }
+
         InvoiceItemList currentItems = new InvoiceItemList();
         for (final InvoiceItem item : currentInvoiceItems) {
             currentItems.add(new DefaultInvoiceItem(item, invoiceId));
@@ -77,18 +84,14 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
                 }
             }
         }
-
         existingItems.removeAll(existingItemsToRemove);
 
         // remove cancelling pairs of invoice items
         existingItems.removeCancellingPairs();
 
-        // remove zero-dollar invoice items
-        //currentItems.removeZeroDollarItems();
-
         // add existing items that aren't covered by current items as credit items
         for (final InvoiceItem existingItem : existingItems) {
-            currentItems.add(existingItem.asCredit(invoiceId));
+            currentItems.add(existingItem.asCredit(existingItem.getInvoiceId()));
         }
 
         return currentItems;
@@ -129,11 +132,14 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
             InternationalPrice recurringPrice = event.getRecurringPrice();
     		BigDecimal rate = (recurringPrice == null) ? BigDecimal.ZERO : recurringPrice.getPrice(targetCurrency);
 
-    		BigDecimal invoiceItemAmount = calculateInvoiceItemAmount(event, targetDate, rate);
-    		BillingMode billingMode = getBillingMode(event.getBillingMode());
-    		DateTime billThroughDate = billingMode.calculateEffectiveEndDate(event.getEffectiveDate(), targetDate, event.getBillCycleDay(), event.getBillingPeriod());
+    		BigDecimal numberOfBillingPeriods = calculateNumberOfBillingPeriods(event, targetDate);
+            if (numberOfBillingPeriods.compareTo(BigDecimal.ZERO) != 0) {
+                BigDecimal invoiceItemAmount = numberOfBillingPeriods.multiply(rate);
+                BillingMode billingMode = getBillingMode(event.getBillingMode());
+                DateTime billThroughDate = billingMode.calculateEffectiveEndDate(event.getEffectiveDate(), targetDate, event.getBillCycleDay(), event.getBillingPeriod());
 
-    		addInvoiceItem(invoiceId, items, event, billThroughDate, invoiceItemAmount, rate, targetCurrency);
+                addInvoiceItem(invoiceId, items, event, billThroughDate, invoiceItemAmount, rate, targetCurrency);
+            }
     	} catch (CatalogApiException e) {
             log.error(String.format("Encountered a catalog error processing invoice %s for billing event on date %s", 
                     invoiceId.toString(), 
@@ -143,16 +149,19 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
 
     private void processEvents(final UUID invoiceId, final BillingEvent firstEvent, final BillingEvent secondEvent,
                                final List<InvoiceItem> items, final DateTime targetDate, final Currency targetCurrency) {
-    	//TODO: Jeff getPrice() -> getRecurringPrice()
     	try {
             InternationalPrice recurringPrice = firstEvent.getRecurringPrice();
-            BigDecimal rate = (recurringPrice == null) ? BigDecimal.ZERO : recurringPrice.getPrice(targetCurrency);
-
-            BigDecimal invoiceItemAmount = calculateInvoiceItemAmount(firstEvent, secondEvent, targetDate, rate);
-            BillingMode billingMode = getBillingMode(firstEvent.getBillingMode());
-            DateTime billThroughDate = billingMode.calculateEffectiveEndDate(firstEvent.getEffectiveDate(), secondEvent.getEffectiveDate(), targetDate, firstEvent.getBillCycleDay(), firstEvent.getBillingPeriod());
-
-            addInvoiceItem(invoiceId, items, firstEvent, billThroughDate, invoiceItemAmount, rate, targetCurrency);
+            if (recurringPrice != null) {
+                BigDecimal rate = recurringPrice.getPrice(targetCurrency);
+                BigDecimal numberOfBillingPeriods = calculateNumberOfBillingPeriods(firstEvent, secondEvent, targetDate);
+                if (numberOfBillingPeriods.compareTo(BigDecimal.ZERO) != 0) {
+                    BigDecimal invoiceItemAmount = numberOfBillingPeriods.multiply(rate);
+                    BillingMode billingMode = getBillingMode(firstEvent.getBillingMode());
+                    DateTime billThroughDate = billingMode.calculateEffectiveEndDate(firstEvent.getEffectiveDate(), secondEvent.getEffectiveDate(), targetDate, firstEvent.getBillCycleDay(), firstEvent.getBillingPeriod());
+
+                    addInvoiceItem(invoiceId, items, firstEvent, billThroughDate, invoiceItemAmount, rate, targetCurrency);
+                }
+            }
     	} catch (CatalogApiException e) {
     		log.error(String.format("Encountered a catalog error processing invoice %s for billing event on date %s",
                     invoiceId.toString(),
@@ -163,31 +172,26 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
     private void addInvoiceItem(final UUID invoiceId, final List<InvoiceItem> items, final BillingEvent event,
                                 final DateTime billThroughDate, final BigDecimal amount, final BigDecimal rate,
                                 final Currency currency) {
-        //if (!(amount.compareTo(BigDecimal.ZERO) == 0)) {
-            DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, event.getSubscription().getId(), event.getEffectiveDate(), billThroughDate, event.getDescription(), amount, rate, currency);
-            items.add(item);
-        //}
+        DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, event.getSubscription().getId(), event.getEffectiveDate(), billThroughDate, event.getDescription(), amount, rate, currency);
+        items.add(item);
     }
 
-    private BigDecimal calculateInvoiceItemAmount(final BillingEvent event, final DateTime targetDate,
-                                                  final BigDecimal rate){
+    private BigDecimal calculateNumberOfBillingPeriods(final BillingEvent event, final DateTime targetDate){
         BillingMode billingMode = getBillingMode(event.getBillingMode());
         DateTime startDate = event.getEffectiveDate();
         int billingCycleDay = event.getBillCycleDay();
         BillingPeriod billingPeriod = event.getBillingPeriod();
 
         try {
-            BigDecimal numberOfBillingCycles;
-            numberOfBillingCycles = billingMode.calculateNumberOfBillingCycles(startDate, targetDate, billingCycleDay, billingPeriod);
-            return numberOfBillingCycles.multiply(rate);
+            return billingMode.calculateNumberOfBillingCycles(startDate, targetDate, billingCycleDay, billingPeriod);
         } catch (InvalidDateSequenceException e) {
             // TODO: Jeff -- log issue
             return BigDecimal.ZERO;
         }
     }
 
-    private BigDecimal calculateInvoiceItemAmount(final BillingEvent firstEvent, final BillingEvent secondEvent,
-                                                  final DateTime targetDate, final BigDecimal rate) {
+    private BigDecimal calculateNumberOfBillingPeriods(final BillingEvent firstEvent, final BillingEvent secondEvent,
+                                                  final DateTime targetDate) {
         BillingMode billingMode = getBillingMode(firstEvent.getBillingMode());
         DateTime startDate = firstEvent.getEffectiveDate();
         int billingCycleDay = firstEvent.getBillCycleDay();
@@ -196,9 +200,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         DateTime endDate = secondEvent.getEffectiveDate();
 
         try {
-            BigDecimal numberOfBillingCycles;
-            numberOfBillingCycles = billingMode.calculateNumberOfBillingCycles(startDate, endDate, targetDate, billingCycleDay, billingPeriod);
-            return numberOfBillingCycles.multiply(rate);
+            return billingMode.calculateNumberOfBillingCycles(startDate, endDate, targetDate, billingCycleDay, billingPeriod);
         } catch (InvalidDateSequenceException e) {
             // TODO: Jeff -- log issue
             return BigDecimal.ZERO;
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java
index dfed0db..3fd03b2 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/DefaultNextBillingDateNotifier.java
@@ -18,6 +18,8 @@ package com.ning.billing.invoice.notification;
 
 import java.util.UUID;
 
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
@@ -26,11 +28,8 @@ import org.slf4j.LoggerFactory;
 import com.google.inject.Inject;
 import com.ning.billing.config.InvoiceConfig;
 import com.ning.billing.invoice.api.DefaultInvoiceService;
-import com.ning.billing.lifecycle.KillbillService;
-import com.ning.billing.lifecycle.LifecycleHandlerType;
-import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.Bus.EventBusException;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
 import com.ning.billing.util.notificationq.NotificationConfig;
 import com.ning.billing.util.notificationq.NotificationKey;
 import com.ning.billing.util.notificationq.NotificationQueue;
@@ -47,17 +46,19 @@ public class DefaultNextBillingDateNotifier implements  NextBillingDateNotifier 
     private final Bus eventBus;
     private final NotificationQueueService notificationQueueService;
 	private final InvoiceConfig config;
+    private final EntitlementDao entitlementDao;
 
     private NotificationQueue nextBillingQueue;
 
     @Inject
-	public DefaultNextBillingDateNotifier(NotificationQueueService notificationQueueService, Bus eventBus, InvoiceConfig config){
+	public DefaultNextBillingDateNotifier(NotificationQueueService notificationQueueService, Bus eventBus,
+                                          InvoiceConfig config, EntitlementDao entitlementDao){
 		this.notificationQueueService = notificationQueueService;
 		this.config = config;
 		this.eventBus = eventBus;
+        this.entitlementDao = entitlementDao;
 	}
 
-
     @Override
     public void initialize() {
 		try {
@@ -68,13 +69,18 @@ public class DefaultNextBillingDateNotifier implements  NextBillingDateNotifier 
                 public void handleReadyNotification(String notificationKey) {
                 	UUID subscriptionId;
                 	try {
-                		subscriptionId = UUID.fromString(notificationKey);
+                 		UUID key = UUID.fromString(notificationKey);
+                        Subscription subscription = entitlementDao.getSubscriptionFromId(key);
+                        if (subscription == null) {
+                            log.warn("Next Billing Date Notification Queue handled spurious notification (key: " + key + ")" );
+                        } else {
+                            processEvent(key);
+                        }
                 	} catch (IllegalArgumentException e) {
-                		log.error("The key returned from the NextBillingNotificationQueue is not a valid UUID",e);
+                		log.error("The key returned from the NextBillingNotificationQueue is not a valid UUID", e);
                 		return;
                 	}
 
-                    processEvent(subscriptionId);
                 }
             },
             new NotificationConfig() {
@@ -121,9 +127,10 @@ public class DefaultNextBillingDateNotifier implements  NextBillingDateNotifier 
     }
 
     @Override
-    public void insertNextBillingNotification(Transmogrifier transactionalDao, final UUID subscriptionId, DateTime futureNotificationTime) {
+    public void insertNextBillingNotification(final Transmogrifier transactionalDao, final UUID subscriptionId, final DateTime futureNotificationTime) {
     	if (nextBillingQueue != null) {
             log.info("Queuing next billing date notification. id: {}, timestamp: {}", subscriptionId.toString(), futureNotificationTime.toString());
+
             nextBillingQueue.recordFutureNotificationFromTransaction(transactionalDao, futureNotificationTime, new NotificationKey(){
                 @Override
                 public String toString() {
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/NextBillingDateEvent.java b/invoice/src/main/java/com/ning/billing/invoice/notification/NextBillingDateEvent.java
index 59ec8a2..659d9e9 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/NextBillingDateEvent.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/NextBillingDateEvent.java
@@ -18,7 +18,7 @@ package com.ning.billing.invoice.notification;
 
 import java.util.UUID;
 
-import com.ning.billing.util.eventbus.BusEvent;
+import com.ning.billing.util.bus.BusEvent;
 
 public class NextBillingDateEvent implements BusEvent{
 	private final UUID subscriptionId;
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 ce7a429..f483773 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
@@ -91,15 +91,6 @@ getUnpaidInvoicesByAccountId() ::= <<
   ORDER BY i.target_date ASC;
 >>
 
-getAccountBalance() ::= <<
-  SELECT SUM(iis.total_amount) AS amount_invoiced, SUM(ips.total_paid) AS amount_paid
-  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
-  GROUP BY i.account_id;
->>
-
 test() ::= <<
   SELECT 1
   FROM 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 8e54bb6..4779495 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
@@ -21,6 +21,7 @@ import static org.testng.Assert.fail;
 
 import java.io.IOException;
 
+import com.ning.billing.invoice.tests.InvoicingTestBase;
 import org.apache.commons.io.IOUtils;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -29,10 +30,10 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
 import com.ning.billing.invoice.glue.InvoiceModuleWithEmbeddedDb;
-import com.ning.billing.util.eventbus.BusService;
-import com.ning.billing.util.eventbus.DefaultEventBusService;
+import com.ning.billing.util.bus.BusService;
+import com.ning.billing.util.bus.DefaultBusService;
 
-public abstract class InvoiceDaoTestBase {
+public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
     protected InvoiceDao invoiceDao;
     protected InvoiceItemSqlDao invoiceItemDao;
     protected InvoicePaymentSqlDao invoicePaymentDao;
@@ -60,7 +61,7 @@ public abstract class InvoiceDaoTestBase {
             invoicePaymentDao = module.getInvoicePaymentSqlDao();
 
             BusService busService = injector.getInstance(BusService.class);
-            ((DefaultEventBusService) busService).startBus();
+            ((DefaultBusService) busService).startBus();
 
             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 8ce7a26..66ad993 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
@@ -16,13 +16,31 @@
 
 package com.ning.billing.invoice.dao;
 
+import com.ning.billing.catalog.DefaultPrice;
+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.PhaseType;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
+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.user.EntitlementUserApiException;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoicePayment;
+import com.ning.billing.invoice.model.BillingEventSet;
 import com.ning.billing.invoice.model.DefaultInvoice;
+import com.ning.billing.invoice.model.DefaultInvoiceGenerator;
 import com.ning.billing.invoice.model.DefaultInvoiceItem;
 import com.ning.billing.invoice.model.DefaultInvoicePayment;
+import com.ning.billing.invoice.model.InvoiceGenerator;
+import com.ning.billing.invoice.model.InvoiceItemList;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 import org.joda.time.DateTime;
@@ -35,6 +53,7 @@ import java.util.List;
 import java.util.UUID;
 
 import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
 
 @Test(groups = {"invoicing", "invoicing-invoiceDao"})
 public class InvoiceDaoTests extends InvoiceDaoTestBase {
@@ -448,4 +467,189 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate);
         assertEquals(invoices.size(), 2);
     }
+
+    /*
+     *
+     * this test verifies that immediate changes give the correct results
+     *
+     */
+    @Test
+    public void testInvoiceGenerationForImmediateChanges() {
+        InvoiceGenerator generator = new DefaultInvoiceGenerator();
+
+        UUID accountId = UUID.randomUUID();
+        InvoiceItemList invoiceItemList = new InvoiceItemList();
+        DateTime targetDate = new DateTime(2011, 2, 16, 0, 0, 0, 0);
+
+        // generate first invoice
+        DefaultPrice price1 = new DefaultPrice(TEN, Currency.USD);
+        MockInternationalPrice recurringPrice = new MockInternationalPrice(price1);
+        MockPlanPhase phase1 = new MockPlanPhase(recurringPrice, null, BillingPeriod.MONTHLY, PhaseType.TRIAL);
+        MockPlan plan1 = new MockPlan(phase1);
+
+        Subscription subscription = new MockSubscription();
+        DateTime effectiveDate1 = new DateTime(2011, 2, 1, 0, 0, 0, 0);
+        BillingEvent event1 = new DefaultBillingEvent(subscription, effectiveDate1, plan1, phase1, null,
+                                                      recurringPrice, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                      "testEvent1");
+
+        BillingEventSet events = new BillingEventSet();
+        events.add(event1);
+
+        Invoice invoice1 = generator.generateInvoice(accountId, events, invoiceItemList, targetDate, Currency.USD);
+        assertEquals(invoice1.getBalance(), TEN);
+        invoiceItemList.addAll(invoice1.getInvoiceItems());
+
+        // generate second invoice
+        DefaultPrice price2 = new DefaultPrice(TWENTY, Currency.USD);
+        MockInternationalPrice recurringPrice2 = new MockInternationalPrice(price2);
+        MockPlanPhase phase2 = new MockPlanPhase(recurringPrice, null, BillingPeriod.MONTHLY, PhaseType.TRIAL);
+        MockPlan plan2 = new MockPlan(phase2);
+
+        DateTime effectiveDate2 = new DateTime(2011, 2, 15, 0, 0, 0, 0);
+        BillingEvent event2 = new DefaultBillingEvent(subscription, effectiveDate2, plan2, phase2, null,
+                                                      recurringPrice2, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                      "testEvent2");
+        events.add(event2);
+
+        // second invoice should be for one half (14/28 days) the difference between the rate plans
+        // this is a temporary state, since it actually contains an adjusting item that properly belong to invoice 1
+        Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceItemList, targetDate, Currency.USD);
+        assertEquals(invoice2.getBalance(), FIVE);
+        invoiceItemList.addAll(invoice2.getInvoiceItems());
+
+        invoiceDao.create(invoice1);
+        invoiceDao.create(invoice2);
+
+        Invoice savedInvoice1 = invoiceDao.getById(invoice1.getId());
+        assertEquals(savedInvoice1.getTotalAmount(), ZERO);
+
+        Invoice savedInvoice2 = invoiceDao.getById(invoice2.getId());
+        assertEquals(savedInvoice2.getTotalAmount(), FIFTEEN);
+    }
+
+    @Test
+    public void testInvoiceForFreeTrial() {
+        DefaultPrice price = new DefaultPrice(BigDecimal.ZERO, Currency.USD);
+        MockInternationalPrice recurringPrice = new MockInternationalPrice(price);
+        MockPlanPhase phase = new MockPlanPhase(recurringPrice, null);
+        MockPlan plan = new MockPlan(phase);
+
+        Subscription subscription = new MockSubscription();
+        DateTime effectiveDate = buildDateTime(2011, 1, 1);
+
+        BillingEvent event = new DefaultBillingEvent(subscription, effectiveDate, plan, phase, null,
+                                                     recurringPrice, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
+                                                     "testEvent");
+        BillingEventSet events = new BillingEventSet();
+        events.add(event);
+
+        DateTime targetDate = buildDateTime(2011, 1, 15);
+        InvoiceGenerator generator = new DefaultInvoiceGenerator();
+        Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD);
+        assertEquals(invoice.getNumberOfItems(), 1);
+        assertEquals(invoice.getTotalAmount().compareTo(ZERO), 0);
+    }
+
+    @Test
+    public void testInvoiceForEmptyEventSet() {
+        InvoiceGenerator generator = new DefaultInvoiceGenerator();
+        BillingEventSet events = new BillingEventSet();
+        Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new DateTime(), Currency.USD);
+        assertNull(invoice);
+    }
+
+    private class MockSubscription implements Subscription {
+        private UUID subscriptionId = UUID.randomUUID();
+
+        @Override
+        public void cancel(DateTime requestedDate, boolean eot) throws EntitlementUserApiException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void uncancel() throws EntitlementUserApiException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void changePlan(String productName, BillingPeriod term, String planSet, DateTime requestedDate) throws EntitlementUserApiException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void pause() throws EntitlementUserApiException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void resume() throws EntitlementUserApiException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public UUID getId() {
+            return subscriptionId;
+        }
+
+        @Override
+        public UUID getBundleId() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public SubscriptionState getState() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public DateTime getStartDate() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public DateTime getEndDate() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Plan getCurrentPlan() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String getCurrentPriceList() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public PlanPhase getCurrentPhase() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public DateTime getChargedThroughDate() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public DateTime getPaidThroughDate() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<SubscriptionTransition> getActiveTransitions() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<SubscriptionTransition> getAllTransitions() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public SubscriptionTransition getPendingTransition() {
+            throw new UnsupportedOperationException();
+        }
+    }
 }
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 55b4ce2..cf6c112 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
@@ -18,16 +18,13 @@ package com.ning.billing.invoice.dao;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.UUID;
 
 import com.ning.billing.invoice.api.InvoicePayment;
-import com.ning.billing.util.eventbus.Bus;
+import com.ning.billing.util.bus.Bus;
 import org.joda.time.DateTime;
 
 import com.google.inject.Inject;
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 21a66e3..d2fcdee 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
@@ -20,12 +20,21 @@ import java.io.IOException;
 import java.sql.SQLException;
 import java.util.UUID;
 import java.util.concurrent.Callable;
+
+import com.ning.billing.catalog.DefaultCatalogService;
+import com.ning.billing.catalog.api.CatalogService;
+import com.ning.billing.config.CatalogConfig;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
+import com.ning.billing.entitlement.engine.dao.EntitlementSqlDao;
+import com.ning.billing.util.bus.InMemoryBus;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.Transaction;
 import org.skife.jdbi.v2.TransactionStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
@@ -39,8 +48,7 @@ import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.lifecycle.KillbillService.ServiceException;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.MemoryEventBus;
+import com.ning.billing.util.bus.Bus;
 import com.ning.billing.util.notificationq.DefaultNotificationQueueService;
 import com.ning.billing.util.notificationq.DummySqlTest;
 import com.ning.billing.util.notificationq.NotificationQueueService;
@@ -50,7 +58,7 @@ import static com.jayway.awaitility.Awaitility.await;
 import static java.util.concurrent.TimeUnit.MINUTES;
 
 public class TestNextBillingDateNotifier {
-
+    private static Logger log = LoggerFactory.getLogger(TestNextBillingDateNotifier.class);
 	private Clock clock;
 	private DefaultNextBillingDateNotifier notifier;
 	private DummySqlTest dao;
@@ -63,15 +71,18 @@ public class TestNextBillingDateNotifier {
         final Injector g = Guice.createInjector(Stage.PRODUCTION,  new AbstractModule() {
 			protected void configure() {
 				 bind(Clock.class).to(ClockMock.class).asEagerSingleton();
-				 bind(Bus.class).to(MemoryEventBus.class).asEagerSingleton();
+				 bind(Bus.class).to(InMemoryBus.class).asEagerSingleton();
 				 bind(NotificationQueueService.class).to(DefaultNotificationQueueService.class).asEagerSingleton();
-				 final InvoiceConfig config = new ConfigurationObjectFactory(System.getProperties()).build(InvoiceConfig.class);
-				 bind(InvoiceConfig.class).toInstance(config);
-				 final MysqlTestingHelper helper = new MysqlTestingHelper();
+				 final InvoiceConfig invoiceConfig = new ConfigurationObjectFactory(System.getProperties()).build(InvoiceConfig.class);
+				 bind(InvoiceConfig.class).toInstance(invoiceConfig);
+				 final CatalogConfig catalogConfig = new ConfigurationObjectFactory(System.getProperties()).build(CatalogConfig.class);
+                 bind(CatalogConfig.class).toInstance(catalogConfig);
+                 bind(CatalogService.class).to(DefaultCatalogService.class).asEagerSingleton();
+                 final MysqlTestingHelper helper = new MysqlTestingHelper();
 				 bind(MysqlTestingHelper.class).toInstance(helper);
 				 IDBI dbi = helper.getDBI();
 				 bind(IDBI.class).toInstance(dbi);
-
+                 bind(EntitlementDao.class).to(EntitlementSqlDao.class).asEagerSingleton();
 			}
         });
 
@@ -80,16 +91,18 @@ public class TestNextBillingDateNotifier {
         dao = dbi.onDemand(DummySqlTest.class);
         eventBus = g.getInstance(Bus.class);
         helper = g.getInstance(MysqlTestingHelper.class);
-        notifier = new DefaultNextBillingDateNotifier(g.getInstance(NotificationQueueService.class), eventBus, g.getInstance(InvoiceConfig.class));
+        notifier = new DefaultNextBillingDateNotifier(g.getInstance(NotificationQueueService.class), eventBus, g.getInstance(InvoiceConfig.class), g.getInstance(EntitlementDao.class));
         startMysql();
 	}
 
 	private void startMysql() throws IOException, ClassNotFoundException, SQLException {
 		final String ddl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
 		final String testDdl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
+		final String entitlementDdl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/entitlement/ddl.sql"));
 		helper.startMysql();
 		helper.initDb(ddl);
 		helper.initDb(testDdl);
+        helper.initDb(entitlementDdl);
 	}
 
 	public static class NextBillingEventListener {
@@ -112,7 +125,7 @@ public class TestNextBillingDateNotifier {
 		}
 	}
 
-	@Test(enabled=true, groups="slow")
+	@Test(enabled=false, groups="slow")
 	public void test() throws Exception {
 		final UUID subscriptionId = new UUID(0L,1000L);
 		final DateTime now = new DateTime();
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
index 0952f28..11c3b1d 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
@@ -42,6 +42,7 @@ import java.util.UUID;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
 
 @Test(groups = {"fast", "invoicing", "invoiceGenerator"})
 public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
@@ -53,9 +54,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
         UUID accountId = UUID.randomUUID();
         Invoice invoice = generator.generateInvoice(accountId, new BillingEventSet(), new InvoiceItemList(), new DateTime(), Currency.USD);
 
-        assertNotNull(invoice);
-        assertEquals(invoice.getNumberOfItems(), 0);
-        assertEquals(invoice.getTotalAmount(), ZERO);
+        assertNull(invoice);
     }
 
     @Test
@@ -66,9 +65,7 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
         UUID accountId = UUID.randomUUID();
         Invoice invoice = generator.generateInvoice(accountId, events, existingInvoiceItems, new DateTime(), Currency.USD);
 
-        assertNotNull(invoice);
-        assertEquals(invoice.getNumberOfItems(), 0);
-        assertEquals(invoice.getTotalAmount(), ZERO);
+        assertNull(invoice);
     }
 
     @Test
@@ -457,11 +454,11 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
         Currency currency = Currency.USD;
         UUID accountId = UUID.randomUUID();
         Invoice invoice = generator.generateInvoice(accountId, events, existingInvoiceItems, targetDate, currency);
-        existingInvoiceItems.addAll(invoice.getInvoiceItems());
         assertNotNull(invoice);
         assertEquals(invoice.getNumberOfItems(), expectedNumberOfItems);
+
+        existingInvoiceItems.addAll(invoice.getInvoiceItems());
         assertEquals(invoice.getTotalAmount(), expectedAmount);
     }
-
     // TODO: Jeff C -- how do we ensure that an annual add-on is properly aligned *at the end* with the base plan?
-}
\ No newline at end of file
+}                      
\ No newline at end of file

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

diff --git a/payment/pom.xml b/payment/pom.xml
index 5baa4d4..17acd85 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.3-SNAPSHOT</version>
+        <version>0.1.4-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-payment</artifactId>
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
index 1fe63c3..69e0dfe 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
@@ -67,7 +67,12 @@ public class DefaultPaymentApi implements PaymentApi {
 
         if (accountKey != null) {
             final Account account = accountUserApi.getAccountByKey(accountKey);
-            return getPaymentProviderPlugin(account);
+            if (account != null) {
+                return getPaymentProviderPlugin(account);
+            }
+            else {
+                throw new IllegalArgumentException("Did not find account with accountKey " + accountKey);
+            }
         }
 
         return pluginRegistry.getPlugin(paymentProviderName);
@@ -173,15 +178,15 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
-    public Either<PaymentError, PaymentProviderAccount> createPaymentProviderAccount(PaymentProviderAccount account) {
+    public Either<PaymentError, String> createPaymentProviderAccount(Account account) {
         final PaymentProviderPlugin plugin = getPaymentProviderPlugin((Account)null);
         return plugin.createPaymentProviderAccount(account);
     }
 
     @Override
-    public Either<PaymentError, PaymentProviderAccount> updatePaymentProviderAccount(PaymentProviderAccount account) {
-        //TODO
-        throw new UnsupportedOperationException();
+    public Either<PaymentError, PaymentProviderAccount> updatePaymentProviderAccount(Account account) {
+        final PaymentProviderPlugin plugin = getPaymentProviderPlugin(account);
+        return plugin.updatePaymentProviderAccount(account);
     }
 
     @Override
diff --git a/payment/src/main/java/com/ning/billing/payment/PaymentInfoRequest.java b/payment/src/main/java/com/ning/billing/payment/PaymentInfoRequest.java
index 8ab345f..5a999e2 100644
--- a/payment/src/main/java/com/ning/billing/payment/PaymentInfoRequest.java
+++ b/payment/src/main/java/com/ning/billing/payment/PaymentInfoRequest.java
@@ -18,7 +18,7 @@ package com.ning.billing.payment;
 
 import java.util.UUID;
 
-import com.ning.billing.util.eventbus.BusEvent;
+import com.ning.billing.util.bus.BusEvent;
 
 public class PaymentInfoRequest implements BusEvent {
     private final UUID accountId;
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/PaymentProviderPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/PaymentProviderPlugin.java
index 4f19eb7..460951d 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/PaymentProviderPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/PaymentProviderPlugin.java
@@ -29,8 +29,9 @@ import com.ning.billing.payment.api.PaypalPaymentMethodInfo;
 
 public interface PaymentProviderPlugin {
     Either<PaymentError, PaymentInfo> processInvoice(Account account, Invoice invoice);
-    Either<PaymentError, PaymentProviderAccount> createPaymentProviderAccount(PaymentProviderAccount account);
+    Either<PaymentError, String> createPaymentProviderAccount(Account account);
     Either<PaymentError, String> addPaypalPaymentMethod(String accountId, PaypalPaymentMethodInfo paypalPaymentMethod);
+    Either<PaymentError, PaymentProviderAccount> updatePaymentProviderAccount(Account account);
 
     Either<PaymentError, PaymentInfo> getPaymentInfo(String paymentId);
     Either<PaymentError, PaymentMethodInfo> getPaymentMethodInfo(String paymentMethodId);
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java b/payment/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java
index f7778d8..fc9c149 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java
@@ -38,6 +38,12 @@ public class PaymentProviderPluginRegistry {
     }
 
     public PaymentProviderPlugin getPlugin(String name) {
-        return pluginsByName.get(StringUtils.defaultIfEmpty(name, defaultPlugin).toLowerCase());
+        PaymentProviderPlugin plugin = pluginsByName.get(StringUtils.defaultIfEmpty(name, defaultPlugin).toLowerCase());
+
+        if (plugin == null) {
+            throw new IllegalArgumentException("No payment provider plugin is configured for " + name);
+        }
+
+        return plugin;
     }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java b/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
index 304e6a1..9700450 100644
--- a/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
@@ -33,8 +33,8 @@ import com.ning.billing.payment.api.PaymentError;
 import com.ning.billing.payment.api.PaymentInfo;
 import com.ning.billing.payment.provider.PaymentProviderPlugin;
 import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.Bus.EventBusException;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
 
 public class RequestProcessor {
     public static final String PAYMENT_PROVIDER_KEY = "paymentProvider";
diff --git a/payment/src/main/java/com/ning/billing/payment/util/EventBusFuture.java b/payment/src/main/java/com/ning/billing/payment/util/EventBusFuture.java
index ae2612a..3cbe802 100644
--- a/payment/src/main/java/com/ning/billing/payment/util/EventBusFuture.java
+++ b/payment/src/main/java/com/ning/billing/payment/util/EventBusFuture.java
@@ -20,8 +20,8 @@ import javax.annotation.Nullable;
 
 import com.google.common.eventbus.Subscribe;
 import com.google.common.util.concurrent.AbstractFuture;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.Bus.EventBusException;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
 
 public class EventBusFuture<T, V extends EventBusResponse<T>> extends AbstractFuture<V> {
     public static <V, W extends EventBusRequest<V>, X extends EventBusResponse<V>> EventBusFuture<V, X> post(final Bus eventBus, final W event) throws EventBusException {
diff --git a/payment/src/main/java/com/ning/billing/payment/util/EventBusRequest.java b/payment/src/main/java/com/ning/billing/payment/util/EventBusRequest.java
index 1ee0cbd..a895afc 100644
--- a/payment/src/main/java/com/ning/billing/payment/util/EventBusRequest.java
+++ b/payment/src/main/java/com/ning/billing/payment/util/EventBusRequest.java
@@ -16,7 +16,7 @@
 
 package com.ning.billing.payment.util;
 
-import com.ning.billing.util.eventbus.BusEvent;
+import com.ning.billing.util.bus.BusEvent;
 
 public interface EventBusRequest<T> extends BusEvent {
     T getId();
diff --git a/payment/src/main/java/com/ning/billing/payment/util/EventBusResponse.java b/payment/src/main/java/com/ning/billing/payment/util/EventBusResponse.java
index 4b3af2b..ff5b62c 100644
--- a/payment/src/main/java/com/ning/billing/payment/util/EventBusResponse.java
+++ b/payment/src/main/java/com/ning/billing/payment/util/EventBusResponse.java
@@ -16,7 +16,7 @@
 
 package com.ning.billing.payment.util;
 
-import com.ning.billing.util.eventbus.BusEvent;
+import com.ning.billing.util.bus.BusEvent;
 
 public interface EventBusResponse<T> extends BusEvent {
     T getRequestId();
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
index d2d8033..5e3f076 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
@@ -37,8 +37,8 @@ import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.model.DefaultInvoiceItem;
 import com.ning.billing.payment.TestHelper;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.Bus.EventBusException;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
 
 public abstract class TestPaymentApi {
     @Inject
diff --git a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
index c26f28a..121db01 100644
--- a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
+++ b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
@@ -21,6 +21,7 @@ import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.commons.lang.math.RandomUtils;
 import org.joda.time.DateTime;
 
 import com.ning.billing.account.api.Account;
@@ -66,15 +67,15 @@ public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
     }
 
     @Override
-    public Either<PaymentError, PaymentProviderAccount> createPaymentProviderAccount(PaymentProviderAccount account) {
+    public Either<PaymentError, String> createPaymentProviderAccount(Account account) {
         if (account != null) {
-            PaymentProviderAccount paymentProviderAccount = accounts.put(account.getAccountName(),
-                                                                         new PaymentProviderAccount.Builder().setAccountName(account.getAccountName())
-                                                                                                             .setAccountNumber(account.getAccountName())
-                                                                                                             .setId(account.getId())
+            PaymentProviderAccount paymentProviderAccount = accounts.put(account.getExternalKey(),
+                                                                         new PaymentProviderAccount.Builder().setAccountNumber(String.valueOf(RandomUtils.nextInt(10)))
+                                                                                                             .setDefaultPaymentMethod(String.valueOf(RandomUtils.nextInt(10)))
+                                                                                                             .setId(String.valueOf(RandomUtils.nextInt(10)))
                                                                                                              .build());
 
-            return Either.right(paymentProviderAccount);
+            return Either.right(paymentProviderAccount.getId());
         }
         else {
             return Either.left(new PaymentError("unknown", "Did not get account to create payment provider account"));
@@ -82,6 +83,12 @@ public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
     }
 
     @Override
+    public Either<PaymentError, PaymentProviderAccount> updatePaymentProviderAccount(Account account) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
     public Either<PaymentError, PaymentMethodInfo> getPaymentMethodInfo(String paymentMethodId) {
         // TODO
         return Either.left(new PaymentError("unknown", "Not implemented"));
@@ -122,4 +129,5 @@ public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
         // TODO
         return Either.left(new PaymentError("unknown", "Not implemented"));
     }
+
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithEmbeddedDb.java b/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithEmbeddedDb.java
index e8c723b..9d9372c 100644
--- a/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithEmbeddedDb.java
+++ b/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithEmbeddedDb.java
@@ -16,12 +16,12 @@
 
 package com.ning.billing.payment.setup;
 
-import com.ning.billing.util.eventbus.Bus;
+import com.ning.billing.util.bus.Bus;
 import org.apache.commons.collections.MapUtils;
 
 import com.google.common.collect.ImmutableMap;
 import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
-import com.ning.billing.util.eventbus.MemoryEventBus;
+import com.ning.billing.util.bus.InMemoryBus;
 
 public class PaymentTestModuleWithEmbeddedDb extends PaymentModule {
     public PaymentTestModuleWithEmbeddedDb() {
@@ -36,6 +36,6 @@ public class PaymentTestModuleWithEmbeddedDb extends PaymentModule {
     @Override
     protected void configure() {
         super.configure();
-        bind(Bus.class).to(MemoryEventBus.class).asEagerSingleton();
+        bind(Bus.class).to(InMemoryBus.class).asEagerSingleton();
     }
 }
diff --git a/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithMocks.java b/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithMocks.java
index 75c045d..0d73691 100644
--- a/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithMocks.java
+++ b/payment/src/test/java/com/ning/billing/payment/setup/PaymentTestModuleWithMocks.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.payment.setup;
 
+import com.ning.billing.util.bus.InMemoryBus;
 import org.apache.commons.collections.MapUtils;
 
 import com.google.common.collect.ImmutableMap;
@@ -26,8 +27,7 @@ import com.ning.billing.invoice.dao.MockInvoiceDao;
 import com.ning.billing.payment.dao.MockPaymentDao;
 import com.ning.billing.payment.dao.PaymentDao;
 import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.MemoryEventBus;
+import com.ning.billing.util.bus.Bus;
 
 public class PaymentTestModuleWithMocks extends PaymentModule {
     public PaymentTestModuleWithMocks() {
@@ -47,7 +47,7 @@ public class PaymentTestModuleWithMocks extends PaymentModule {
     @Override
     protected void configure() {
         super.configure();
-        bind(Bus.class).to(MemoryEventBus.class).asEagerSingleton();
+        bind(Bus.class).to(InMemoryBus.class).asEagerSingleton();
         bind(MockAccountDao.class).asEagerSingleton();
         bind(AccountDao.class).to(MockAccountDao.class);
         bind(MockInvoiceDao.class).asEagerSingleton();
diff --git a/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java b/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java
index 13cf865..1bd7695 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java
@@ -34,8 +34,8 @@ import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.invoice.glue.InvoiceModuleWithMocks;
 import com.ning.billing.payment.setup.PaymentTestModuleWithMocks;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.Bus.EventBusException;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
 
 @Test
 @Guice(modules = { PaymentTestModuleWithMocks.class, AccountModuleWithMocks.class, InvoiceModuleWithMocks.class })
diff --git a/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java b/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java
index 2c9c2f1..0533bdc 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestPaymentInvoiceIntegration.java
@@ -51,8 +51,8 @@ import com.ning.billing.payment.api.PaymentAttempt;
 import com.ning.billing.payment.api.PaymentError;
 import com.ning.billing.payment.api.PaymentInfo;
 import com.ning.billing.payment.setup.PaymentTestModuleWithEmbeddedDb;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.Bus.EventBusException;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
 
 public class TestPaymentInvoiceIntegration {
     // create payment for received invoice and save it -- positive and negative
diff --git a/payment/src/test/java/com/ning/billing/payment/TestPaymentProvider.java b/payment/src/test/java/com/ning/billing/payment/TestPaymentProvider.java
index bd175f4..d682e16 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestPaymentProvider.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestPaymentProvider.java
@@ -37,8 +37,8 @@ import com.ning.billing.invoice.glue.InvoiceModuleWithMocks;
 import com.ning.billing.payment.api.PaymentError;
 import com.ning.billing.payment.api.PaymentInfo;
 import com.ning.billing.payment.setup.PaymentTestModuleWithMocks;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.Bus.EventBusException;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
 
 @Guice(modules = { PaymentTestModuleWithMocks.class, AccountModuleWithMocks.class, InvoiceModuleWithMocks.class })
 public class TestPaymentProvider {
diff --git a/payment/src/test/java/com/ning/billing/payment/util/TestSyncWaitOnEventBus.java b/payment/src/test/java/com/ning/billing/payment/util/TestSyncWaitOnEventBus.java
index 63f353d..0e76771 100644
--- a/payment/src/test/java/com/ning/billing/payment/util/TestSyncWaitOnEventBus.java
+++ b/payment/src/test/java/com/ning/billing/payment/util/TestSyncWaitOnEventBus.java
@@ -27,8 +27,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.google.common.eventbus.Subscribe;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.MemoryEventBus;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.InMemoryBus;
 
 @Test
 public class TestSyncWaitOnEventBus {
@@ -74,7 +74,7 @@ public class TestSyncWaitOnEventBus {
 
     @BeforeMethod(alwaysRun = true)
     public void setUp() throws Exception {
-        eventBus = new MemoryEventBus();
+        eventBus = new InMemoryBus();
         eventBus.start();
         eventBus.register(new Object() {
             @Subscribe

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index eb22569..7aa42a0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
     <groupId>com.ning.billing</groupId>
     <artifactId>killbill</artifactId>
     <packaging>pom</packaging>
-    <version>0.1.3-SNAPSHOT</version>
+    <version>0.1.4-SNAPSHOT</version>
     <name>killbill</name>
     <description>Library for managing recurring subscriptions and the associated billing</description>
     <url>http://github.com/ning/killbill</url>

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

diff --git a/util/pom.xml b/util/pom.xml
index f582868..8013122 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.1.3-SNAPSHOT</version>
+        <version>0.1.4-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-util</artifactId>
diff --git a/util/src/main/java/com/ning/billing/util/glue/BusModule.java b/util/src/main/java/com/ning/billing/util/glue/BusModule.java
index 3d6203f..d6f7a37 100644
--- a/util/src/main/java/com/ning/billing/util/glue/BusModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/BusModule.java
@@ -17,17 +17,17 @@
 package com.ning.billing.util.glue;
 
 import com.google.inject.AbstractModule;
-import com.ning.billing.util.eventbus.DefaultEventBusService;
-import com.ning.billing.util.eventbus.Bus;
-import com.ning.billing.util.eventbus.BusService;
-import com.ning.billing.util.eventbus.MemoryEventBus;
+import com.ning.billing.util.bus.DefaultBusService;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.BusService;
+import com.ning.billing.util.bus.InMemoryBus;
 
 public class BusModule extends AbstractModule {
 
     @Override
     protected void configure() {
-        bind(BusService.class).to(DefaultEventBusService.class);
-        bind(Bus.class).to(MemoryEventBus.class).asEagerSingleton();
+        bind(BusService.class).to(DefaultBusService.class);
+        bind(Bus.class).to(InMemoryBus.class).asEagerSingleton();
 
     }