killbill-memoizeit

Changes

Details

diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
index c1450c0..2f7e944 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessTagRecorder.java
@@ -109,9 +109,8 @@ public class TestBusinessTagRecorder extends AnalyticsTestSuiteWithEmbeddedDB {
         final EntitlementDao entitlementDao = new DefaultEntitlementDao(dbi, clock, addonUtils, notificationQueueService, eventBus, catalogService);
         final PlanAligner planAligner = new PlanAligner(catalogService);
         final DefaultSubscriptionApiService apiService = new DefaultSubscriptionApiService(clock, entitlementDao, catalogService, planAligner, internalCallContextFactory);
-        final DefaultSubscriptionFactory subscriptionFactory = new DefaultSubscriptionFactory(apiService, clock, catalogService);
-        entitlementApi = new DefaultEntitlementInternalApi(entitlementDao, subscriptionFactory);
-        entitlementUserApi = new DefaultEntitlementUserApi(clock, entitlementDao, catalogService, apiService, subscriptionFactory, addonUtils, internalCallContextFactory);
+        entitlementApi = new DefaultEntitlementInternalApi(entitlementDao, apiService, clock);
+        entitlementUserApi = new DefaultEntitlementUserApi(clock, entitlementDao, catalogService, apiService, addonUtils, internalCallContextFactory);
         tagDao = new BusinessTagDao(accountTagSqlDao, invoicePaymentTagSqlDao, invoiceTagSqlDao, subscriptionTransitionTagSqlDao,
                                     accountApi, entitlementApi);
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
index 3d5abda..b330f37 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/svcs/DefaultEntitlementInternalApi.java
@@ -15,6 +15,7 @@
  */
 package com.ning.billing.entitlement.api.svcs;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
@@ -28,6 +29,7 @@ import org.joda.time.LocalTime;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.entitlement.api.SubscriptionFactory;
 import com.ning.billing.entitlement.api.user.DefaultEffectiveSubscriptionEvent;
+import com.ning.billing.entitlement.api.user.DefaultSubscriptionApiService;
 import com.ning.billing.entitlement.api.user.DefaultSubscriptionFactory.SubscriptionBuilder;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
@@ -37,6 +39,7 @@ import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.events.EffectiveSubscriptionInternalEvent;
 import com.ning.billing.util.svcapi.entitlement.EntitlementInternalApi;
 
@@ -48,12 +51,16 @@ import com.google.inject.Inject;
 public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
 
     private final EntitlementDao dao;
-    private final SubscriptionFactory subscriptionFactory;
+    private final DefaultSubscriptionApiService apiService;
+    private final Clock clock;
+
     @Inject
     public DefaultEntitlementInternalApi(final EntitlementDao dao,
-            final SubscriptionFactory subscriptionFactory) {
+            final DefaultSubscriptionApiService apiService,
+            final Clock clock) {
         this.dao = dao;
-        this.subscriptionFactory = subscriptionFactory;
+        this.apiService = apiService;
+        this.clock = clock;
     }
 
     @Override
@@ -65,27 +72,28 @@ public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
     @Override
     public List<Subscription> getSubscriptionsForBundle(UUID bundleId,
             InternalTenantContext context) {
-        return dao.getSubscriptions(subscriptionFactory, bundleId, context);
+        final List<Subscription> internalSubscriptions =  dao.getSubscriptions(bundleId, context);
+        return createSubscriptionsForApiUse(internalSubscriptions);
     }
 
     @Override
     public Subscription getBaseSubscription(UUID bundleId,
             InternalTenantContext context) throws EntitlementUserApiException {
-        final Subscription result = dao.getBaseSubscription(subscriptionFactory, bundleId, context);
+        final Subscription result = dao.getBaseSubscription(bundleId, context);
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_GET_NO_SUCH_BASE_SUBSCRIPTION, bundleId);
         }
-        return result;
+        return createSubscriptionForApiUse(result);
     }
 
     @Override
     public Subscription getSubscriptionFromId(UUID id,
             InternalTenantContext context) throws EntitlementUserApiException {
-        final Subscription result = dao.getSubscriptionFromId(subscriptionFactory, id, context);
+        final Subscription result = dao.getSubscriptionFromId(id, context);
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, id);
         }
-        return result;
+        return createSubscriptionForApiUse(result);
     }
 
     @Override
@@ -108,7 +116,7 @@ public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
     @Override
     public void setChargedThroughDate(UUID subscriptionId,
             LocalDate localChargedThruDate, InternalCallContext context) {
-        final SubscriptionData subscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionFactory, subscriptionId, context);
+        final SubscriptionData subscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionId, context);
         final DateTime chargedThroughDate = localChargedThruDate.toDateTime(new LocalTime(subscription.getStartDate(), DateTimeZone.UTC), DateTimeZone.UTC);
         final SubscriptionBuilder builder = new SubscriptionBuilder(subscription)
                 .setChargedThroughDate(chargedThroughDate)
@@ -138,4 +146,19 @@ public class DefaultEntitlementInternalApi implements EntitlementInternalApi {
             }
         }));
     }
