killbill-aplcache

Details

diff --git a/account/src/main/java/com/ning/billing/account/glue/DefaultAccountModule.java b/account/src/main/java/com/ning/billing/account/glue/DefaultAccountModule.java
index eb31347..a02f146 100644
--- a/account/src/main/java/com/ning/billing/account/glue/DefaultAccountModule.java
+++ b/account/src/main/java/com/ning/billing/account/glue/DefaultAccountModule.java
@@ -48,7 +48,9 @@ public class DefaultAccountModule extends AbstractModule implements AccountModul
 
     @Override
     public void installAccountUserApi() {
+        // STEPH_ENT should eliminate the RealImplementation if not nedded
         bind(AccountUserApi.class).annotatedWith(RealImplementation.class).to(DefaultAccountUserApi.class).asEagerSingleton();
+        bind(AccountUserApi.class).to(DefaultAccountUserApi.class).asEagerSingleton();
     }
 
     @Override
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index d9ea99e..a0dcfb4 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -109,7 +109,6 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // Set next invoice to fail and create subscription
         paymentPlugin.makeAllInvoicesFailWithError(true);
         final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
-
         invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
         invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 5, 1), callContext);
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
index 7ecce7c..2b11c68 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestBundleTransfer.java
@@ -16,7 +16,13 @@
 
 package com.ning.billing.beatrix.integration;
 
-import com.google.common.collect.ImmutableList;
+import java.math.BigDecimal;
+import java.util.List;
+
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.testng.annotations.Test;
+
 import com.ning.billing.account.api.Account;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
@@ -28,14 +34,8 @@ import com.ning.billing.entitlement.api.DefaultEntitlement;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
-import com.ning.billing.subscription.api.user.SubscriptionBundle;
-import com.ning.billing.subscription.api.user.SubscriptionData;
-import org.joda.time.DateTime;
-import org.joda.time.LocalDate;
-import org.testng.annotations.Test;
 
-import java.math.BigDecimal;
-import java.util.List;
+import com.google.common.collect.ImmutableList;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -63,8 +63,7 @@ public class TestBundleTransfer extends TestIntegrationBase {
         //
         final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
         assertNotNull(bpEntitlement);
-        assertTrue(busHandler.isCompleted(DELAY));
-        assertListenerStatus();
+
         assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).size(), 1);
         assertEquals(bpEntitlement.getSubscription().getCurrentPlan().getBillingPeriod(), BillingPeriod.ANNUAL);
 
@@ -82,7 +81,7 @@ public class TestBundleTransfer extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.TRANSFER);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-        transferApi.transferBundle(account.getId(), newAccount.getId(), "mycutebundle", clock.getUTCNow(), false, false, callContext);
+        transferApi.transferBundle(account.getId(), newAccount.getId(), "externalKey", clock.getUTCNow(), false, false, callContext);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
@@ -135,7 +134,7 @@ public class TestBundleTransfer extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.TRANSFER);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-        transferApi.transferBundle(account.getId(), newAccount.getId(), "mycutebundle", clock.getUTCNow(), false, false, callContext);
+        transferApi.transferBundle(account.getId(), newAccount.getId(), "externalKey", clock.getUTCNow(), false, false, callContext);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
@@ -198,7 +197,7 @@ public class TestBundleTransfer extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE_ADJUSTMENT);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-        transferApi.transferBundle(account.getId(), newAccount.getId(), "mycutebundle", clock.getUTCNow(), false, true, callContext);
+        transferApi.transferBundle(account.getId(), newAccount.getId(), "externalKey", clock.getUTCNow(), false, true, callContext);
         assertTrue(busHandler.isCompleted(DELAY));
         assertListenerStatus();
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
index d8d9e46..729ffd9 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
@@ -63,12 +63,12 @@ public class TestIntegration extends TestIntegrationBase {
         //
         final DefaultEntitlement bpSubscription = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE);
         // Check bundle after BP got created otherwise we get an error from auditApi.
-        subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), callContext);
+        subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
         invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
         //
         // ADD ADD_ON ON THE SAME DAY
         //
-        addAOEntitlementAndCheckForCompletion(account.getId(), "Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE, NextEvent.PAYMENT);
+        addAOEntitlementAndCheckForCompletion(bpSubscription.getId(), "Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE, NextEvent.PAYMENT);
         Invoice invoice = invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 4, 1), new LocalDate(2012, 5, 1), InvoiceItemType.RECURRING, new BigDecimal("399.95")));
         paymentChecker.checkPayment(account.getId(), 1, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 4, 1), new BigDecimal("399.95"), PaymentStatus.SUCCESS, invoice.getId(), Currency.USD));
 
@@ -101,7 +101,7 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
         //