+
+
+    // TODO Copied from DefaultEntitlemenUserApi. should probably share that in a base class
+    private List<Subscription> createSubscriptionsForApiUse(final List<Subscription> internalSubscriptions) {
+        return new ArrayList<Subscription>(Collections2.transform(internalSubscriptions, new Function<Subscription, Subscription>() {
+            @Override
+            public Subscription apply(final Subscription subscription) {
+                return createSubscriptionForApiUse((SubscriptionData) subscription);
+            }
+        }));
+    }
+
+    private Subscription createSubscriptionForApiUse(final Subscription internalSubscription) {
+        return new SubscriptionData((SubscriptionData) internalSubscription, apiService, clock);
+    }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
index f61d2a6..a3c6441 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.entitlement.api.timeline;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -25,12 +26,15 @@ import java.util.Set;
 import java.util.TreeSet;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 
 import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.entitlement.api.SubscriptionApiService;
 import com.ning.billing.entitlement.api.SubscriptionFactory;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
 import com.ning.billing.entitlement.api.timeline.SubscriptionTimeline.NewEvent;
@@ -40,6 +44,7 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionBundleData;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
+import com.ning.billing.entitlement.engine.addon.AddonUtils;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
 import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
@@ -47,7 +52,10 @@ import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.TenantContext;
+import com.ning.billing.util.clock.Clock;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 
@@ -58,6 +66,11 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     private final RepairEntitlementLifecycleDao repairDao;
     private final CatalogService catalogService;
     private final InternalCallContextFactory internalCallContextFactory;
+    private final Clock clock;
+    private final AddonUtils addonUtils;
+
+    private final SubscriptionApiService apiService;
+    private final SubscriptionApiService repairApiService;
 
     private enum RepairType {
         BASE_REPAIR,
@@ -68,12 +81,19 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     @Inject
     public DefaultEntitlementTimelineApi(@Named(DefaultEntitlementModule.REPAIR_NAMED) final SubscriptionFactory factory, final CatalogService catalogService,
                                          @Named(DefaultEntitlementModule.REPAIR_NAMED) final RepairEntitlementLifecycleDao repairDao, final EntitlementDao dao,
-                                         final InternalCallContextFactory internalCallContextFactory) {
+                                         final SubscriptionApiService apiService,
+                                         @Named(DefaultEntitlementModule.REPAIR_NAMED) final SubscriptionApiService repairApiService,
+                                         final InternalCallContextFactory internalCallContextFactory, final Clock clock, final AddonUtils addonUtils) {
         this.catalogService = catalogService;
         this.dao = dao;
         this.repairDao = repairDao;
         this.factory = factory;
         this.internalCallContextFactory = internalCallContextFactory;
+
+        this.apiService = apiService;
+        this.repairApiService = repairApiService;
+        this.clock = clock;
+        this.addonUtils = addonUtils;
     }
 
     @Override
@@ -101,7 +121,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             if (bundle == null) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_BUNDLE, descBundle);
             }
-            final List<Subscription> subscriptions = dao.getSubscriptions(factory, bundle.getId(), internalCallContextFactory.createInternalTenantContext(context));
+            final List<SubscriptionDataRepair> subscriptions = convertToSubscriptionsDataRepair(dao.getSubscriptions(bundle.getId(), internalCallContextFactory.createInternalTenantContext(context)));
             if (subscriptions.size() == 0) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NO_ACTIVE_SUBSCRIPTIONS, bundle.getId());
             }
@@ -113,6 +133,18 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         }
     }
 
+    private List<SubscriptionDataRepair> convertToSubscriptionsDataRepair(List<Subscription> input) {
+        return new ArrayList<SubscriptionDataRepair>(Collections2.transform(input, new Function<Subscription, SubscriptionDataRepair>() {
+            @Override
+            public SubscriptionDataRepair apply(@Nullable final Subscription subscription) {
+                return convertToSubscriptionDataRepair((SubscriptionData) subscription);
+            }
+        }));
+    }
+    private SubscriptionDataRepair convertToSubscriptionDataRepair(SubscriptionData input) {
+        return new SubscriptionDataRepair(input, repairApiService, (EntitlementDao) repairDao, clock, addonUtils, catalogService, internalCallContextFactory);
+    }
+
     @Override
     public BundleTimeline repairBundle(final BundleTimeline input, final boolean dryRun, final CallContext context) throws EntitlementRepairException {
         final InternalTenantContext tenantContext = internalCallContextFactory.createInternalTenantContext(context);
@@ -123,7 +155,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             }
 
             // Subscriptions are ordered with BASE subscription first-- if exists
-            final List<Subscription> subscriptions = dao.getSubscriptions(factory, input.getId(), tenantContext);
+            final List<SubscriptionDataRepair> subscriptions = convertToSubscriptionsDataRepair(dao.getSubscriptions(input.getId(), tenantContext));
             if (subscriptions.size() == 0) {
                 throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NO_ACTIVE_SUBSCRIPTIONS, input.getId());
             }
@@ -252,7 +284,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         }
     }
 
-    private void validateBasePlanRecreate(final boolean isBasePlanRecreate, final List<Subscription> subscriptions, final List<SubscriptionTimeline> input)
+    private void validateBasePlanRecreate(final boolean isBasePlanRecreate, final List<SubscriptionDataRepair> subscriptions, final List<SubscriptionTimeline> input)
             throws EntitlementRepairException {
         if (!isBasePlanRecreate) {
             return;
@@ -269,7 +301,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         }
     }
 