-        final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE);
+        DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE);
         SubscriptionData subscription = subscriptionDataFromSubscription(baseEntitlement.getSubscription());
         invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedInvoiceItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
         // No end date for the trial item (fixed price of zero), and CTD should be today (i.e. when the trial started)
@@ -128,7 +128,8 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // CHANGE PLAN EOT AND EXPECT NOTHING
         //
-        changeEntitlementAndCheckForCompletion(baseEntitlement, "Pistol", BillingPeriod.MONTHLY, null);
+        baseEntitlement = changeEntitlementAndCheckForCompletion(baseEntitlement, "Pistol", BillingPeriod.MONTHLY, null);
+        subscription = subscriptionDataFromSubscription(baseEntitlement.getSubscription());
 
         //
         // MOVE TIME AFTER CTD AND EXPECT BOTH EVENTS : NextEvent.CHANGE NextEvent.INVOICE
@@ -157,7 +158,7 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // FINALLY CANCEL SUBSCRIPTION EOT
         //
-        cancelEntitlementAndCheckForCompletion(baseEntitlement, clock.getUTCNow());
+        baseEntitlement = cancelEntitlementAndCheckForCompletion(baseEntitlement, clock.getUTCNow());
 
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         addDaysAndCheckForCompletion(31, NextEvent.CANCEL);
@@ -182,7 +183,7 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
         //
-        final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE);
+        DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE);
         SubscriptionData subscription = subscriptionDataFromSubscription(baseEntitlement.getSubscription());
         invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedInvoiceItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
         // No end date for the trial item (fixed price of zero), and CTD should be today (i.e. when the trial started)
@@ -209,7 +210,8 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // CHANGE PLAN EOT AND EXPECT NOTHING
         //
-        changeEntitlementAndCheckForCompletion(baseEntitlement, "Pistol", BillingPeriod.MONTHLY, null);
+        baseEntitlement = changeEntitlementAndCheckForCompletion(baseEntitlement, "Pistol", BillingPeriod.MONTHLY, null);
+        subscription = subscriptionDataFromSubscription(baseEntitlement.getSubscription());
 
         //
         // MOVE TIME AFTER CTD AND EXPECT BOTH EVENTS : NextEvent.CHANGE NextEvent.INVOICE
@@ -263,7 +265,7 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
         //
-        final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE);
+        DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE);
         SubscriptionData subscription = subscriptionDataFromSubscription(baseEntitlement.getSubscription());
 
 
@@ -274,7 +276,7 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // CHANGE PLAN IMMEDIATELY AND EXPECT BOTH EVENTS: NextEvent.CHANGE NextEvent.INVOICE
         //
-        changeEntitlementAndCheckForCompletion(baseEntitlement, "Assault-Rifle", BillingPeriod.MONTHLY, null, NextEvent.CHANGE, NextEvent.INVOICE);
+        baseEntitlement = changeEntitlementAndCheckForCompletion(baseEntitlement, "Assault-Rifle", BillingPeriod.MONTHLY, null, NextEvent.CHANGE, NextEvent.INVOICE);
         invoiceChecker.checkInvoice(account.getId(), invoiceItemCount++, callContext, new ExpectedInvoiceItemCheck(initialCreationDate.toLocalDate(), null, InvoiceItemType.FIXED, new BigDecimal("0")));
         invoiceChecker.checkChargedThroughDate(subscription.getId(), clock.getUTCToday(), callContext);
 
@@ -298,7 +300,8 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // CHANGE PLAN EOT AND EXPECT NOTHING
         //
-        changeEntitlementAndCheckForCompletion(baseEntitlement, "Pistol", BillingPeriod.MONTHLY, null);
+        baseEntitlement = changeEntitlementAndCheckForCompletion(baseEntitlement, "Pistol", BillingPeriod.MONTHLY, null);
+        subscription = subscriptionDataFromSubscription(baseEntitlement.getSubscription());
 
         //
         // MOVE TIME AFTER CTD AND EXPECT BOTH EVENTS : NextEvent.CHANGE NextEvent.INVOICE
@@ -327,7 +330,7 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // FINALLY CANCEL SUBSCRIPTION EOT
         //