-    private void validateInputSubscriptionsKnown(final List<Subscription> subscriptions, final List<SubscriptionTimeline> input)
+    private void validateInputSubscriptionsKnown(final List<SubscriptionDataRepair> subscriptions, final List<SubscriptionTimeline> input)
             throws EntitlementRepairException {
         for (final SubscriptionTimeline cur : input) {
             boolean found = false;
@@ -365,7 +397,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         return result;
     }
 
-    private String getViewId(final DateTime lastUpdateBundleDate, final List<Subscription> subscriptions) {
+    private String getViewId(final DateTime lastUpdateBundleDate, final List<SubscriptionDataRepair> subscriptions) {
         final StringBuilder tmp = new StringBuilder();
         long lastOrderedId = -1;
         for (final Subscription cur : subscriptions) {
@@ -412,7 +444,7 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
         };
     }
 
-    private List<SubscriptionTimeline> createGetSubscriptionRepairList(final List<Subscription> subscriptions, final List<SubscriptionTimeline> inRepair) throws CatalogApiException {
+    private List<SubscriptionTimeline> createGetSubscriptionRepairList(final List<SubscriptionDataRepair> subscriptions, final List<SubscriptionTimeline> inRepair) throws CatalogApiException {
 
         final List<SubscriptionTimeline> result = new LinkedList<SubscriptionTimeline>();
         final Set<UUID> repairIds = new TreeSet<UUID>();
@@ -464,7 +496,9 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             }
         }
 
-        return (SubscriptionDataRepair) factory.createSubscription(builder, initialEvents);
+        final SubscriptionDataRepair subscriptiondataRepair = new SubscriptionDataRepair(builder, curData.getEvents(), repairApiService, (EntitlementDao) repairDao, clock, addonUtils, catalogService, internalCallContextFactory);
+        subscriptiondataRepair.rebuildTransitions(curData.getEvents(), catalogService.getFullCatalog());
+        return subscriptiondataRepair;
     }
 
     private SubscriptionTimeline findAndCreateSubscriptionRepair(final UUID target, final List<SubscriptionTimeline> input) {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java
index f32a211..72787c6 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/RepairSubscriptionFactory.java
@@ -55,9 +55,14 @@ public class RepairSubscriptionFactory extends DefaultSubscriptionFactory implem
     @Override
     public SubscriptionData createSubscription(final SubscriptionBuilder builder,
                                                final List<EntitlementEvent> events) {
+
+
+        /*
         final SubscriptionData subscription = new SubscriptionDataRepair(builder, events, getApiService(), repairDao, getClock(),
                                                                          addonUtils, getCatalogService(), internalCallContextFactory);
         subscription.rebuildTransitions(events, getCatalogService().getFullCatalog());
         return subscription;
+*/
+        return null;
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java
index 301f15f..748b1fa 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionDataRepair.java
@@ -59,8 +59,6 @@ public class SubscriptionDataRepair extends SubscriptionData {
     private final List<EntitlementEvent> initialEvents;
     private final InternalCallContextFactory internalCallContextFactory;
 
-    // Low level events are ONLY used for Repair APIs
-    private List<EntitlementEvent> events;
 
     public SubscriptionDataRepair(final SubscriptionBuilder builder, final List<EntitlementEvent> initialEvents, final SubscriptionApiService apiService,
                                   final EntitlementDao dao, final Clock clock, final AddonUtils addonUtils, final CatalogService catalogService,
@@ -74,6 +72,20 @@ public class SubscriptionDataRepair extends SubscriptionData {
         this.internalCallContextFactory = internalCallContextFactory;
     }
 
+
+
+    public SubscriptionDataRepair(final SubscriptionData subscriptionData, final SubscriptionApiService apiService,
+                                  final EntitlementDao dao, final Clock clock, final AddonUtils addonUtils, final CatalogService catalogService,
+                                  final InternalCallContextFactory internalCallContextFactory) {
+        super(subscriptionData, apiService , clock);
+        this.repairDao = dao;
+        this.addonUtils = addonUtils;
+        this.clock = clock;
+        this.catalogService = catalogService;
+        this.initialEvents = subscriptionData.getEvents();
+        this.internalCallContextFactory = internalCallContextFactory;
+    }
+
     DateTime getLastUserEventEffectiveDate() {
         DateTime res = null;
         for (final EntitlementEvent cur : events) {
@@ -185,12 +197,6 @@ public class SubscriptionDataRepair extends SubscriptionData {
         }
     }
 
-    @Override
-    public void rebuildTransitions(final List<EntitlementEvent> inputEvents, final Catalog catalog) {
-        this.events = inputEvents;
-        super.rebuildTransitions(inputEvents, catalog);
-    }
-
     public List<EntitlementEvent> getEvents() {
         return events;
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/transfer/DefaultEntitlementTransferApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/transfer/DefaultEntitlementTransferApi.java
index 466d466..343a708 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/transfer/DefaultEntitlementTransferApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/transfer/DefaultEntitlementTransferApi.java
@@ -220,7 +220,7 @@ public class DefaultEntitlementTransferApi implements EntitlementTransferApi {
             DateTime bundleStartdate = null;
 
             for (final SubscriptionTimeline cur : bundleTimeline.getSubscriptions()) {
-                final SubscriptionData oldSubscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionFactory, cur.getId(), fromInternalCallContext);
+                final SubscriptionData oldSubscription = (SubscriptionData) dao.getSubscriptionFromId(cur.getId(), fromInternalCallContext);
                 final List<ExistingEvent> existingEvents = cur.getExistingEvents();
                 final ProductCategory productCategory = existingEvents.get(0).getPlanPhaseSpecifier().getProductCategory();
                 if (productCategory == ProductCategory.ADD_ON) {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
index d7b8d6e..5b7a921 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultEntitlementUserApi.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.entitlement.api.user;
 
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
@@ -46,6 +47,8 @@ import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
 import com.google.inject.Inject;
 
 public class DefaultEntitlementUserApi implements EntitlementUserApi {
@@ -55,19 +58,17 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     private final CatalogService catalogService;
     private final DefaultSubscriptionApiService apiService;
     private final AddonUtils addonUtils;
-    private final SubscriptionFactory subscriptionFactory;
     private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public DefaultEntitlementUserApi(final Clock clock, final EntitlementDao dao, final CatalogService catalogService,
-                                     final DefaultSubscriptionApiService apiService, final SubscriptionFactory subscriptionFactory,
+                                     final DefaultSubscriptionApiService apiService,
                                      final AddonUtils addonUtils, final InternalCallContextFactory internalCallContextFactory) {
         this.clock = clock;
         this.apiService = apiService;
         this.dao = dao;
         this.catalogService = catalogService;
         this.addonUtils = addonUtils;
-        this.subscriptionFactory = subscriptionFactory;
         this.internalCallContextFactory = internalCallContextFactory;
     }
 
@@ -82,11 +83,11 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
 
     @Override
     public Subscription getSubscriptionFromId(final UUID id, final TenantContext context) throws EntitlementUserApiException {
-        final Subscription result = dao.getSubscriptionFromId(subscriptionFactory, id, internalCallContextFactory.createInternalTenantContext(context));
+        final Subscription result = dao.getSubscriptionFromId(id, internalCallContextFactory.createInternalTenantContext(context));
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, id);
         }
-        return result;
+        return createSubscriptionForApiUse(result);
     }
 
     @Override
@@ -111,21 +112,37 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
 
     @Override
     public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId, final String bundleKey, final TenantContext context) {
-        return dao.getSubscriptionsForAccountAndKey(subscriptionFactory, accountId, bundleKey, internalCallContextFactory.createInternalTenantContext(context));
+        final List<Subscription> internalSubscriptions = dao.getSubscriptionsForAccountAndKey(accountId, bundleKey, internalCallContextFactory.createInternalTenantContext(context));
+        return createSubscriptionsForApiUse(internalSubscriptions);
     }
 
     @Override
     public List<Subscription> getSubscriptionsForBundle(final UUID bundleId, final TenantContext context) {
-        return dao.getSubscriptions(subscriptionFactory, bundleId, internalCallContextFactory.createInternalTenantContext(context));
+        final List<Subscription> internalSubscriptions = dao.getSubscriptions(bundleId, internalCallContextFactory.createInternalTenantContext(context));
+        return createSubscriptionsForApiUse(internalSubscriptions);
     }
 
     @Override
     public Subscription getBaseSubscription(final UUID bundleId, final TenantContext context) throws EntitlementUserApiException {
-        final Subscription result = dao.getBaseSubscription(subscriptionFactory, bundleId, internalCallContextFactory.createInternalTenantContext(context));
+        final Subscription result = dao.getBaseSubscription(bundleId, internalCallContextFactory.createInternalTenantContext(context));
         if (result == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_GET_NO_SUCH_BASE_SUBSCRIPTION, bundleId);
         }
-        return result;
+        return createSubscriptionForApiUse(result);
+    }
+
+
+    private List<Subscription> createSubscriptionsForApiUse(final List<Subscription> internalSubscriptions) {
+        return new ArrayList<Subscription>(Collections2.transform(internalSubscriptions, new Function<Subscription, Subscription>() {
+            @Override
+            public Subscription apply(final Subscription subscription) {
+                return createSubscriptionForApiUse((SubscriptionData) subscription);
+            }
+        }));
+    }
+
+    private Subscription createSubscriptionForApiUse(final Subscription internalSubscription) {
+        return new SubscriptionData((SubscriptionData) internalSubscription, apiService, clock);
     }
 
     @Override
@@ -162,7 +179,7 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
             }
 
             DateTime bundleStartDate = null;
-            final SubscriptionData baseSubscription = (SubscriptionData) dao.getBaseSubscription(subscriptionFactory, bundleId, internalCallContextFactory.createInternalTenantContext(context));
+            final SubscriptionData baseSubscription = (SubscriptionData) dao.getBaseSubscription(bundleId, internalCallContextFactory.createInternalTenantContext(context));
             switch (plan.getProduct().getCategory()) {
                 case BASE:
                     if (baseSubscription != null) {
@@ -231,7 +248,7 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
     public List<SubscriptionStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, @Nullable final String baseProductName,
                                                                     final DateTime requestedDate, final TenantContext context)
             throws EntitlementUserApiException {
-        final Subscription subscription = dao.getSubscriptionFromId(subscriptionFactory, subscriptionId, internalCallContextFactory.createInternalTenantContext(context));
+        final Subscription subscription = dao.getSubscriptionFromId(subscriptionId, internalCallContextFactory.createInternalTenantContext(context));
         if (subscription == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_SUBSCRIPTION_ID, subscriptionId);
         }
@@ -241,7 +258,7 @@ public class DefaultEntitlementUserApi implements EntitlementUserApi {
 
         final List<SubscriptionStatusDryRun> result = new LinkedList<SubscriptionStatusDryRun>();
 
-        final List<Subscription> bundleSubscriptions = dao.getSubscriptions(subscriptionFactory, subscription.getBundleId(), internalCallContextFactory.createInternalTenantContext(context));
+        final List<Subscription> bundleSubscriptions = dao.getSubscriptions(subscription.getBundleId(), internalCallContextFactory.createInternalTenantContext(context));
         for (final Subscription cur : bundleSubscriptions) {
             if (cur.getId().equals(subscriptionId)) {
                 continue;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java
index 3dd5850..4bd5f80 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/DefaultSubscriptionApiService.java
@@ -17,7 +17,9 @@
 package com.ning.billing.entitlement.api.user;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -37,6 +39,7 @@ import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.api.PriceList;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.Product;
+import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.entitlement.alignment.PlanAligner;
 import com.ning.billing.entitlement.alignment.TimedPhase;
 import com.ning.billing.entitlement.api.SubscriptionApiService;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
index 2903504..37edb2f 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionData.java
@@ -85,6 +85,14 @@ public class SubscriptionData extends EntityBase implements Subscription {
     //
     private LinkedList<SubscriptionTransitionData> transitions;
 
+    // Low level events are ONLY used for Repair APIs
+    protected List<EntitlementEvent> events;
+
+
+    public List<EntitlementEvent> getEvents() {
+        return events;
+    }
+
     // Transient object never returned at the API
     public SubscriptionData(final SubscriptionBuilder builder) {
         this(builder, null, null);
@@ -103,6 +111,22 @@ public class SubscriptionData extends EntityBase implements Subscription {
         this.paidThroughDate = builder.getPaidThroughDate();
     }
 
+    // Used for API to make sure we have a clock and an apiService set before we return the object
+    public SubscriptionData(final SubscriptionData internalSubscription, final SubscriptionApiService apiService, final Clock clock) {
+        super(internalSubscription.getId(), internalSubscription.getCreatedDate(), internalSubscription.getUpdatedDate());
+        this.apiService = apiService;
+        this.clock = clock;
+        this.bundleId = internalSubscription.getBundleId();
+        this.alignStartDate = internalSubscription.getAlignStartDate();
+        this.bundleStartDate = internalSubscription.getBundleStartDate();
+        this.category = internalSubscription.getCategory();
+        this.activeVersion = internalSubscription.getActiveVersion();
+        this.chargedThroughDate = internalSubscription.getChargedThroughDate();
+        this.paidThroughDate = internalSubscription.getPaidThroughDate();
+        this.transitions = new LinkedList<SubscriptionTransitionData>(internalSubscription.getAllTransitions());
+        this.events = internalSubscription.getEvents();
+    }
+
     @Override
     public UUID getBundleId() {
         return bundleId;
@@ -491,6 +515,8 @@ public class SubscriptionData extends EntityBase implements Subscription {
             return;
         }
 
+        this.events = inputEvents;
+
         SubscriptionState nextState = null;
         String nextPlanName = null;
         String nextPhaseName = null;
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 b4d8d88..6e60f0d 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
@@ -29,7 +29,6 @@ import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.util.config.EntitlementConfig;
-import com.ning.billing.util.config.NotificationConfig;
 import com.ning.billing.entitlement.alignment.PlanAligner;
 import com.ning.billing.entitlement.alignment.TimedPhase;
 import com.ning.billing.entitlement.api.EntitlementService;
@@ -161,7 +160,7 @@ public class Engine implements EventListener, EntitlementService {
             return;
         }
 
-        final SubscriptionData subscription = (SubscriptionData) dao.getSubscriptionFromId(subscriptionFactory, event.getSubscriptionId(), context);
+        final SubscriptionData subscription = (SubscriptionData) dao.getSubscriptionFromId(event.getSubscriptionId(), context);
         if (subscription == null) {
             log.warn("Failed to retrieve subscription for id %s", event.getSubscriptionId());
             return;
@@ -211,7 +210,7 @@ public class Engine implements EventListener, EntitlementService {
         final DateTime now = clock.getUTCNow();
         final Product baseProduct = (baseSubscription.getState() == SubscriptionState.CANCELLED) ? null : baseSubscription.getCurrentPlan().getProduct();
 
-        final List<Subscription> subscriptions = dao.getSubscriptions(subscriptionFactory, baseSubscription.getBundleId(), context);
+        final List<Subscription> subscriptions = dao.getSubscriptions(baseSubscription.getBundleId(), context);
 
         final Map<UUID, EntitlementEvent> addOnCancellations = new HashMap<UUID, EntitlementEvent>();
         final Map<UUID, SubscriptionData> addOnCancellationSubscriptions = new HashMap<UUID, SubscriptionData>();
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/DefaultEntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/DefaultEntitlementDao.java
index 4831fdc..c02dd19 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/DefaultEntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/DefaultEntitlementDao.java
@@ -39,7 +39,6 @@ import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.CatalogService;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.SubscriptionFactory;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.BundleMigrationData;
 import com.ning.billing.entitlement.api.migration.AccountMigrationData.SubscriptionMigrationData;
@@ -98,6 +97,7 @@ public class DefaultEntitlementDao implements EntitlementDao {
     private final NotificationQueueService notificationQueueService;
     private final AddonUtils addonUtils;
     private final InternalBus eventBus;
+    private final CatalogService catalogService;
 
     @Inject
     public DefaultEntitlementDao(final IDBI dbi, final Clock clock, final AddonUtils addonUtils,
@@ -107,6 +107,7 @@ public class DefaultEntitlementDao implements EntitlementDao {
         this.notificationQueueService = notificationQueueService;
         this.addonUtils = addonUtils;
         this.eventBus = eventBus;
+        this.catalogService = catalogService;
     }
 
     @Override
@@ -206,29 +207,26 @@ public class DefaultEntitlementDao implements EntitlementDao {
     }
 
     @Override
-    public Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
-        return getBaseSubscription(factory, bundleId, true, context);
+    public Subscription getBaseSubscription(final UUID bundleId, final InternalTenantContext context) {
+        return getBaseSubscription(bundleId, true, context);
     }
 
     @Override
-    public Subscription getSubscriptionFromId(final SubscriptionFactory factory, final UUID subscriptionId, final InternalTenantContext context) {
-        return buildSubscription(factory, getSubscriptionFromId(subscriptionId, context), context);
-    }
-
-    private Subscription getSubscriptionFromId(final UUID subscriptionId, final InternalTenantContext context) {
-        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Subscription>() {
+    public Subscription getSubscriptionFromId(final UUID subscriptionId, final InternalTenantContext context) {
+        final Subscription shellSubscription = transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Subscription>() {
             @Override
             public Subscription inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
                 final SubscriptionModelDao model = entitySqlDaoWrapperFactory.become(SubscriptionSqlDao.class).getById(subscriptionId.toString(), context);
                 return SubscriptionModelDao.toSubscription(model);
             }
         });
+        return buildSubscription(shellSubscription, context);
     }
 
 
     @Override
-    public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
-        return buildBundleSubscriptions(bundleId, factory, getSubscriptionFromBundleId(bundleId, context), context);
+    public List<Subscription> getSubscriptions(final UUID bundleId, final InternalTenantContext context) {
+        return buildBundleSubscriptions(bundleId, getSubscriptionFromBundleId(bundleId, context), context);
     }
 
     private List<Subscription> getSubscriptionFromBundleId(final UUID bundleId, final InternalTenantContext context) {
@@ -248,7 +246,7 @@ public class DefaultEntitlementDao implements EntitlementDao {
 
 
     @Override
-    public List<Subscription> getSubscriptionsForAccountAndKey(final SubscriptionFactory factory, final UUID accountId,
+    public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId,
                                                                final String bundleKey, final InternalTenantContext context) {
         return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<Subscription>>() {
             @Override
@@ -257,7 +255,7 @@ public class DefaultEntitlementDao implements EntitlementDao {
                 if (bundleModel == null) {
                     return Collections.emptyList();
                 }
-                return getSubscriptions(factory, bundleModel.getId(), context);
+                return getSubscriptions(bundleModel.getId(), context);
             }
         });
     }
@@ -663,14 +661,14 @@ public class DefaultEntitlementDao implements EntitlementDao {
         }
     }
 
-    private Subscription buildSubscription(final SubscriptionFactory factory, final Subscription input, final InternalTenantContext context) {
+    private Subscription buildSubscription(final Subscription input, final InternalTenantContext context) {
         if (input == null) {
             return null;
         }
 
         final List<Subscription> bundleInput = new ArrayList<Subscription>();
         if (input.getCategory() == ProductCategory.ADD_ON) {
-            final Subscription baseSubscription = getBaseSubscription(factory, input.getBundleId(), false, context);
+            final Subscription baseSubscription = getBaseSubscription(input.getBundleId(), false, context);
             if (baseSubscription == null) {
                 return null;
             }
@@ -681,7 +679,7 @@ public class DefaultEntitlementDao implements EntitlementDao {
             bundleInput.add(input);
         }
 
-        final List<Subscription> reloadedSubscriptions = buildBundleSubscriptions(input.getBundleId(), factory, bundleInput, context);
+        final List<Subscription> reloadedSubscriptions = buildBundleSubscriptions(input.getBundleId(), bundleInput, context);
         for (final Subscription cur : reloadedSubscriptions) {
             if (cur.getId().equals(input.getId())) {
                 return cur;
@@ -691,7 +689,7 @@ public class DefaultEntitlementDao implements EntitlementDao {
         throw new EntitlementError("Unexpected code path in buildSubscription");
     }
 
-    private List<Subscription> buildBundleSubscriptions(final UUID bundleId, final SubscriptionFactory factory, final List<Subscription> input, final InternalTenantContext context) {
+    private List<Subscription> buildBundleSubscriptions(final UUID bundleId, final List<Subscription> input, final InternalTenantContext context) {
         if (input == null || input.size() == 0) {
             return Collections.emptyList();
         }
@@ -714,7 +712,7 @@ public class DefaultEntitlementDao implements EntitlementDao {
         final List<Subscription> result = new ArrayList<Subscription>(input.size());
         for (final Subscription cur : input) {
             final List<EntitlementEvent> events = getEventsForSubscription(cur.getId(), context);
-            Subscription reloaded = factory.createSubscription(new SubscriptionBuilder((SubscriptionData) cur), events);
+            Subscription reloaded = createSubscriptionForInternalUse(cur, events);
 
             switch (cur.getCategory()) {
                 case BASE:
@@ -752,7 +750,7 @@ public class DefaultEntitlementDao implements EntitlementDao {
 
                         events.add(addOnCancelEvent);
                         // Finally reload subscription with full set of events
-                        reloaded = factory.createSubscription(new SubscriptionBuilder((SubscriptionData) cur), events);
+                        reloaded = createSubscriptionForInternalUse(cur, events);
                     }
                     break;
                 default:
@@ -765,6 +763,15 @@ public class DefaultEntitlementDao implements EntitlementDao {
         return result;
     }
 
+
+    private SubscriptionData createSubscriptionForInternalUse(final Subscription shellSubscription, final List<EntitlementEvent> events) {
+        final SubscriptionData result = new SubscriptionData(new SubscriptionBuilder(((SubscriptionData) shellSubscription)), null, clock);
+        if (events.size() > 0) {
+            result.rebuildTransitions(events, catalogService.getFullCatalog());
+        }
+        return result;
+    }
+
     @Override
     public void migrate(final UUID accountId, final AccountMigrationData accountData, final InternalCallContext context) {
         transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
@@ -838,11 +845,11 @@ public class DefaultEntitlementDao implements EntitlementDao {
         });
     }
 
-    private Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, final boolean rebuildSubscription, final InternalTenantContext context) {
+    private Subscription getBaseSubscription(final UUID bundleId, final boolean rebuildSubscription, final InternalTenantContext context) {
         final List<Subscription> subscriptions = getSubscriptionFromBundleId(bundleId, context);
         for (final Subscription cur : subscriptions) {
             if (cur.getCategory() == ProductCategory.BASE) {
-                return rebuildSubscription ? buildSubscription(factory, cur, context) : cur;
+                return rebuildSubscription ? buildSubscription(cur, context) : cur;
             }
         }
         return null;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
index 1c17929..0235597 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementDao.java
@@ -46,17 +46,17 @@ public interface EntitlementDao {
 
     public SubscriptionBundle createSubscriptionBundle(SubscriptionBundleData bundle, InternalCallContext context);
 
-    public Subscription getSubscriptionFromId(SubscriptionFactory factory, UUID subscriptionId, InternalTenantContext context);
+    public Subscription getSubscriptionFromId(UUID subscriptionId, InternalTenantContext context);
 
     // ACCOUNT retrieval
     public UUID getAccountIdFromSubscriptionId(UUID subscriptionId, InternalTenantContext context);
 
     // Subscription retrieval
-    public Subscription getBaseSubscription(SubscriptionFactory factory, UUID bundleId, InternalTenantContext context);
+    public Subscription getBaseSubscription(UUID bundleId, InternalTenantContext context);
 
-    public List<Subscription> getSubscriptions(SubscriptionFactory factory, UUID bundleId, InternalTenantContext context);
+    public List<Subscription> getSubscriptions(UUID bundleId, InternalTenantContext context);
 
-    public List<Subscription> getSubscriptionsForAccountAndKey(SubscriptionFactory factory, UUID accountId, String bundleKey, InternalTenantContext context);
+    public List<Subscription> getSubscriptionsForAccountAndKey(UUID accountId, String bundleKey, InternalTenantContext context);
 
     // Update
     public void updateChargedThroughDate(SubscriptionData subscription, InternalCallContext context);
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
index b4d3899..b6fb2e8 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/RepairEntitlementDao.java
@@ -228,7 +228,7 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
     }
 
     @Override
-    public Subscription getSubscriptionFromId(final SubscriptionFactory factory, final UUID subscriptionId, final InternalTenantContext context) {
+    public Subscription getSubscriptionFromId(final UUID subscriptionId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
@@ -238,17 +238,17 @@ public class RepairEntitlementDao implements EntitlementDao, RepairEntitlementLi
     }
 
     @Override
-    public Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
+    public Subscription getBaseSubscription(final UUID bundleId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
+    public List<Subscription> getSubscriptions(final UUID bundleId, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForAccountAndKey(final SubscriptionFactory factory, final UUID accountId,
+    public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId,
                                                                final String bundleKey, final InternalTenantContext context) {
         throw new EntitlementError(NOT_IMPLEMENTED);
     }
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 0b95f47..bd05062 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
@@ -275,6 +275,10 @@ public abstract class TestApiBase extends EntitlementTestSuiteWithEmbeddedDB imp
                                                                                                    new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSet, null),
                                                                                                    requestedDate == null ? clock.getUTCNow() : requestedDate, callContext);
         assertNotNull(subscription);
+
+
+        //try {Thread.sleep(100000000); } catch (Exception e) {};
+
         assertTrue(testListener.isCompleted(5000));
         return subscription;
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
index db3df23..8052a4f 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestRepairBP.java
@@ -342,7 +342,7 @@ public class TestRepairBP extends TestApiBaseRepair {
 
         assertEquals(dryRunBaseSubscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
         assertEquals(dryRunBaseSubscription.getBundleId(), bundle.getId());
-        assertEquals(dryRunBaseSubscription.getStartDate(), baseSubscription.getStartDate());
+        assertTrue(dryRunBaseSubscription.getStartDate().compareTo(baseSubscription.getStartDate()) == 0);
 
         Plan currentPlan = dryRunBaseSubscription.getCurrentPlan();
         assertNotNull(currentPlan);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
index b73c1e3..fde5edc 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/MockEntitlementDaoMemory.java
@@ -141,10 +141,10 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public Subscription getSubscriptionFromId(final SubscriptionFactory factory, final UUID subscriptionId, final InternalTenantContext context) {
+    public Subscription getSubscriptionFromId(final UUID subscriptionId, final InternalTenantContext context) {
         for (final Subscription cur : subscriptions) {
             if (cur.getId().equals(subscriptionId)) {
-                return buildSubscription(factory, (SubscriptionData) cur, context);
+                return buildSubscription((SubscriptionData) cur, context);
             }
         }
         return null;
@@ -156,11 +156,11 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public List<Subscription> getSubscriptionsForAccountAndKey(final SubscriptionFactory factory, final UUID accountId, final String bundleKey, final InternalTenantContext context) {
+    public List<Subscription> getSubscriptionsForAccountAndKey(final UUID accountId, final String bundleKey, final InternalTenantContext context) {
 
         for (final SubscriptionBundle cur : bundles) {
             if (cur.getExternalKey().equals(bundleKey) && cur.getAccountId().equals(bundleKey)) {
-                return getSubscriptions(factory, cur.getId(), context);
+                return getSubscriptions(cur.getId(), context);
             }
         }
         return Collections.emptyList();
@@ -175,7 +175,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
                 recordFutureNotificationFromTransaction(null, cur.getEffectiveDate(), new EntitlementNotificationKey(cur.getId()), context);
             }
         }
-        final Subscription updatedSubscription = buildSubscription(null, subscription, context);
+        final Subscription updatedSubscription = buildSubscription(subscription, context);
         subscriptions.add(updatedSubscription);
     }
 
@@ -190,11 +190,11 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public List<Subscription> getSubscriptions(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
+    public List<Subscription> getSubscriptions(final UUID bundleId, final InternalTenantContext context) {
         final List<Subscription> results = new ArrayList<Subscription>();
         for (final Subscription cur : subscriptions) {
             if (cur.getBundleId().equals(bundleId)) {
-                results.add(buildSubscription(factory, (SubscriptionData) cur, context));
+                results.add(buildSubscription((SubscriptionData) cur, context));
             }
         }
         return results;
@@ -229,11 +229,11 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     @Override
-    public Subscription getBaseSubscription(final SubscriptionFactory factory, final UUID bundleId, final InternalTenantContext context) {
+    public Subscription getBaseSubscription(final UUID bundleId, final InternalTenantContext context) {
         for (final Subscription cur : subscriptions) {
             if (cur.getBundleId().equals(bundleId) &&
                 cur.getCurrentPlan().getProduct().getCategory() == ProductCategory.BASE) {
-                return buildSubscription(factory, (SubscriptionData) cur, context);
+                return buildSubscription((SubscriptionData) cur, context);
             }
         }
         return null;
@@ -245,16 +245,13 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
         insertEvent(nextPhase, context);
     }
 
-    private Subscription buildSubscription(final SubscriptionFactory factory, final SubscriptionData in, final InternalTenantContext context) {
-        if (factory != null) {
-            return factory.createSubscription(new SubscriptionBuilder(in), getEventsForSubscription(in.getId(), context));
-        } else {
+    private Subscription buildSubscription(final SubscriptionData in, final InternalTenantContext context) {
             final SubscriptionData subscription = new SubscriptionData(new SubscriptionBuilder(in), null, clock);
             if (events.size() > 0) {
                 subscription.rebuildTransitions(getEventsForSubscription(in.getId(), context), catalogService.getFullCatalog());
             }
             return subscription;
-        }
+
     }
 
     @Override
@@ -303,7 +300,7 @@ public class MockEntitlementDaoMemory implements EntitlementDao {
     }
 
     private void cancelNextPhaseEvent(final UUID subscriptionId, final InternalTenantContext context) {
-        final Subscription curSubscription = getSubscriptionFromId(null, subscriptionId, context);
+        final Subscription curSubscription = getSubscriptionFromId(subscriptionId, context);
         if (curSubscription.getCurrentPhase() == null ||
             curSubscription.getCurrentPhase().getDuration().getUnit() == TimeUnit.UNLIMITED) {
             return;