-        cancelEntitlementAndCheckForCompletion(baseEntitlement, clock.getUTCNow());
+        baseEntitlement = cancelEntitlementAndCheckForCompletion(baseEntitlement, clock.getUTCNow());
 
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         addDaysAndCheckForCompletion(31, NextEvent.CANCEL);
@@ -402,10 +405,6 @@ public class TestIntegration extends TestIntegrationBase {
         log.info("Moving clock from" + clock.getUTCNow() + " to " + clock.getUTCNow().plusDays(3));
         clock.addDays(3);
 
-        busHandler.pushExpectedEvent(NextEvent.CREATE);
-        busHandler.pushExpectedEvent(NextEvent.INVOICE);
-        busHandler.pushExpectedEvent(NextEvent.PAYMENT);
-
         final DefaultEntitlement aoEntitlement1 = addAOEntitlementAndCheckForCompletion(baseEntitlement.getId(), "Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY,
                                                                                         NextEvent.CREATE, NextEvent.INVOICE, NextEvent.PAYMENT);
 
@@ -471,18 +470,13 @@ public class TestIntegration extends TestIntegrationBase {
         //
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
         //
-        busHandler.pushExpectedEvent(NextEvent.CREATE);
-        busHandler.pushExpectedEvent(NextEvent.INVOICE);
-
         final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
-
         assertNotNull(baseEntitlement);
-        assertTrue(busHandler.isCompleted(DELAY));
 
         //
         // VERIFY CTD HAS BEEN SET
         //
-        final SubscriptionData subscription = (SubscriptionData) baseEntitlement.getSubscription();
+        SubscriptionData subscription = (SubscriptionData) baseEntitlement.getSubscription();
         final DateTime startDate = subscription.getCurrentPhaseStart();
         final BigDecimal rate = subscription.getCurrentPhase().getFixedPrice().getPrice(Currency.USD);
         final int invoiceItemCount = 1;
@@ -497,8 +491,9 @@ public class TestIntegration extends TestIntegrationBase {
         clock.addDeltaFromReality(AT_LEAST_ONE_MONTH_MS);
         assertTrue(busHandler.isCompleted(DELAY));
 
-        final DefaultEntitlement entitlement = (DefaultEntitlement) entitlementApi.getEntitlementFromId(baseEntitlement.getId(), callContext);
+        DefaultEntitlement entitlement = (DefaultEntitlement) entitlementApi.getEntitlementFromId(baseEntitlement.getId(), callContext);
         entitlement.cancelEntitlementWithDate(clock.getUTCNow().toLocalDate(), callContext);
+        subscription = (SubscriptionData) baseEntitlement.getSubscription();
 
         // MOVE AFTER CANCEL DATE AND EXPECT EVENT : NextEvent.CANCEL
         busHandler.pushExpectedEvent(NextEvent.CANCEL);
@@ -511,6 +506,8 @@ public class TestIntegration extends TestIntegrationBase {
         term = BillingPeriod.MONTHLY;
         planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
+        // STEPH_ENT we should use new API pause/resume billing
+        /*
         busHandler.pushExpectedEvent(NextEvent.RE_CREATE);
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         busHandler.pushExpectedEvent(NextEvent.PAYMENT);
@@ -518,6 +515,7 @@ public class TestIntegration extends TestIntegrationBase {
         assertTrue(busHandler.isCompleted(DELAY));
 
         assertListenerStatus();
+        */
     }
 
     @Test(groups = "slow")
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
index 9b05a8b..2d9e56f 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
@@ -503,7 +503,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
                                                                             final BillingPeriod billingPeriod,
                                                                             final NextEvent... events) {
         if (productCategory != ProductCategory.ADD_ON) {
-            throw new RuntimeException("Unxepected Call for creating a productCatrgory " + productCategory);
+            throw new RuntimeException("Unexpected Call for creating a productCategory " + productCategory);
         }
 
         return (DefaultEntitlement) doCallAndCheckForCompletion(new Function<Void, Entitlement>() {
@@ -515,7 +515,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
                     assertNotNull(entitlement);
                     return entitlement;
                 } catch (EntitlementApiException e) {
-                    fail();
+                    fail(e.getMessage());
                     return null;
                 }
             }
@@ -561,7 +561,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
                     refreshedEntitlement.cancelEntitlementWithDate(requestedDate.toLocalDate(), callContext);
                     return refreshedEntitlement;
                 } catch (EntitlementApiException e) {
-                    fail();
+                    fail(e.getMessage());
                     return null;
                 }
             }
@@ -609,6 +609,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
         assertTrue(busHandler.isCompleted(DELAY), "Were expecting events " + joiner.join(events));
         assertListenerStatus();
 
+
         log.info("            ************    DONE WITH BUS HANDLER CHECK    ********************");
         return result;
     }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java b/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java
index 21b6df3..5caed82 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/util/InvoiceChecker.java
@@ -28,14 +28,15 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 
+import com.ning.billing.entitlement.api.DefaultEntitlement;
+import com.ning.billing.entitlement.api.EntitlementApi;
+import com.ning.billing.entitlement.api.EntitlementApiException;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.api.InvoiceItemType;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.subscription.api.user.Subscription;
-import com.ning.billing.subscription.api.user.SubscriptionUserApi;
-import com.ning.billing.subscription.api.user.SubscriptionUserApiException;
 import com.ning.billing.util.callcontext.CallContext;
 
 import com.google.common.collect.ImmutableList;
@@ -51,13 +52,13 @@ public class InvoiceChecker {
     private static final Logger log = LoggerFactory.getLogger(InvoiceChecker.class);
 
     private final InvoiceUserApi invoiceUserApi;
-    private final SubscriptionUserApi subscriptionApi;
+    private final EntitlementApi entitlementApi;
     private final AuditChecker auditChecker;
 
     @Inject
-    public InvoiceChecker(final InvoiceUserApi invoiceUserApi, final SubscriptionUserApi subscriptionApi, final AuditChecker auditChecker) {
+    public InvoiceChecker(final InvoiceUserApi invoiceUserApi, final EntitlementApi entitlementApi, final AuditChecker auditChecker) {
         this.invoiceUserApi = invoiceUserApi;
-        this.subscriptionApi = subscriptionApi;
+        this.entitlementApi = entitlementApi;
         this.auditChecker = auditChecker;
     }
 
@@ -120,25 +121,26 @@ public class InvoiceChecker {
         auditChecker.checkInvoiceCreated(invoice, context);
     }
 
-    public void checkNullChargedThroughDate(final UUID subscriptionId, final CallContext context) {
-        checkChargedThroughDate(subscriptionId, null, context);
+    public void checkNullChargedThroughDate(final UUID entitlementId, final CallContext context) {
+        checkChargedThroughDate(entitlementId, null, context);
     }
 
-    public void checkChargedThroughDate(final UUID subscriptionId, final LocalDate expectedLocalCTD, final CallContext context) {
+    public void checkChargedThroughDate(final UUID entitlementId, final LocalDate expectedLocalCTD, final CallContext context) {
         try {
-            final Subscription subscription = subscriptionApi.getSubscriptionFromId(subscriptionId, context);
+            final DefaultEntitlement entitlement = (DefaultEntitlement) entitlementApi.getEntitlementFromId(entitlementId, context);
+            final Subscription subscription = entitlement.getSubscription();
             if (expectedLocalCTD == null) {
                 assertNull(subscription.getChargedThroughDate());
             } else {
                 final DateTime expectedCTD = expectedLocalCTD.toDateTime(new LocalTime(subscription.getStartDate().getMillis(), DateTimeZone.UTC), DateTimeZone.UTC);
-                final String msg = String.format("Checking CTD for subscription %s : expectedLocalCTD = %s => expectedCTD = %s, got %s",
-                                                 subscriptionId, expectedLocalCTD, expectedCTD, subscription.getChargedThroughDate());
+                final String msg = String.format("Checking CTD for entitlement %s : expectedLocalCTD = %s => expectedCTD = %s, got %s",
+                                                 entitlementId, expectedLocalCTD, expectedCTD, subscription.getChargedThroughDate());
                 log.info(msg);
                 assertNotNull(subscription.getChargedThroughDate());
                 assertTrue(subscription.getChargedThroughDate().compareTo(expectedCTD) == 0, msg);
             }
-        } catch (SubscriptionUserApiException e) {
-            fail("Failed to retrieve subscription for " + subscriptionId);
+        } catch (EntitlementApiException e) {
+            fail("Failed to retrieve entitlement for " + entitlementId);
         }
     }
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/util/SubscriptionChecker.java b/beatrix/src/test/java/com/ning/billing/beatrix/util/SubscriptionChecker.java
index 959d58e..e85c258 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/util/SubscriptionChecker.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/util/SubscriptionChecker.java
@@ -16,36 +16,39 @@
 
 package com.ning.billing.beatrix.util;
 
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+
 import com.ning.billing.subscription.api.user.Subscription;
 import com.ning.billing.subscription.api.user.SubscriptionBundle;
 import com.ning.billing.subscription.api.user.SubscriptionTransition;
 import com.ning.billing.subscription.api.user.SubscriptionTransitionData;
-import com.ning.billing.subscription.api.user.SubscriptionUserApi;
 import com.ning.billing.subscription.api.user.SubscriptionUserApiException;
-import com.ning.billing.util.callcontext.CallContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-
-import javax.inject.Inject;
-import java.util.List;
-import java.util.UUID;
+import com.ning.billing.util.callcontext.InternalCallContext;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.svcapi.subscription.SubscriptionInternalApi;
 
 public class SubscriptionChecker {
 
 
     private static final Logger log = LoggerFactory.getLogger(SubscriptionChecker.class);
 
-    private final SubscriptionUserApi subscriptionApi;
+    private final SubscriptionInternalApi subscriptionApi;
     private final AuditChecker auditChecker;
 
     @Inject
-    public SubscriptionChecker(final SubscriptionUserApi subscriptionApi, final AuditChecker auditChecker) {
+    public SubscriptionChecker(final SubscriptionInternalApi subscriptionApi, final AuditChecker auditChecker) {
         this.subscriptionApi = subscriptionApi;
         this.auditChecker = auditChecker;
     }
 
-    public SubscriptionBundle checkBundleNoAudits(final UUID bundleId, final UUID expectedAccountId, final String expectedKey, final CallContext context) throws SubscriptionUserApiException {
+    public SubscriptionBundle checkBundleNoAudits(final UUID bundleId, final UUID expectedAccountId, final String expectedKey, final InternalTenantContext context) throws SubscriptionUserApiException {
         final SubscriptionBundle bundle = subscriptionApi.getBundleFromId(bundleId, context);
         Assert.assertNotNull(bundle);
         Assert.assertEquals(bundle.getAccountId(), expectedAccountId);
@@ -53,22 +56,22 @@ public class SubscriptionChecker {
         return bundle;
     }
 
-    public SubscriptionBundle checkBundleAuditUpdated(final UUID bundleId, final CallContext context) throws SubscriptionUserApiException {
+    public SubscriptionBundle checkBundleAuditUpdated(final UUID bundleId, final InternalCallContext context) throws SubscriptionUserApiException {
         final SubscriptionBundle bundle = subscriptionApi.getBundleFromId(bundleId, context);
-        auditChecker.checkBundleUpdated(bundle.getId(), context);
+        auditChecker.checkBundleUpdated(bundle.getId(), context.toCallContext());
         return bundle;
     }
 
-    public Subscription checkSubscriptionCreated(final UUID subscriptionId, final CallContext context) throws SubscriptionUserApiException {
+    public Subscription checkSubscriptionCreated(final UUID subscriptionId, final InternalCallContext context) throws SubscriptionUserApiException {
         final Subscription subscription = subscriptionApi.getSubscriptionFromId(subscriptionId, context);
         Assert.assertNotNull(subscription);
-        auditChecker.checkSubscriptionCreated(subscription.getBundleId(), subscriptionId, context);
+        auditChecker.checkSubscriptionCreated(subscription.getBundleId(), subscriptionId, context.toCallContext());
 
         List<SubscriptionTransition> subscriptionEvents = getSubscriptionEvents(subscription);
         Assert.assertTrue(subscriptionEvents.size() >= 1);
-        auditChecker.checkSubscriptionEventCreated(subscription.getBundleId(), ((SubscriptionTransitionData) subscriptionEvents.get(0)).getId(), context);
+        auditChecker.checkSubscriptionEventCreated(subscription.getBundleId(), ((SubscriptionTransitionData) subscriptionEvents.get(0)).getId(), context.toCallContext());
 
-        auditChecker.checkBundleCreated(subscription.getBundleId(), context);
+        auditChecker.checkBundleCreated(subscription.getBundleId(), context.toCallContext());
         return subscription;
     }
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlement.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlement.java
index e08bc9b..035ebb0 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlement.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlement.java
@@ -25,27 +25,34 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.catalog.api.ActionPolicy;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.clock.Clock;
 import com.ning.billing.entitlement.block.BlockingChecker;
 import com.ning.billing.subscription.api.user.Subscription;
+import com.ning.billing.subscription.api.user.SubscriptionBundle;
 import com.ning.billing.subscription.api.user.SubscriptionUserApiException;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.svcapi.account.AccountInternalApi;
+import com.ning.billing.util.svcapi.subscription.SubscriptionInternalApi;
 import com.ning.billing.util.timezone.DateAndTimeZoneContext;
 
 public class DefaultEntitlement implements Entitlement {
 
     private final AccountInternalApi accountApi;
+    private final SubscriptionInternalApi subscriptionInternalApi;
     private final Subscription subscription;
     private final InternalCallContextFactory internalCallContextFactory;
     private final Clock clock;
     private final BlockingChecker checker;
+    private final UUID accountId;
 
-    public DefaultEntitlement(final AccountInternalApi accountApi, final Subscription subscription, final InternalCallContextFactory internalCallContextFactory, final Clock clock, final BlockingChecker checker) {
+    public DefaultEntitlement(final AccountInternalApi accountApi, final SubscriptionInternalApi subscriptionInternalApi, final Subscription subscription, final UUID accountId, final InternalCallContextFactory internalCallContextFactory, final Clock clock, final BlockingChecker checker) {
         this.accountApi = accountApi;
+        this.subscriptionInternalApi = subscriptionInternalApi;
         this.subscription = subscription;
+        this.accountId = accountId;
         this.internalCallContextFactory = internalCallContextFactory;
         this.clock = clock;
         this.checker = checker;
@@ -55,7 +62,7 @@ public class DefaultEntitlement implements Entitlement {
     @Override
     public boolean cancelEntitlementWithDate(final LocalDate localDate, final CallContext callContext) throws EntitlementApiException {
 
-        final InternalCallContext context = internalCallContextFactory.createInternalCallContext(callContext);
+        final InternalCallContext context = internalCallContextFactory.createInternalCallContext(accountId, callContext);
         final DateTime requestedDate = fromLocalDateAndReferenceTime(localDate, subscription.getStartDate(), clock, context);
         try {
             return subscription.cancel(requestedDate, callContext);
@@ -64,6 +71,7 @@ public class DefaultEntitlement implements Entitlement {
         }
     }
 
+
     @Override
     public boolean cancelEntitlementWithPolicy(final EntitlementActionPolicy entitlementActionPolicy, final CallContext callContext) throws EntitlementApiException {
         return false;
@@ -87,7 +95,7 @@ public class DefaultEntitlement implements Entitlement {
     @Override
     public boolean changePlan(final String productName, final BillingPeriod billingPeriod, final String priceList, final LocalDate localDate, final CallContext callContext) throws EntitlementApiException {
 
-        final InternalCallContext context = internalCallContextFactory.createInternalCallContext(callContext);
+        final InternalCallContext context = internalCallContextFactory.createInternalCallContext(accountId, callContext);
         final DateTime requestedDate = fromLocalDateAndReferenceTime(localDate, subscription.getStartDate(), clock, context);
         try {
             checker.checkBlockedChange(subscription, context);
@@ -100,8 +108,17 @@ public class DefaultEntitlement implements Entitlement {
     }
 
     @Override
-    public boolean changePlanOverrideBillingPolicy(final String s, final BillingPeriod billingPeriod, final String s2, final LocalDate localDate, final ActionPolicy actionPolicy, final CallContext callContext) throws EntitlementApiException {
-        return false;
+    public boolean changePlanOverrideBillingPolicy(final String productName, final BillingPeriod billingPeriod, final String priceList, final LocalDate localDate, final ActionPolicy actionPolicy, final CallContext callContext) throws EntitlementApiException {
+        final InternalCallContext context = internalCallContextFactory.createInternalCallContext(accountId, callContext);
+        final DateTime requestedDate = fromLocalDateAndReferenceTime(localDate, subscription.getStartDate(), clock, context);
+        try {
+            checker.checkBlockedChange(subscription, context);
+            return subscription.changePlanWithPolicy(productName, billingPeriod, priceList, requestedDate, actionPolicy, callContext);
+        } catch (BlockingApiException e) {
+            throw new EntitlementApiException(e, e.getCode(), e.getMessage());
+        } catch (SubscriptionUserApiException e) {
+            throw new EntitlementApiException(e);
+        }
     }
 
     @Override
@@ -114,6 +131,9 @@ public class DefaultEntitlement implements Entitlement {
         return false;
     }
 
+    public UUID getAccountId() {
+        return accountId;
+    }
 
     public Subscription getSubscription() {
         return subscription;
@@ -163,14 +183,29 @@ public class DefaultEntitlement implements Entitlement {
      */
 
 
+    /**
+     * Returns a DateTime that is equals or beforeNow and whose LocalDate using the account timeZone is the one provided
+     *
+     * Relies on the subscriptionStartDate for the reference time
+     *
+     * @param requestedDate
+     * @param subscriptionStartDate
+     * @param clock
+     * @param callContext
+     * @return
+     * @throws EntitlementApiException
+     */
     private DateTime fromLocalDateAndReferenceTime(final LocalDate requestedDate, final DateTime subscriptionStartDate, final Clock clock, final InternalCallContext callContext) throws EntitlementApiException {
         try {
             final Account account = accountApi.getAccountByRecordId(callContext.getAccountRecordId(), callContext);
             final DateAndTimeZoneContext timeZoneContext = new DateAndTimeZoneContext(subscriptionStartDate, account.getTimeZone(), clock);
-            return timeZoneContext.computeUTCDateTimeFromLocalDate(requestedDate);
+            final DateTime computedTime = timeZoneContext.computeUTCDateTimeFromLocalDate(requestedDate);
+
+            return computedTime.isAfter(clock.getUTCNow()) ? clock.getUTCNow() : computedTime;
         } catch (AccountApiException e) {
             throw new EntitlementApiException(e);
         }
     }
 
+
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlementApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlementApi.java
index e3ccde1..847b646 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlementApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/DefaultEntitlementApi.java
@@ -23,7 +23,11 @@ import java.util.UUID;
 import javax.annotation.Nullable;
 import javax.inject.Inject;
 
+import org.joda.time.DateTime;
+
 import com.ning.billing.ErrorCode;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.clock.Clock;
@@ -40,6 +44,7 @@ import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.svcapi.account.AccountInternalApi;
 import com.ning.billing.util.svcapi.subscription.SubscriptionInternalApi;
+import com.ning.billing.util.timezone.DateAndTimeZoneContext;
 
 import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
@@ -71,7 +76,7 @@ public class DefaultEntitlementApi implements EntitlementApi {
         try {
             final SubscriptionBundle bundle = subscriptionInternalApi.createBundleForAccount(accountId, externalKey, context);
             final Subscription subscription = subscriptionInternalApi.createSubscription(bundle.getId(), planPhaseSpecifier, clock.getUTCNow(), context);
-            return new DefaultEntitlement(accountApi, subscription, internalCallContextFactory, clock, checker);
+            return new DefaultEntitlement(accountApi, subscriptionInternalApi, subscription, accountId, internalCallContextFactory, clock, checker);
         } catch (SubscriptionUserApiException e) {
             throw new EntitlementApiException(e);
         }
@@ -86,8 +91,13 @@ public class DefaultEntitlementApi implements EntitlementApi {
                 baseSubscription.getState() != SubscriptionState.ACTIVE) {
                 throw new EntitlementApiException(new SubscriptionUserApiException(ErrorCode.SUB_GET_NO_SUCH_BASE_SUBSCRIPTION, baseSubscription.getBundleId()));
             }
-            final Subscription subscription = subscriptionInternalApi.createSubscription(baseSubscription.getBundleId(), planPhaseSpecifier, clock.getUTCNow(), context);
-            return new DefaultEntitlement(accountApi, subscription, internalCallContextFactory, clock, checker);
+
+            final SubscriptionBundle bundle = subscriptionInternalApi.getBundleFromId(baseSubscription.getBundleId(), context);
+            final InternalCallContext contextWithValidAccountRecordId = internalCallContextFactory.createInternalCallContext(bundle.getAccountId(), callContext);
+
+            final DateTime requestedDate = fromNowAndReferenceTime(baseSubscription.getStartDate(), contextWithValidAccountRecordId);
+            final Subscription subscription = subscriptionInternalApi.createSubscription(baseSubscription.getBundleId(), planPhaseSpecifier, requestedDate, context);
+            return new DefaultEntitlement(accountApi, subscriptionInternalApi, subscription, bundle.getAccountId(), internalCallContextFactory, clock, checker);
         } catch (SubscriptionUserApiException e) {
             throw new EntitlementApiException(e);
         }
@@ -98,7 +108,8 @@ public class DefaultEntitlementApi implements EntitlementApi {
         final InternalTenantContext context = internalCallContextFactory.createInternalTenantContext(tenantContext);
         try {
             final Subscription subscription = subscriptionInternalApi.getSubscriptionFromId(uuid, context);
-            return new DefaultEntitlement(accountApi, subscription, internalCallContextFactory, clock, checker);
+            final SubscriptionBundle bundle = subscriptionInternalApi.getBundleFromId(subscription.getBundleId(), context);
+            return new DefaultEntitlement(accountApi, subscriptionInternalApi, subscription, bundle.getAccountId(), internalCallContextFactory, clock, checker);
         } catch (SubscriptionUserApiException e) {
             throw new EntitlementApiException(e);
         }
@@ -109,7 +120,8 @@ public class DefaultEntitlementApi implements EntitlementApi {
         final InternalTenantContext context = internalCallContextFactory.createInternalTenantContext(tenantContext);
         try {
             final Subscription baseSubscription = subscriptionInternalApi.getSubscriptionFromId(baseSubscriptionId, context);
-            return getAllEntitlementFromBundleId(baseSubscription.getBundleId(), context);
+            final SubscriptionBundle bundle = subscriptionInternalApi.getBundleFromId(baseSubscription.getBundleId(), context);
+            return getAllEntitlementFromBundleId(baseSubscription.getBundleId(), bundle.getAccountId(), context);
         } catch (SubscriptionUserApiException e) {
             throw new EntitlementApiException(e);
         }
@@ -121,20 +133,20 @@ public class DefaultEntitlementApi implements EntitlementApi {
 
         try {
             final SubscriptionBundle bundle = subscriptionInternalApi.getBundleForAccountAndKey(accountId, externalKey, context);
-            return getAllEntitlementFromBundleId(bundle.getId(), context);
+            return getAllEntitlementFromBundleId(bundle.getId(), bundle.getAccountId(), context);
         } catch (SubscriptionUserApiException e) {
             throw new EntitlementApiException(e);
         }
     }
 
 
-    private List<Entitlement> getAllEntitlementFromBundleId(final UUID bundleId, final InternalTenantContext context) throws EntitlementApiException {
+    private List<Entitlement> getAllEntitlementFromBundleId(final UUID bundleId, final UUID accountId, final InternalTenantContext context) throws EntitlementApiException {
         final List<Subscription> subscriptions = subscriptionInternalApi.getSubscriptionsForBundle(bundleId, context);
         return ImmutableList.<Entitlement>copyOf(Collections2.transform(subscriptions, new Function<Subscription, Entitlement>() {
             @Nullable
             @Override
             public Entitlement apply(@Nullable final Subscription input) {
-                return new DefaultEntitlement(accountApi, input, internalCallContextFactory, clock, checker);
+                return new DefaultEntitlement(accountApi, subscriptionInternalApi, input, accountId, internalCallContextFactory, clock, checker);
             }
         }));
     }
@@ -147,7 +159,7 @@ public class DefaultEntitlementApi implements EntitlementApi {
         final InternalTenantContext context = internalCallContextFactory.createInternalTenantContext(tenantContext);
         final List<SubscriptionBundle> bundles = subscriptionInternalApi.getBundlesForAccount(accountId, context);
         for (final SubscriptionBundle bundle : bundles) {
-            final List<Entitlement> entitlements = getAllEntitlementFromBundleId(bundle.getId(), context);
+            final List<Entitlement> entitlements = getAllEntitlementFromBundleId(bundle.getId(), bundle.getAccountId(), context);
             result.addAll(entitlements);
         }
         return result;
@@ -157,4 +169,15 @@ public class DefaultEntitlementApi implements EntitlementApi {
     public List<BlockingState> getBlockingHistory(final UUID overdueableId, final TenantContext context) {
         return dao.getBlockingHistoryFor(overdueableId, internalCallContextFactory.createInternalTenantContext(context));
     }
+
+    private DateTime fromNowAndReferenceTime(final DateTime subscriptionStartDate, final InternalCallContext callContext) throws EntitlementApiException {
+        try {
+            final Account account = accountApi.getAccountByRecordId(callContext.getAccountRecordId(), callContext);
+            final DateAndTimeZoneContext timeZoneContext = new DateAndTimeZoneContext(subscriptionStartDate, account.getTimeZone(), clock);
+            return timeZoneContext.computeUTCDateTimeFromNow();
+        } catch (AccountApiException e) {
+            throw new EntitlementApiException(e);
+        }
+    }
+
 }
diff --git a/osgi/killbill-osgi.iml b/osgi/killbill-osgi.iml
index e7e9b77..e0c8736 100644
--- a/osgi/killbill-osgi.iml
+++ b/osgi/killbill-osgi.iml
@@ -4,8 +4,8 @@
     <output url="file://$MODULE_DIR$/target/classes" />
     <output-test url="file://$MODULE_DIR$/target/test-classes" />
     <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <excludeFolder url="file://$MODULE_DIR$/target" />
     </content>
diff --git a/osgi-bundles/libs/killbill/killbill-osgi-bundles-lib-killbill.iml b/osgi-bundles/libs/killbill/killbill-osgi-bundles-lib-killbill.iml
index 7f58107..66797cd 100644
--- a/osgi-bundles/libs/killbill/killbill-osgi-bundles-lib-killbill.iml
+++ b/osgi-bundles/libs/killbill/killbill-osgi-bundles-lib-killbill.iml
@@ -4,10 +4,10 @@
     <output url="file://$MODULE_DIR$/target/classes" />
     <output-test url="file://$MODULE_DIR$/target/test-classes" />
     <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/test/resources" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
       <excludeFolder url="file://$MODULE_DIR$/target" />
     </content>
     <orderEntry type="inheritedJdk" />
diff --git a/util/src/main/java/com/ning/billing/util/timezone/DateAndTimeZoneContext.java b/util/src/main/java/com/ning/billing/util/timezone/DateAndTimeZoneContext.java
index 1aba246..717a1b0 100644
--- a/util/src/main/java/com/ning/billing/util/timezone/DateAndTimeZoneContext.java
+++ b/util/src/main/java/com/ning/billing/util/timezone/DateAndTimeZoneContext.java
@@ -28,6 +28,7 @@ public final class DateAndTimeZoneContext {
         return new LocalDate(targetDateTime, accountTimeZone);
     }
 
+
     public DateTime computeUTCDateTimeFromLocalDate(final LocalDate invoiceItemEndDate) {
         //
         // Since we create the targetDate for next invoice using the date from the notificationQ, we need to make sure
@@ -47,4 +48,10 @@ public final class DateAndTimeZoneContext {
         final int localToUTCOffest = -1 * utcOffest;
         return invoiceItemEndDate.toDateTime(referenceTime, DateTimeZone.UTC).plusMillis(localToUTCOffest);
     }
+
+    public DateTime computeUTCDateTimeFromNow() {
+        final LocalDate now = computeTargetDate(clock.getUTCNow());
+        return computeUTCDateTimeFromLocalDate(now);
+    }
+
 }