killbill-uncached

Merge branch 'master' of github.com:ning/killbill into killbill-account;

12/7/2011 4:57:47 PM

Changes

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

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

api/src/main/java/com/ning/billing/catalog/api/ICatalog.java 62(+0 -62)

api/src/main/java/com/ning/billing/invoice/api/IInvoiceGenerated.java 30(+0 -30)

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

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

catalog/src/main/java/com/ning/billing/catalog/ICatalogConfiguration.java 26(+0 -26)

entitlement/src/main/java/com/ning/billing/entitlement/api/user/PrivateFields.java 41(+0 -41)

entitlement/src/main/java/com/ning/billing/entitlement/engine/core/IEventNotifier.java 25(+0 -25)

entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/IEntitlementDao.java 71(+0 -71)

entitlement/src/main/java/com/ning/billing/entitlement/events/phase/IPhaseEvent.java 24(+0 -24)

entitlement/src/main/java/com/ning/billing/entitlement/glue/InjectorMagic.java 76(+0 -76)

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

invoice/src/main/java/com/ning/billing/invoice/model/TestConsole.java 145(+0 -145)

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

pom.xml 2(+1 -1)

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

util/src/main/java/com/ning/billing/util/clock/IClock.java 30(+0 -30)

Details

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

diff --git a/account/pom.xml b/account/pom.xml
index 3443aac..6808744 100644
--- a/account/pom.xml
+++ b/account/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.0.16-SNAPSHOT</version>
+        <version>0.0.17-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-account</artifactId>
diff --git a/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java b/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java
index 3d881b6..9737deb 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/AccountBuilder.java
@@ -16,7 +16,7 @@
 
 package com.ning.billing.account.api.user;
 
-import com.ning.billing.account.api.AccountDefault;
+import com.ning.billing.account.api.DefaultAccount;
 import com.ning.billing.catalog.api.Currency;
 
 import java.util.UUID;
@@ -74,7 +74,7 @@ public class AccountBuilder {
         return this;
     }
 
-    public AccountDefault build() {
-        return new AccountDefault(id, externalKey, email, name, firstNameLength, phone, currency, billingCycleDay);
+    public DefaultAccount build() {
+        return new DefaultAccount(id, externalKey, email, name, firstNameLength, phone, currency, billingCycleDay);
     }
 }
diff --git a/account/src/main/java/com/ning/billing/account/api/user/AccountChangeEventDefault.java b/account/src/main/java/com/ning/billing/account/api/user/AccountChangeEventDefault.java
index 2a992f0..b2f6a75 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/AccountChangeEventDefault.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/AccountChangeEventDefault.java
@@ -17,15 +17,15 @@
 package com.ning.billing.account.api.user;
 
 import com.ning.billing.account.api.Account;
-import com.ning.billing.account.api.AccountChangeEvent;
+import com.ning.billing.account.api.AccountChangeNotification;
 import com.ning.billing.account.api.ChangedField;
-import com.ning.billing.account.api.ChangedFieldDefault;
+import com.ning.billing.account.api.DefaultChangedField;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-public class AccountChangeEventDefault implements AccountChangeEvent {
+public class AccountChangeEventDefault implements AccountChangeNotification {
     private final List<ChangedField> changedFields;
     private final UUID id;
 
@@ -53,22 +53,22 @@ public class AccountChangeEventDefault implements AccountChangeEvent {
         List<ChangedField> changedFields = new ArrayList<ChangedField>();
 
         if (!newData.getExternalKey().equals(oldData.getExternalKey())) {
-            changedFields.add(new ChangedFieldDefault("externalKey", newData.getExternalKey(), oldData.getExternalKey()));
+            changedFields.add(new DefaultChangedField("externalKey", newData.getExternalKey(), oldData.getExternalKey()));
         }
         if (!newData.getEmail().equals(oldData.getEmail())) {
-            changedFields.add(new ChangedFieldDefault("email", newData.getEmail(), oldData.getEmail()));
+            changedFields.add(new DefaultChangedField("email", newData.getEmail(), oldData.getEmail()));
         }
         if (!newData.getName().equals(oldData.getName())) {
-            changedFields.add(new ChangedFieldDefault("firstName", newData.getName(), oldData.getName()));
+            changedFields.add(new DefaultChangedField("firstName", newData.getName(), oldData.getName()));
         }
         if (!newData.getPhone().equals(oldData.getPhone())) {
-            changedFields.add(new ChangedFieldDefault("phone", newData.getPhone(), oldData.getPhone()));
+            changedFields.add(new DefaultChangedField("phone", newData.getPhone(), oldData.getPhone()));
         }
         if (!newData.getCurrency().equals(oldData.getCurrency())) {
-            changedFields.add(new ChangedFieldDefault("currency", newData.getCurrency().toString(), oldData.getCurrency().toString()));
+            changedFields.add(new DefaultChangedField("currency", newData.getCurrency().toString(), oldData.getCurrency().toString()));
         }
         if (newData.getBillCycleDay() != oldData.getBillCycleDay()) {
-            changedFields.add(new ChangedFieldDefault("billCycleDay", Integer.toString(newData.getBillCycleDay()),
+            changedFields.add(new DefaultChangedField("billCycleDay", Integer.toString(newData.getBillCycleDay()),
                                                                Integer.toString(oldData.getBillCycleDay())));
         }
 
diff --git a/account/src/main/java/com/ning/billing/account/api/user/AccountCreationEventDefault.java b/account/src/main/java/com/ning/billing/account/api/user/AccountCreationEventDefault.java
index 7dc8baf..50bee77 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/AccountCreationEventDefault.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/AccountCreationEventDefault.java
@@ -17,12 +17,12 @@
 package com.ning.billing.account.api.user;
 
 import com.ning.billing.account.api.Account;
-import com.ning.billing.account.api.AccountCreationEvent;
+import com.ning.billing.account.api.AccountCreationNotification;
 import com.ning.billing.account.api.AccountData;
 
 import java.util.UUID;
 
-public class AccountCreationEventDefault implements AccountCreationEvent {
+public class AccountCreationEventDefault implements AccountCreationNotification {
     private final UUID id;
     private final AccountData data;
 
diff --git a/account/src/main/java/com/ning/billing/account/api/user/AccountUserApi.java b/account/src/main/java/com/ning/billing/account/api/user/AccountUserApi.java
index fa07547..bec3e32 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/AccountUserApi.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/AccountUserApi.java
@@ -19,7 +19,7 @@ package com.ning.billing.account.api.user;
 import com.google.inject.Inject;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountData;
-import com.ning.billing.account.api.AccountDefault;
+import com.ning.billing.account.api.DefaultAccount;
 import com.ning.billing.account.dao.AccountDao;
 
 import java.util.List;
@@ -35,7 +35,7 @@ public class AccountUserApi implements com.ning.billing.account.api.AccountUserA
 
     @Override
     public Account createAccount(AccountData data) {
-        Account account = new AccountDefault(data);
+        Account account = new DefaultAccount(data);
         dao.save(account);
         return account;
     }
diff --git a/account/src/main/java/com/ning/billing/account/core/Engine.java b/account/src/main/java/com/ning/billing/account/core/Engine.java
index 4a750c9..f95605b 100644
--- a/account/src/main/java/com/ning/billing/account/core/Engine.java
+++ b/account/src/main/java/com/ning/billing/account/core/Engine.java
@@ -18,8 +18,8 @@ package com.ning.billing.account.core;
 
 import com.ning.billing.account.api.AccountService;
 import com.ning.billing.account.api.AccountUserApi;
-import com.ning.billing.lifecycle.LyfecycleHandlerType;
-import com.ning.billing.util.eventbus.IEventBus;
+import com.ning.billing.lifecycle.LifecycleHandlerType;
+import com.ning.billing.util.eventbus.EventBus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -29,24 +29,24 @@ public class Engine implements AccountService {
     private final static Logger log = LoggerFactory.getLogger(Engine.class);
 
     private static final String ACCOUNT_SERVICE_NAME = "account-service";
-    private final IEventBus eventBus;
+    private final EventBus eventBus;
     private final AccountUserApi userApi;
 
     @Inject
-    public Engine(IEventBus eventBus, AccountUserApi userApi) {
+    public Engine(EventBus eventBus, AccountUserApi userApi) {
         this.eventBus = eventBus;
         this.userApi = userApi;
     }
 
-    @LyfecycleHandlerType(LyfecycleHandlerType.LyfecycleLevel.INIT_SERVICE)
+    @LifecycleHandlerType(LifecycleHandlerType.LifecycleLevel.INIT_SERVICE)
     public void initialize() {
     }
 
-    @LyfecycleHandlerType(LyfecycleHandlerType.LyfecycleLevel.START_SERVICE)
+    @LifecycleHandlerType(LifecycleHandlerType.LifecycleLevel.START_SERVICE)
     public void start() {
     }
 
-    @LyfecycleHandlerType(LyfecycleHandlerType.LyfecycleLevel.STOP_SERVICE)
+    @LifecycleHandlerType(LifecycleHandlerType.LifecycleLevel.STOP_SERVICE)
     public void stop() {
     }
 
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
index f571405..831dab2 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
@@ -17,7 +17,7 @@
 package com.ning.billing.account.dao;
 
 import com.ning.billing.account.api.Account;
-import com.ning.billing.account.api.AccountDefault;
+import com.ning.billing.account.api.DefaultAccount;
 import com.ning.billing.account.api.user.AccountBuilder;
 import com.ning.billing.catalog.api.Currency;
 import org.skife.jdbi.v2.SQLStatement;
@@ -67,8 +67,8 @@ public interface AccountDao extends EntityDao<Account> {
     public @interface AccountBinder {
         public static class AccountBinderFactory implements BinderFactory {
             public Binder build(Annotation annotation) {
-                return new Binder<AccountBinder, AccountDefault>() {
-                    public void bind(SQLStatement q, AccountBinder bind, AccountDefault account) {
+                return new Binder<AccountBinder, DefaultAccount>() {
+                    public void bind(SQLStatement q, AccountBinder bind, DefaultAccount account) {
                         q.bind("id", account.getId().toString());
                         q.bind("externalKey", account.getExternalKey());
                         q.bind("email", account.getEmail());
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountDaoWrapper.java b/account/src/main/java/com/ning/billing/account/dao/AccountDaoWrapper.java
index ae7f059..41f4573 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountDaoWrapper.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountDaoWrapper.java
@@ -20,7 +20,7 @@ import com.google.inject.Inject;
 import com.ning.billing.account.api.*;
 import com.ning.billing.account.api.user.AccountChangeEventDefault;
 import com.ning.billing.account.api.user.AccountCreationEventDefault;
-import com.ning.billing.util.eventbus.IEventBus;
+import com.ning.billing.util.eventbus.EventBus;
 import org.skife.jdbi.v2.Handle;
 import org.skife.jdbi.v2.IDBI;
 import org.skife.jdbi.v2.TransactionCallback;
@@ -32,10 +32,10 @@ public class AccountDaoWrapper implements AccountDao {
     private final AccountDao accountDao;
     private final FieldStoreDao fieldStoreDao;
     private final IDBI dbi; // needed for transaction support
-    private final IEventBus eventBus;
+    private final EventBus eventBus;
 
     @Inject
-    public AccountDaoWrapper(IDBI dbi, IEventBus eventBus) {
+    public AccountDaoWrapper(IDBI dbi, EventBus eventBus) {
         this.dbi = dbi;
         this.eventBus = eventBus;
         this.accountDao = dbi.onDemand(AccountDao.class);
@@ -61,7 +61,7 @@ public class AccountDaoWrapper implements AccountDao {
     }
 
     private void loadFields(Account account) {
-        List<CustomField> fields = fieldStoreDao.load(account.getId().toString(), AccountDefault.OBJECT_TYPE);
+        List<CustomField> fields = fieldStoreDao.load(account.getId().toString(), DefaultAccount.OBJECT_TYPE);
         account.getFields().clear();
         if (fields != null) {
             for (CustomField field : fields) {
@@ -83,7 +83,7 @@ public class AccountDaoWrapper implements AccountDao {
     @Override
     public void save(final Account account) {
         final String accountId = account.getId().toString();
-        final String objectType = AccountDefault.OBJECT_TYPE;
+        final String objectType = DefaultAccount.OBJECT_TYPE;
 
         dbi.inTransaction(new TransactionCallback<Void>() {
             @Override
@@ -100,10 +100,10 @@ public class AccountDaoWrapper implements AccountDao {
                     fieldStoreDao.save(accountId, objectType, fieldStore.getFieldList());
 
                     if (currentAccount == null) {
-                        AccountCreationEvent creationEvent = new AccountCreationEventDefault(account);
+                        AccountCreationNotification creationEvent = new AccountCreationEventDefault(account);
                         eventBus.post(creationEvent);
                     } else {
-                        AccountChangeEvent changeEvent = new AccountChangeEventDefault(account.getId(), currentAccount, account);
+                        AccountChangeNotification changeEvent = new AccountChangeEventDefault(account.getId(), currentAccount, account);
                         if (changeEvent.hasChanges()) {
                             eventBus.post(changeEvent);
                         }
diff --git a/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java b/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
index 3db0cac..95b4ade 100644
--- a/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
+++ b/account/src/test/java/com/ning/billing/account/dao/AccountDaoTestBase.java
@@ -20,8 +20,8 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
 import com.ning.billing.account.glue.AccountModuleMock;
+import com.ning.billing.util.eventbus.DefaultEventBusService;
 import com.ning.billing.util.eventbus.EventBusService;
-import com.ning.billing.util.eventbus.IEventBusService;
 import org.apache.commons.io.IOUtils;
 import org.testng.annotations.BeforeClass;
 
@@ -49,8 +49,8 @@ public abstract class AccountDaoTestBase {
             accountDao = injector.getInstance(AccountDao.class);
             accountDao.test();
 
-            IEventBusService busService = injector.getInstance(IEventBusService.class);
-            ((EventBusService) busService).startBus();
+            EventBusService busService = injector.getInstance(EventBusService.class);
+            ((DefaultEventBusService) busService).startBus();
         }
         catch (Throwable t) {
             fail(t.toString());
diff --git a/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
index 3ee07df..88e8c77 100644
--- a/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/TestSimpleAccountDao.java
@@ -17,7 +17,7 @@
 package com.ning.billing.account.dao;
 
 import com.ning.billing.account.api.Account;
-import com.ning.billing.account.api.AccountDefault;
+import com.ning.billing.account.api.DefaultAccount;
 import com.ning.billing.account.api.user.AccountBuilder;
 import com.ning.billing.catalog.api.Currency;
 import org.testng.annotations.Test;
@@ -33,7 +33,7 @@ public class TestSimpleAccountDao extends AccountDaoTestBase {
     private final String firstName = "Wesley";
     private final String email = "me@me.com";
 
-    private AccountDefault createTestAccount() {
+    private DefaultAccount createTestAccount() {
         String thisKey = key + UUID.randomUUID().toString();
         String lastName = UUID.randomUUID().toString();
         String thisEmail = email + " " + UUID.randomUUID();
diff --git a/analytics/pom.xml b/analytics/pom.xml
index 498b3c0..5bd608a 100644
--- a/analytics/pom.xml
+++ b/analytics/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.0.16-SNAPSHOT</version>
+        <version>0.0.17-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-analytics</artifactId>
diff --git a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
index 415a002..ba7a707 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/AnalyticsListener.java
@@ -18,7 +18,7 @@ package com.ning.billing.analytics;
 
 import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
-import com.ning.billing.entitlement.api.user.ISubscriptionTransition;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
 
 public class AnalyticsListener
 {
@@ -33,7 +33,7 @@ public class AnalyticsListener
     }
 
     @Subscribe
-    public void handleSubscriptionTransitionChange(final ISubscriptionTransition event)
+    public void handleSubscriptionTransitionChange(final SubscriptionTransition event)
     {
         switch (event.getTransitionType()) {
             case CREATE:
diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/AnalyticsService.java b/analytics/src/main/java/com/ning/billing/analytics/api/AnalyticsService.java
index 216ff9b..a08e3ab 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/api/AnalyticsService.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/AnalyticsService.java
@@ -18,8 +18,8 @@ package com.ning.billing.analytics.api;
 
 import com.google.inject.Inject;
 import com.ning.billing.analytics.AnalyticsListener;
-import com.ning.billing.lifecycle.LyfecycleHandlerType;
-import com.ning.billing.util.eventbus.IEventBus;
+import com.ning.billing.lifecycle.LifecycleHandlerType;
+import com.ning.billing.util.eventbus.EventBus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -30,10 +30,10 @@ public class AnalyticsService implements IAnalyticsService
     private static final String ANALYTICS_SERVICE = "analytics-service";
 
     private final AnalyticsListener listener;
-    private final IEventBus eventBus;
+    private final EventBus eventBus;
 
     @Inject
-    public AnalyticsService(final AnalyticsListener listener, final IEventBus eventBus)
+    public AnalyticsService(final AnalyticsListener listener, final EventBus eventBus)
     {
         this.listener = listener;
         this.eventBus = eventBus;
@@ -45,13 +45,13 @@ public class AnalyticsService implements IAnalyticsService
         return ANALYTICS_SERVICE;
     }
 
-    @LyfecycleHandlerType(LyfecycleHandlerType.LyfecycleLevel.REGISTER_EVENTS)
+    @LifecycleHandlerType(LifecycleHandlerType.LifecycleLevel.REGISTER_EVENTS)
     public void registerForNotifications()
     {
         try {
             eventBus.register(listener);
         }
-        catch (IEventBus.EventBusException e) {
+        catch (EventBus.EventBusException e) {
             log.error("Unable to register to the EventBus!", e);
         }
     }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java
index ae73e4d..baacad8 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java
@@ -18,7 +18,7 @@ package com.ning.billing.analytics;
 
 import com.ning.billing.analytics.utils.Rounder;
 import com.ning.billing.catalog.api.*;
-import com.ning.billing.entitlement.api.user.ISubscription;
+import com.ning.billing.entitlement.api.user.Subscription;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -27,7 +27,7 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.UUID;
 
-import static com.ning.billing.entitlement.api.user.ISubscription.SubscriptionState;
+import static com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 
 /**
  * Describe a subscription for Analytics purposes
@@ -82,18 +82,18 @@ public class BusinessSubscription
      * @param subscription Subscription to use as a model
      * @param currency     Account currency
      */
-    BusinessSubscription(final ISubscription subscription, final Currency currency)
+    BusinessSubscription(final Subscription subscription, final Currency currency)
     {
         this(subscription.getCurrentPriceList(), subscription.getCurrentPlan(), subscription.getCurrentPhase(), currency, subscription.getStartDate(), subscription.getState(), subscription.getId(), subscription.getBundleId());
     }
 
-    public BusinessSubscription(final String priceList, final IPlan currentPlan, final IPlanPhase currentPhase, final Currency currency, final DateTime startDate, final SubscriptionState state, final UUID subscriptionId, final UUID bundleId)
+    public BusinessSubscription(final String priceList, final Plan currentPlan, final PlanPhase currentPhase, final Currency currency, final DateTime startDate, final SubscriptionState state, final UUID subscriptionId, final UUID bundleId)
     {
         this.priceList = priceList;
 
         // Record plan information
         if (currentPlan != null && currentPlan.getProduct() != null) {
-            final IProduct product = currentPlan.getProduct();
+            final Product product = currentPlan.getProduct();
             productName = product.getName();
             productCategory = product.getCategory();
             // TODO - we should keep the product type
@@ -124,7 +124,14 @@ public class BusinessSubscription
             }
 
             if (currentPhase.getRecurringPrice() != null) {
-                price = currentPhase.getRecurringPrice().getPrice(USD);
+            	//TODO check if this is the right way to handle exception
+            	BigDecimal tmpPrice = null;
+                try {
+                	tmpPrice = currentPhase.getRecurringPrice().getPrice(USD);
+				} catch (CatalogApiException e) {
+					tmpPrice = new BigDecimal(0);
+				}
+                price = tmpPrice;
                 mrr = getMrrFromISubscription(currentPhase.getDuration(), price);
             }
             else {
@@ -233,7 +240,7 @@ public class BusinessSubscription
         return subscriptionId;
     }
 
-    static BigDecimal getMrrFromISubscription(final IDuration duration, final BigDecimal price)
+    static BigDecimal getMrrFromISubscription(final Duration duration, final BigDecimal price)
     {
         if (duration == null || duration.getUnit() == null || duration.getNumber() == 0) {
             return BigDecimal.ZERO;
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionEvent.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionEvent.java
index 865d8e7..5b6b078 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionEvent.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionEvent.java
@@ -16,11 +16,11 @@
 
 package com.ning.billing.analytics;
 
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.catalog.api.IProduct;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
 
-import static com.ning.billing.entitlement.api.user.ISubscription.SubscriptionState;
+import static com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 
 /**
  * Describe an event associated with a transition between two BusinessSubscription
@@ -79,32 +79,32 @@ public class BusinessSubscriptionEvent
         return eventType;
     }
 
-    public static BusinessSubscriptionEvent subscriptionCreated(final IPlan plan)
+    public static BusinessSubscriptionEvent subscriptionCreated(final Plan plan)
     {
         return eventFromType(EventType.ADD, plan);
     }
 
-    public static BusinessSubscriptionEvent subscriptionCancelled(final IPlan plan)
+    public static BusinessSubscriptionEvent subscriptionCancelled(final Plan plan)
     {
         return eventFromType(EventType.CANCEL, plan);
     }
 
-    public static BusinessSubscriptionEvent subscriptionChanged(final IPlan plan)
+    public static BusinessSubscriptionEvent subscriptionChanged(final Plan plan)
     {
         return eventFromType(EventType.CHANGE, plan);
     }
 
-    public static BusinessSubscriptionEvent subscriptionPaused(final IPlan plan)
+    public static BusinessSubscriptionEvent subscriptionPaused(final Plan plan)
     {
         return eventFromType(EventType.PAUSE, plan);
     }
 
-    public static BusinessSubscriptionEvent subscriptionResumed(final IPlan plan)
+    public static BusinessSubscriptionEvent subscriptionResumed(final Plan plan)
     {
         return eventFromType(EventType.RESUME, plan);
     }
 
-    public static BusinessSubscriptionEvent subscriptionPhaseChanged(final IPlan plan, final SubscriptionState state)
+    public static BusinessSubscriptionEvent subscriptionPhaseChanged(final Plan plan, final SubscriptionState state)
     {
         if (state != null && state.equals(SubscriptionState.CANCELLED)) {
             return eventFromType(EventType.SYSTEM_CANCEL, plan);
@@ -114,16 +114,16 @@ public class BusinessSubscriptionEvent
         }
     }
 
-    private static BusinessSubscriptionEvent eventFromType(final EventType eventType, final IPlan plan)
+    private static BusinessSubscriptionEvent eventFromType(final EventType eventType, final Plan plan)
     {
         final ProductCategory category = getTypeFromSubscription(plan);
         return new BusinessSubscriptionEvent(eventType, category);
     }
 
-    private static ProductCategory getTypeFromSubscription(final IPlan plan)
+    private static ProductCategory getTypeFromSubscription(final Plan plan)
     {
         if (plan != null && plan.getProduct() != null) {
-            final IProduct product = plan.getProduct();
+            final Product product = plan.getProduct();
             if (product.getCatalogName() != null && product.getCategory() != null) {
                 return product.getCategory();
             }
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
index 5125e7e..33b8f4d 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscriptionTransitionRecorder.java
@@ -21,9 +21,9 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionDao;
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.entitlement.api.user.IEntitlementUserApi;
-import com.ning.billing.entitlement.api.user.ISubscriptionBundle;
-import com.ning.billing.entitlement.api.user.ISubscriptionTransition;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,61 +35,61 @@ public class BusinessSubscriptionTransitionRecorder
     private static final Logger log = LoggerFactory.getLogger(BusinessSubscriptionTransitionRecorder.class);
 
     private final BusinessSubscriptionTransitionDao dao;
-    private final IEntitlementUserApi entitlementApi;
+    private final EntitlementUserApi entitlementApi;
     private final AccountUserApi accountApi;
 
     @Inject
-    public BusinessSubscriptionTransitionRecorder(final BusinessSubscriptionTransitionDao dao, final IEntitlementUserApi entitlementApi, final AccountUserApi accountApi)
+    public BusinessSubscriptionTransitionRecorder(final BusinessSubscriptionTransitionDao dao, final EntitlementUserApi entitlementApi, final AccountUserApi accountApi)
     {
         this.dao = dao;
         this.entitlementApi = entitlementApi;
         this.accountApi = accountApi;
     }
 
-    public void subscriptionCreated(final ISubscriptionTransition created)
+    public void subscriptionCreated(final SubscriptionTransition created)
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCreated(created.getNextPlan());
         recordTransition(event, created);
     }
 
-    public void subscriptionCancelled(final ISubscriptionTransition cancelled)
+    public void subscriptionCancelled(final SubscriptionTransition cancelled)
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCancelled(cancelled.getNextPlan());
         recordTransition(event, cancelled);
     }
 
-    public void subscriptionChanged(final ISubscriptionTransition changed)
+    public void subscriptionChanged(final SubscriptionTransition changed)
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionChanged(changed.getNextPlan());
         recordTransition(event, changed);
     }
 
-    public void subscriptionPaused(final ISubscriptionTransition paused)
+    public void subscriptionPaused(final SubscriptionTransition paused)
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionPaused(paused.getNextPlan());
         recordTransition(event, paused);
     }
 
-    public void subscriptionResumed(final ISubscriptionTransition resumed)
+    public void subscriptionResumed(final SubscriptionTransition resumed)
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionResumed(resumed.getNextPlan());
         recordTransition(event, resumed);
     }
 
-    public void subscriptionPhaseChanged(final ISubscriptionTransition phaseChanged)
+    public void subscriptionPhaseChanged(final SubscriptionTransition phaseChanged)
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionPhaseChanged(phaseChanged.getNextPlan(), phaseChanged.getNextState());
         recordTransition(event, phaseChanged);
     }
 
-    public void recordTransition(final BusinessSubscriptionEvent event, final ISubscriptionTransition transition)
+    public void recordTransition(final BusinessSubscriptionEvent event, final SubscriptionTransition transition)
     {
         Currency currency = null;
         String transitionKey = null;
         String accountKey = null;
 
         // Retrieve key and currency via the bundle
-        final ISubscriptionBundle bundle = entitlementApi.getBundleFromId(transition.getBundleId());
+        final SubscriptionBundle bundle = entitlementApi.getBundleFromId(transition.getBundleId());
         if (bundle != null) {
             transitionKey = bundle.getKey();
 
diff --git a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
index fb5e641..a31d104 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/dao/BusinessSubscriptionTransitionMapper.java
@@ -30,7 +30,7 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.UUID;
 
-import static com.ning.billing.entitlement.api.user.ISubscription.SubscriptionState;
+import static com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
 
 public class BusinessSubscriptionTransitionMapper implements ResultSetMapper<BusinessSubscriptionTransition>
 {
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
index 9734ada..04b97d1 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
@@ -24,9 +24,9 @@ import com.ning.billing.analytics.dao.BusinessSubscriptionTransitionDao;
 import com.ning.billing.catalog.api.*;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.entitlement.api.user.*;
-import com.ning.billing.entitlement.events.IEvent;
+import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
-import com.ning.billing.util.eventbus.IEventBus;
+import com.ning.billing.util.eventbus.EventBus;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
@@ -50,13 +50,13 @@ public class TestAnalyticsService
     private AccountUserApi accountApi;
 
     @Inject
-    private IEntitlementUserApi entitlementApi;
+    private EntitlementUserApi entitlementApi;
 
     @Inject
     private AnalyticsService service;
 
     @Inject
-    private IEventBus bus;
+    private EventBus bus;
 
     @Inject
     private BusinessSubscriptionTransitionDao dao;
@@ -64,11 +64,11 @@ public class TestAnalyticsService
     @Inject
     private MysqlTestingHelper helper;
 
-    private ISubscriptionTransition transition;
+    private SubscriptionTransition transition;
     private BusinessSubscriptionTransition expectedTransition;
 
     @BeforeClass(alwaysRun = true)
-    public void Setup() throws IOException, ClassNotFoundException, SQLException, EntitlementUserApiException
+    public void startMysql() throws IOException, ClassNotFoundException, SQLException, EntitlementUserApiException
     {
         final String analyticsDdl = IOUtils.toString(BusinessSubscriptionTransitionDao.class.getResourceAsStream("/com/ning/billing/analytics/ddl.sql"));
         // For bundles
@@ -80,43 +80,28 @@ public class TestAnalyticsService
         helper.initDb(accountDdl);
         helper.initDb(entitlementDdl);
 
-        bus.start();
-    }
-
-    @AfterClass(alwaysRun = true)
-    public void stopMysql()
-    {
-        helper.stopMysql();
-    }
-
-    @Test(groups = "slow")
-    public void testRegisterForNotifications() throws Exception
-    {
-        // Make sure the service has been instantiated
-        Assert.assertEquals(service.getName(), "analytics-service");
-
-         // We need a bundle to retrieve the event key
+        // We need a bundle to retrieve the event key
         final MockAccount account = new MockAccount(UUID.randomUUID(), ACCOUNT_KEY, Currency.USD);
         final Account storedAccount = accountApi.createAccount(account);
-        final ISubscriptionBundle bundle = entitlementApi.createBundleForAccount(storedAccount, KEY);
+        final SubscriptionBundle bundle = entitlementApi.createBundleForAccount(storedAccount, KEY);
 
         // Verify we correctly initialized the account subsystem
         Assert.assertNotNull(bundle);
         Assert.assertEquals(bundle.getKey(), KEY);
 
         // Create a subscription transition
-        final IProduct product = new MockProduct("platinum", "subscription", ProductCategory.BASE);
-        final IPlan plan = new MockPlan("platinum-monthly", product);
-        final IPlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
+        final Product product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
+        final Plan plan = new MockPlan("platinum-monthly", product);
+        final PlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
         final UUID subscriptionId = UUID.randomUUID();
         final DateTime effectiveTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedTransitionTime = new DateTime(DateTimeZone.UTC);
         final String priceList = "something";
-        transition = new SubscriptionTransition(
+        transition = new SubscriptionTransitionData(
             UUID.randomUUID(),
             subscriptionId,
             bundle.getId(),
-            IEvent.EventType.API_USER,
+            EntitlementEvent.EventType.API_USER,
             ApiEventType.CREATE,
             requestedTransitionTime,
             effectiveTransitionTime,
@@ -124,7 +109,7 @@ public class TestAnalyticsService
             null,
             null,
             null,
-            ISubscription.SubscriptionState.ACTIVE,
+            Subscription.SubscriptionState.ACTIVE,
             plan,
             phase,
             priceList
@@ -135,11 +120,25 @@ public class TestAnalyticsService
             requestedTransitionTime,
             BusinessSubscriptionEvent.subscriptionCreated(plan),
             null,
-            new BusinessSubscription(priceList, plan, phase, Currency.USD, effectiveTransitionTime, ISubscription.SubscriptionState.ACTIVE, subscriptionId, bundle.getId())
+            new BusinessSubscription(priceList, plan, phase, null, effectiveTransitionTime, Subscription.SubscriptionState.ACTIVE, subscriptionId, bundle.getId())
         );
+    }
+
+    @AfterClass(alwaysRun = true)
+    public void stopMysql()
+    {
+        helper.stopMysql();
+    }
+
+    @Test(groups = "slow")
+    public void testRegisterForNotifications() throws Exception
+    {
+        // Make sure the service has been instantiated
+        Assert.assertEquals(service.getName(), "analytics-service");
 
-        // Make sure we can register our service
+        // Test the bus and make sure we can register our service
         try {
+            bus.start();
             service.registerForNotifications();
         }
         catch (Throwable t) {
diff --git a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
index 9fe916e..368b8c1 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/dao/TestAnalyticsDao.java
@@ -20,7 +20,7 @@ import com.ning.billing.analytics.*;
 import com.ning.billing.analytics.utils.Rounder;
 import com.ning.billing.catalog.api.*;
 import com.ning.billing.dbi.MysqlTestingHelper;
-import com.ning.billing.entitlement.api.user.ISubscription;
+import com.ning.billing.entitlement.api.user.Subscription;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
@@ -44,9 +44,9 @@ public class TestAnalyticsDao
     private static final String ACCOUNT_KEY = "pierre-143343-vcc";
 
     private final MysqlTestingHelper helper = new MysqlTestingHelper();
-    private final IProduct product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
-    private final IPlan plan = new MockPlan("platinum-monthly", product);
-    private final IPlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
+    private final Product product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
+    private final Plan plan = new MockPlan("platinum-monthly", product);
+    private final PlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
 
     private BusinessSubscriptionTransitionDao businessSubscriptionTransitionDao;
     private BusinessSubscriptionTransition transition;
@@ -67,8 +67,8 @@ public class TestAnalyticsDao
 
     private void setupBusinessSubscriptionTransition()
     {
-        final BusinessSubscription prevSubscription = new BusinessSubscription(null, plan, phase, Currency.USD, new DateTime(DateTimeZone.UTC), ISubscription.SubscriptionState.ACTIVE, UUID.randomUUID(), UUID.randomUUID());
-        final BusinessSubscription nextSubscription = new BusinessSubscription(null, plan, phase, Currency.USD, new DateTime(DateTimeZone.UTC), ISubscription.SubscriptionState.CANCELLED, UUID.randomUUID(), UUID.randomUUID());
+        final BusinessSubscription prevSubscription = new BusinessSubscription(null, plan, phase, Currency.USD, new DateTime(DateTimeZone.UTC), Subscription.SubscriptionState.ACTIVE, UUID.randomUUID(), UUID.randomUUID());
+        final BusinessSubscription nextSubscription = new BusinessSubscription(null, plan, phase, Currency.USD, new DateTime(DateTimeZone.UTC), Subscription.SubscriptionState.CANCELLED, UUID.randomUUID(), UUID.randomUUID());
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCancelled(plan);
         final DateTime requestedTimestamp = new DateTime(DateTimeZone.UTC);
 
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
index bfcfea8..56c5ce0 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockAccount.java
@@ -17,7 +17,7 @@
 package com.ning.billing.analytics;
 
 import com.ning.billing.account.api.Account;
-import com.ning.billing.account.api.AccountDefault;
+import com.ning.billing.account.api.DefaultAccount;
 import com.ning.billing.account.api.FieldStore;
 import com.ning.billing.catalog.api.Currency;
 import sun.reflect.generics.reflectiveObjects.NotImplementedException;
@@ -105,6 +105,6 @@ public class MockAccount implements Account
 
     @Override
     public String getObjectName() {
-        return AccountDefault.OBJECT_TYPE;
+        return DefaultAccount.OBJECT_TYPE;
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java b/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java
index 7eb191e..2012995 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockDuration.java
@@ -16,14 +16,14 @@
 
 package com.ning.billing.analytics;
 
-import com.ning.billing.catalog.api.IDuration;
+import com.ning.billing.catalog.api.Duration;
 import com.ning.billing.catalog.api.TimeUnit;
 
 public class MockDuration
 {
-    public static IDuration MONHTLY()
+    public static Duration MONHTLY()
     {
-        return new IDuration()
+        return new Duration()
         {
             @Override
             public TimeUnit getUnit()
@@ -39,9 +39,9 @@ public class MockDuration
         };
     }
 
-    public static IDuration YEARLY()
+    public static Duration YEARLY()
     {
-        return new IDuration()
+        return new Duration()
         {
             @Override
             public TimeUnit getUnit()
@@ -57,9 +57,9 @@ public class MockDuration
         };
     }
 
-    public static IDuration UNLIMITED()
+    public static Duration UNLIMITED()
     {
-        return new IDuration()
+        return new Duration()
         {
             @Override
             public TimeUnit getUnit()
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockIEntitlementUserApi.java b/analytics/src/test/java/com/ning/billing/analytics/MockIEntitlementUserApi.java
index 3565296..475353d 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockIEntitlementUserApi.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockIEntitlementUserApi.java
@@ -18,10 +18,11 @@ package com.ning.billing.analytics;
 
 import com.ning.billing.account.api.Account;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
-import com.ning.billing.entitlement.api.user.IEntitlementUserApi;
-import com.ning.billing.entitlement.api.user.ISubscription;
-import com.ning.billing.entitlement.api.user.ISubscriptionBundle;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import org.joda.time.DateTime;
 
 import java.util.HashMap;
@@ -29,7 +30,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
-public class MockIEntitlementUserApi implements IEntitlementUserApi
+public class MockIEntitlementUserApi implements EntitlementUserApi
 {
     private final Map<UUID, String> subscriptionBundles = new HashMap<UUID, String>();
 
@@ -39,14 +40,14 @@ public class MockIEntitlementUserApi implements IEntitlementUserApi
     }
 
     @Override
-    public ISubscriptionBundle getBundleFromId(final UUID id)
+    public SubscriptionBundle getBundleFromId(final UUID id)
     {
         final String key = subscriptionBundles.get(id);
         if (key == null) {
             return null;
         }
 
-        return new ISubscriptionBundle()
+        return new SubscriptionBundle()
         {
             @Override
             public UUID getAccountId()
@@ -71,53 +72,42 @@ public class MockIEntitlementUserApi implements IEntitlementUserApi
             {
                 return key;
             }
-
-            @Override
-            public void setPrivate(final String name, final String value)
-            {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public String getPrivate(final String name)
-            {
-                throw new UnsupportedOperationException();
-            }
         };
     }
 
     @Override
-    public ISubscription getSubscriptionFromId(final UUID id)
+    public Subscription getSubscriptionFromId(final UUID id)
     {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<ISubscriptionBundle> getBundlesForAccount(final UUID accountId)
+    public List<SubscriptionBundle> getBundlesForAccount(final UUID accountId)
     {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public List<ISubscription> getSubscriptionsForBundle(final UUID bundleId)
+    public List<Subscription> getSubscriptionsForBundle(final UUID bundleId)
     {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public ISubscriptionBundle createBundleForAccount(final Account account, final String bundleKey) throws EntitlementUserApiException
+    public SubscriptionBundle createBundleForAccount(final Account account, final String bundleKey) throws EntitlementUserApiException
     {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public ISubscription createSubscription(final UUID bundleId, final String productName, final BillingPeriod term, final String planSet, final DateTime requestedDate) throws EntitlementUserApiException
-    {
+    public List<Subscription> getSubscriptionsForKey(String bundleKey) {
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public List<ISubscription> getSubscriptionsForKey(String bundleKey) {
-        throw new UnsupportedOperationException();
-    }
+	@Override
+	public Subscription createSubscription(UUID bundleId, String productName,
+			BillingPeriod term, String priceList, PhaseType initialPhase,
+			DateTime requestedDate) throws EntitlementUserApiException {
+		throw new UnsupportedOperationException();
+	}
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockPhase.java b/analytics/src/test/java/com/ning/billing/analytics/MockPhase.java
index 10d1256..7eb9b44 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockPhase.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockPhase.java
@@ -21,14 +21,14 @@ import com.ning.billing.catalog.api.*;
 import java.math.BigDecimal;
 import java.util.Date;
 
-public class MockPhase implements IPlanPhase
+public class MockPhase implements PlanPhase
 {
     private final PhaseType cohort;
-    private final IPlan plan;
-    private final IDuration duration;
+    private final Plan plan;
+    private final Duration duration;
     private final double price;
 
-    public MockPhase(final PhaseType cohort, final IPlan plan, final IDuration duration, final double price)
+    public MockPhase(final PhaseType cohort, final Plan plan, final Duration duration, final double price)
     {
         this.cohort = cohort;
         this.plan = plan;
@@ -37,12 +37,12 @@ public class MockPhase implements IPlanPhase
     }
 
     @Override
-    public IInternationalPrice getRecurringPrice()
+    public InternationalPrice getRecurringPrice()
     {
-        return new IInternationalPrice()
+        return new InternationalPrice()
         {
             @Override
-            public IPrice[] getPrices()
+            public Price[] getPrices()
             {
                 throw new UnsupportedOperationException();
             }
@@ -62,12 +62,12 @@ public class MockPhase implements IPlanPhase
     }
 
     @Override
-    public IInternationalPrice getFixedPrice()
+    public InternationalPrice getFixedPrice()
     {
-        return new IInternationalPrice()
+        return new InternationalPrice()
         {
             @Override
-            public IPrice[] getPrices()
+            public Price[] getPrices()
             {
                 throw new UnsupportedOperationException();
             }
@@ -104,13 +104,13 @@ public class MockPhase implements IPlanPhase
     }
 
     @Override
-    public IPlan getPlan()
+    public Plan getPlan()
     {
         return plan;
     }
 
     @Override
-    public IDuration getDuration()
+    public Duration getDuration()
     {
         return duration;
     }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockPlan.java b/analytics/src/test/java/com/ning/billing/analytics/MockPlan.java
index a2baa37..0e0809c 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockPlan.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockPlan.java
@@ -16,34 +16,32 @@
 
 package com.ning.billing.analytics;
 
-import com.ning.billing.catalog.api.BillingAlignment;
 import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.catalog.api.IPlanPhase;
-import com.ning.billing.catalog.api.IProduct;
-import com.ning.billing.catalog.api.PlanAlignmentChange;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.catalog.api.Product;
 
 import java.util.Iterator;
 
-public class MockPlan implements IPlan
+public class MockPlan implements Plan
 {
     private final String name;
-    private final IProduct product;
+    private final Product product;
 
-    public MockPlan(final String name, final IProduct product)
+    public MockPlan(final String name, final Product product)
     {
         this.name = name;
         this.product = product;
     }
 
     @Override
-    public IPlanPhase[] getInitialPhases()
+    public PlanPhase[] getInitialPhases()
     {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public IProduct getProduct()
+    public Product getProduct()
     {
         return product;
     }
@@ -55,13 +53,13 @@ public class MockPlan implements IPlan
     }
 
     @Override
-    public Iterator<IPlanPhase> getInitialPhaseIterator()
+    public Iterator<PlanPhase> getInitialPhaseIterator()
     {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public IPlanPhase getFinalPhase()
+    public PlanPhase getFinalPhase()
     {
         throw new UnsupportedOperationException();
     }
@@ -77,4 +75,9 @@ public class MockPlan implements IPlan
     {
         throw new UnsupportedOperationException();
     }
+
+	@Override
+	public PlanPhase[] getAllPhases() {
+		 throw new UnsupportedOperationException();
+	}
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockProduct.java b/analytics/src/test/java/com/ning/billing/analytics/MockProduct.java
index 57e0b5b..27ace04 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockProduct.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockProduct.java
@@ -16,10 +16,10 @@
 
 package com.ning.billing.analytics;
 
-import com.ning.billing.catalog.api.IProduct;
+import com.ning.billing.catalog.api.Product;
 import com.ning.billing.catalog.api.ProductCategory;
 
-public class MockProduct implements IProduct
+public class MockProduct implements Product
 {
     private final String name;
     private final String type;
@@ -51,13 +51,13 @@ public class MockProduct implements IProduct
     }
 
     @Override
-    public IProduct[] getAvailable()
+    public Product[] getAvailable()
     {
         return null;
     }
 
     @Override
-    public IProduct[] getIncluded()
+    public Product[] getIncluded()
     {
         return null;
     }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java b/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
index a756447..cff4ad7 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/MockSubscription.java
@@ -17,26 +17,28 @@
 package com.ning.billing.analytics;
 
 import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.catalog.api.IPlanPhase;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
-import com.ning.billing.entitlement.api.user.ISubscription;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
+import java.util.List;
 import java.util.UUID;
 
-public class MockSubscription implements ISubscription
+public class MockSubscription implements Subscription
 {
     private static final UUID ID = UUID.randomUUID();
     private static final UUID BUNDLE_ID = UUID.randomUUID();
     private static final DateTime START_DATE = new DateTime(DateTimeZone.UTC);
 
     private final SubscriptionState state;
-    private final IPlan plan;
-    private final IPlanPhase phase;
+    private final Plan plan;
+    private final PlanPhase phase;
 
-    public MockSubscription(final SubscriptionState state, final IPlan plan, final IPlanPhase phase)
+    public MockSubscription(final SubscriptionState state, final Plan plan, final PlanPhase phase)
     {
         this.state = state;
         this.plan = plan;
@@ -92,28 +94,17 @@ public class MockSubscription implements ISubscription
     }
 
     @Override
-    public IPlan getCurrentPlan()
+    public Plan getCurrentPlan()
     {
         return plan;
     }
 
     @Override
-    public IPlanPhase getCurrentPhase()
+    public PlanPhase getCurrentPhase()
     {
         return phase;
     }
 
-    @Override
-    public void setPrivate(final String name, final String value)
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPrivate(final String name)
-    {
-        throw new UnsupportedOperationException();
-    }
 
     @Override
     public void uncancel() throws EntitlementUserApiException
@@ -131,4 +122,9 @@ public class MockSubscription implements ISubscription
     public DateTime getEndDate() {
         return null;
     }
+
+    @Override
+    public List<SubscriptionTransition> getActiveTransitions() {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java b/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
index 5e65898..7bad790 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestAnalyticsListener.java
@@ -17,9 +17,9 @@
 package com.ning.billing.analytics;
 
 import com.ning.billing.catalog.api.*;
-import com.ning.billing.entitlement.api.user.ISubscription;
-import com.ning.billing.entitlement.api.user.SubscriptionTransition;
-import com.ning.billing.entitlement.events.IEvent;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionTransitionData;
+import com.ning.billing.entitlement.events.EntitlementEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
@@ -38,9 +38,9 @@ public class TestAnalyticsListener
     private final MockBusinessSubscriptionTransitionDao dao = new MockBusinessSubscriptionTransitionDao();
     private final UUID subscriptionId = UUID.randomUUID();
     private final UUID bundleUUID = UUID.randomUUID();
-    private final IProduct product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
-    private final IPlan plan = new MockPlan("platinum-monthly", product);
-    private final IPlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
+    private final Product product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
+    private final Plan plan = new MockPlan("platinum-monthly", product);
+    private final PlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
     private final String priceList = null;
 
     private AnalyticsListener listener;
@@ -58,7 +58,7 @@ public class TestAnalyticsListener
         // Create a subscription
         final DateTime effectiveTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedTransitionTime = new DateTime(DateTimeZone.UTC);
-        final SubscriptionTransition firstTransition = createFirstSubscriptionTransition(requestedTransitionTime, effectiveTransitionTime);
+        final SubscriptionTransitionData firstTransition = createFirstSubscriptionTransition(requestedTransitionTime, effectiveTransitionTime);
         final BusinessSubscriptionTransition firstBST = createExpectedFirstBST(requestedTransitionTime, effectiveTransitionTime);
         listener.handleSubscriptionTransitionChange(firstTransition);
         Assert.assertEquals(dao.getTransitions(KEY).size(), 1);
@@ -67,7 +67,7 @@ public class TestAnalyticsListener
         // Pause it
         final DateTime effectivePauseTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedPauseTransitionTime = new DateTime(DateTimeZone.UTC);
-        final SubscriptionTransition pausedSubscriptionTransition = createPauseSubscriptionTransition(effectivePauseTransitionTime, requestedPauseTransitionTime, firstTransition.getNextState());
+        final SubscriptionTransitionData pausedSubscriptionTransition = createPauseSubscriptionTransition(effectivePauseTransitionTime, requestedPauseTransitionTime, firstTransition.getNextState());
         final BusinessSubscriptionTransition pausedBST = createExpectedPausedBST(requestedPauseTransitionTime, effectivePauseTransitionTime, firstBST.getNextSubscription());
         listener.handleSubscriptionTransitionChange(pausedSubscriptionTransition);
         Assert.assertEquals(dao.getTransitions(KEY).size(), 2);
@@ -76,7 +76,7 @@ public class TestAnalyticsListener
         // Un-Pause it
         final DateTime effectiveResumeTransitionTime = new DateTime(DateTimeZone.UTC);
         final DateTime requestedResumeTransitionTime = new DateTime(DateTimeZone.UTC);
-        final SubscriptionTransition resumedSubscriptionTransition = createResumeSubscriptionTransition(requestedResumeTransitionTime, effectiveResumeTransitionTime, pausedSubscriptionTransition.getNextState());
+        final SubscriptionTransitionData resumedSubscriptionTransition = createResumeSubscriptionTransition(requestedResumeTransitionTime, effectiveResumeTransitionTime, pausedSubscriptionTransition.getNextState());
         final BusinessSubscriptionTransition resumedBST = createExpectedResumedBST(requestedResumeTransitionTime, effectiveResumeTransitionTime, pausedBST.getNextSubscription());
         listener.handleSubscriptionTransitionChange(resumedSubscriptionTransition);
         Assert.assertEquals(dao.getTransitions(KEY).size(), 3);
@@ -94,28 +94,28 @@ public class TestAnalyticsListener
     private BusinessSubscriptionTransition createExpectedFirstBST(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime)
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCreated(plan);
-        final ISubscription.SubscriptionState subscriptionState = ISubscription.SubscriptionState.ACTIVE;
+        final Subscription.SubscriptionState subscriptionState = Subscription.SubscriptionState.ACTIVE;
         return createExpectedBST(event, requestedTransitionTime, effectiveTransitionTime, null, subscriptionState);
     }
 
     private BusinessSubscriptionTransition createExpectedPausedBST(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription)
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionPaused(plan);
-        final ISubscription.SubscriptionState subscriptionState = ISubscription.SubscriptionState.PAUSED;
+        final Subscription.SubscriptionState subscriptionState = Subscription.SubscriptionState.PAUSED;
         return createExpectedBST(event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, subscriptionState);
     }
 
     private BusinessSubscriptionTransition createExpectedResumedBST(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription)
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionResumed(plan);
-        final ISubscription.SubscriptionState nextState = ISubscription.SubscriptionState.ACTIVE;
+        final Subscription.SubscriptionState nextState = Subscription.SubscriptionState.ACTIVE;
         return createExpectedBST(event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, nextState);
     }
 
     private BusinessSubscriptionTransition createExpectedCancelledBST(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final BusinessSubscription lastSubscription)
     {
         final BusinessSubscriptionEvent event = BusinessSubscriptionEvent.subscriptionCancelled(plan);
-        final ISubscription.SubscriptionState nextState = ISubscription.SubscriptionState.CANCELLED;
+        final Subscription.SubscriptionState nextState = Subscription.SubscriptionState.CANCELLED;
         return createExpectedBST(event, requestedTransitionTime, effectiveTransitionTime, lastSubscription, nextState);
     }
 
@@ -124,7 +124,7 @@ public class TestAnalyticsListener
         final DateTime requestedTransitionTime,
         final DateTime effectiveTransitionTime,
         final BusinessSubscription previousSubscription,
-        final ISubscription.SubscriptionState nextState
+        final Subscription.SubscriptionState nextState
     )
     {
         return new BusinessSubscriptionTransition(
@@ -146,15 +146,15 @@ public class TestAnalyticsListener
         );
     }
 
-    private SubscriptionTransition createFirstSubscriptionTransition(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime)
+    private SubscriptionTransitionData createFirstSubscriptionTransition(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime)
     {
         final ApiEventType eventType = ApiEventType.CREATE;
-        final ISubscription.SubscriptionState nextState = ISubscription.SubscriptionState.ACTIVE;
-        return new SubscriptionTransition(
+        final Subscription.SubscriptionState nextState = Subscription.SubscriptionState.ACTIVE;
+        return new SubscriptionTransitionData(
             UUID.randomUUID(),
             subscriptionId,
             bundleUUID,
-            IEvent.EventType.API_USER,
+            EntitlementEvent.EventType.API_USER,
             eventType,
             requestedTransitionTime,
             effectiveTransitionTime,
@@ -169,40 +169,40 @@ public class TestAnalyticsListener
         );
     }
 
-    private SubscriptionTransition createPauseSubscriptionTransition(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final ISubscription.SubscriptionState previousState)
+    private SubscriptionTransitionData createPauseSubscriptionTransition(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final Subscription.SubscriptionState previousState)
     {
         final ApiEventType eventType = ApiEventType.PAUSE;
-        final ISubscription.SubscriptionState nextState = ISubscription.SubscriptionState.PAUSED;
+        final Subscription.SubscriptionState nextState = Subscription.SubscriptionState.PAUSED;
         return createSubscriptionTransition(eventType, requestedTransitionTime, effectiveTransitionTime, previousState, nextState);
     }
 
-    private SubscriptionTransition createResumeSubscriptionTransition(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final ISubscription.SubscriptionState previousState)
+    private SubscriptionTransitionData createResumeSubscriptionTransition(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final Subscription.SubscriptionState previousState)
     {
         final ApiEventType eventType = ApiEventType.RESUME;
-        final ISubscription.SubscriptionState nextState = ISubscription.SubscriptionState.ACTIVE;
+        final Subscription.SubscriptionState nextState = Subscription.SubscriptionState.ACTIVE;
         return createSubscriptionTransition(eventType, requestedTransitionTime, effectiveTransitionTime, previousState, nextState);
     }
 
-    private SubscriptionTransition createCancelSubscriptionTransition(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final ISubscription.SubscriptionState previousState)
+    private SubscriptionTransitionData createCancelSubscriptionTransition(final DateTime requestedTransitionTime, final DateTime effectiveTransitionTime, final Subscription.SubscriptionState previousState)
     {
         final ApiEventType eventType = ApiEventType.CANCEL;
-        final ISubscription.SubscriptionState nextState = ISubscription.SubscriptionState.CANCELLED;
+        final Subscription.SubscriptionState nextState = Subscription.SubscriptionState.CANCELLED;
         return createSubscriptionTransition(eventType, requestedTransitionTime, effectiveTransitionTime, previousState, nextState);
     }
 
-    private SubscriptionTransition createSubscriptionTransition(
+    private SubscriptionTransitionData createSubscriptionTransition(
         final ApiEventType eventType,
         final DateTime requestedTransitionTime,
         final DateTime effectiveTransitionTime,
-        final ISubscription.SubscriptionState previousState,
-        final ISubscription.SubscriptionState nextState
+        final Subscription.SubscriptionState previousState,
+        final Subscription.SubscriptionState nextState
     )
     {
-        return new SubscriptionTransition(
+        return new SubscriptionTransitionData(
             UUID.randomUUID(),
             subscriptionId,
             bundleUUID,
-            IEvent.EventType.API_USER,
+            EntitlementEvent.EventType.API_USER,
             eventType,
             requestedTransitionTime,
             effectiveTransitionTime,
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscription.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscription.java
index 92cb1de..6c38854 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscription.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscription.java
@@ -17,7 +17,7 @@
 package com.ning.billing.analytics;
 
 import com.ning.billing.catalog.api.*;
-import com.ning.billing.entitlement.api.user.ISubscription;
+import com.ning.billing.entitlement.api.user.Subscription;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -28,8 +28,8 @@ import static com.ning.billing.catalog.api.Currency.USD;
 
 public class TestBusinessSubscription
 {
-    private final IDuration MONTHLY = MockDuration.MONHTLY();
-    private final IDuration YEARLY = MockDuration.YEARLY();
+    private final Duration MONTHLY = MockDuration.MONHTLY();
+    private final Duration YEARLY = MockDuration.YEARLY();
     final Object[][] catalog = {
         {MONTHLY, 229.0000, 229.0000},
         {MONTHLY, 19.9500, 19.9500},
@@ -42,10 +42,10 @@ public class TestBusinessSubscription
         {YEARLY, 18.2900, 1.5242},
         {YEARLY, 49.0000, 4.0833}};
 
-    private IProduct product;
-    private IPlan plan;
-    private IPlanPhase phase;
-    private ISubscription isubscription;
+    private Product product;
+    private Plan plan;
+    private PlanPhase phase;
+    private Subscription isubscription;
     private BusinessSubscription subscription;
 
     @BeforeMethod(alwaysRun = true)
@@ -54,7 +54,7 @@ public class TestBusinessSubscription
         product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
         plan = new MockPlan("platinum-monthly", product);
         phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
-        isubscription = new MockSubscription(ISubscription.SubscriptionState.ACTIVE, plan, phase);
+        isubscription = new MockSubscription(Subscription.SubscriptionState.ACTIVE, plan, phase);
         subscription = new BusinessSubscription(isubscription, USD);
     }
 
@@ -63,7 +63,7 @@ public class TestBusinessSubscription
     {
         int i = 0;
         for (final Object[] object : catalog) {
-            final IDuration duration = (IDuration) object[0];
+            final Duration duration = (Duration) object[0];
             final double price = (Double) object[1];
             final double expectedMrr = (Double) object[2];
 
@@ -94,7 +94,7 @@ public class TestBusinessSubscription
         Assert.assertEquals(subscription, subscription);
         Assert.assertTrue(subscription.equals(subscription));
 
-        final ISubscription otherIsubscription = new MockSubscription(ISubscription.SubscriptionState.CANCELLED, plan, phase);
+        final Subscription otherIsubscription = new MockSubscription(Subscription.SubscriptionState.CANCELLED, plan, phase);
         Assert.assertTrue(!subscription.equals(new BusinessSubscription(otherIsubscription, USD)));
     }
 }
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionEvent.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionEvent.java
index dfae096..5ea1950 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionEvent.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionEvent.java
@@ -16,22 +16,18 @@
 
 package com.ning.billing.analytics;
 
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.catalog.api.IPlanPhase;
-import com.ning.billing.catalog.api.IProduct;
-import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.user.ISubscription;
+import com.ning.billing.catalog.api.*;
+import com.ning.billing.entitlement.api.user.Subscription;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class TestBusinessSubscriptionEvent
 {
-    private IProduct product;
-    private IPlan plan;
-    private IPlanPhase phase;
-    private ISubscription isubscription;
+    private Product product;
+    private Plan plan;
+    private PlanPhase phase;
+    private Subscription isubscription;
 
     @BeforeMethod(alwaysRun = true)
     public void setUp() throws Exception
@@ -39,7 +35,7 @@ public class TestBusinessSubscriptionEvent
         product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
         plan = new MockPlan("platinum-monthly", product);
         phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
-        isubscription = new MockSubscription(ISubscription.SubscriptionState.ACTIVE, plan, phase);
+        isubscription = new MockSubscription(Subscription.SubscriptionState.ACTIVE, plan, phase);
     }
 
     @Test(groups = "fast")
@@ -100,7 +96,7 @@ public class TestBusinessSubscriptionEvent
         Assert.assertEquals(event.getCategory(), product.getCategory());
         Assert.assertEquals(event.toString(), "SYSTEM_CHANGE_BASE");
 
-        isubscription = new MockSubscription(ISubscription.SubscriptionState.CANCELLED, plan, phase);
+        isubscription = new MockSubscription(Subscription.SubscriptionState.CANCELLED, plan, phase);
         event = BusinessSubscriptionEvent.subscriptionPhaseChanged(isubscription.getCurrentPlan(), isubscription.getState());
         // The subscription is cancelled, it's a system cancellation
         Assert.assertEquals(event.getEventType(), BusinessSubscriptionEvent.EventType.SYSTEM_CANCEL);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java
index 61fd399..592d20d 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/TestBusinessSubscriptionTransition.java
@@ -17,7 +17,7 @@
 package com.ning.billing.analytics;
 
 import com.ning.billing.catalog.api.*;
-import com.ning.billing.entitlement.api.user.ISubscription;
+import com.ning.billing.entitlement.api.user.Subscription;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.testng.Assert;
@@ -39,11 +39,11 @@ public class TestBusinessSubscriptionTransition
     @BeforeMethod(alwaysRun = true)
     public void setUp() throws Exception
     {
-        final IProduct product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
-        final IPlan plan = new MockPlan("platinum-monthly", product);
-        final IPlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
-        final ISubscription prevISubscription = new MockSubscription(ISubscription.SubscriptionState.ACTIVE, plan, phase);
-        final ISubscription nextISubscription = new MockSubscription(ISubscription.SubscriptionState.CANCELLED, plan, phase);
+        final Product product = new MockProduct("platinium", "subscription", ProductCategory.BASE);
+        final Plan plan = new MockPlan("platinum-monthly", product);
+        final PlanPhase phase = new MockPhase(PhaseType.EVERGREEN, plan, MockDuration.UNLIMITED(), 25.95);
+        final Subscription prevISubscription = new MockSubscription(Subscription.SubscriptionState.ACTIVE, plan, phase);
+        final Subscription nextISubscription = new MockSubscription(Subscription.SubscriptionState.CANCELLED, plan, phase);
 
         prevSubscription = new BusinessSubscription(prevISubscription, USD);
         nextSubscription = new BusinessSubscription(nextISubscription, USD);

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

diff --git a/api/pom.xml b/api/pom.xml
index 5a01c5b..7f7f108 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.0.16-SNAPSHOT</version>
+        <version>0.0.17-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-api</artifactId>
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountService.java b/api/src/main/java/com/ning/billing/account/api/AccountService.java
index 709e6e7..43175da 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountService.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountService.java
@@ -16,8 +16,9 @@
 
 package com.ning.billing.account.api;
 
-import com.ning.billing.lifecycle.IService;
+import com.ning.billing.lifecycle.KillbillService;
+
+public interface AccountService extends KillbillService {
 
-public interface AccountService extends IService {
     public AccountUserApi getAccountUserApi();
 }
diff --git a/api/src/main/java/com/ning/billing/analytics/api/IAnalyticsService.java b/api/src/main/java/com/ning/billing/analytics/api/IAnalyticsService.java
index 2a5d0c5..b817e64 100644
--- a/api/src/main/java/com/ning/billing/analytics/api/IAnalyticsService.java
+++ b/api/src/main/java/com/ning/billing/analytics/api/IAnalyticsService.java
@@ -16,7 +16,7 @@
 
 package com.ning.billing.analytics.api;
 
-import com.ning.billing.lifecycle.IService;
+import com.ning.billing.lifecycle.KillbillService;
 
-public interface IAnalyticsService extends IService {
+public interface IAnalyticsService extends KillbillService {
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/PlanChangeResult.java b/api/src/main/java/com/ning/billing/catalog/api/PlanChangeResult.java
index c0be482..3974e87 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/PlanChangeResult.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/PlanChangeResult.java
@@ -18,18 +18,18 @@ package com.ning.billing.catalog.api;
 
 public class PlanChangeResult {
  
-	private final IPriceList newPriceList;
+	private final PriceList newPriceList;
 	private final ActionPolicy policy;
 	private final PlanAlignmentChange alignment;
 	
-	public PlanChangeResult(IPriceList newPriceList, ActionPolicy policy, PlanAlignmentChange alignment) {
+	public PlanChangeResult(PriceList newPriceList, ActionPolicy policy, PlanAlignmentChange alignment) {
 		super();
 		this.newPriceList = newPriceList;
 		this.policy = policy;
 		this.alignment = alignment;
 	}
 
-	public IPriceList getNewPriceList() {
+	public PriceList getNewPriceList() {
 		return newPriceList;
 	}
 
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 5cca8fa..8fc3df4 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -32,7 +32,7 @@ public enum ErrorCode {
     ENT_INVALID_REQUESTED_DATE(1001, "Requested in the future is not allowed : %s"),
 
     /* Creation */
-    ENT_CREATE_BAD_CATALOG(1011, "Plan for product %s, term %s and set %s does not exist in the catalog"),
+    ENT_CREATE_BAD_PHASE(1011, "Can't create plan initial phase %s"),
     ENT_CREATE_NO_BUNDLE(1012, "Bundle %s does not exists"),
     ENT_CREATE_NO_BP(1013, "Missing Base Subscription for bundle %s"),
     ENT_CREATE_BP_EXISTS(1015, "Subscription bundle %s already has a base subscription"),
@@ -43,10 +43,46 @@ public enum ErrorCode {
     ENT_CANCEL_BAD_STATE(1031, "Subscription %s is in state %s"),
     /* Un-cancellation */
     ENT_UNCANCEL_BAD_STATE(1070, "Subscription %s was not in a cancelled state"),
-    
+
+    /*
+    *
+    * Range 2000 : CATALOG
+    *
+    */
+
+    /*
+    * Rules exceptions
+    */
+
+    /* Plan change is disallowed by the catalog */
     CAT_ILLEGAL_CHANGE_REQUEST(2001, "Attempting to change plan from (product: '%s', billing period: '%s', " +
-    		"pricelist '%s') to (product: '%s', billing period: '%s', pricelist '%s'). This transition is not allowed by catalog rules")
-    
+    		"pricelist '%s') to (product: '%s', billing period: '%s', pricelist '%s'). This transition is not allowed by catalog rules"),
+
+	/*
+	 * Price list
+	 */
+
+	/*Attempt to reference a price that is not present - should only happen if it is a currency not available in the catalog */
+    CAT_NO_PRICE_FOR_CURRENCY(2010, "This price does not have a value for the currency '%s'."),
+
+    /* Price value explicitly set to NULL meaning there is no price available in that currency */
+    CAT_PRICE_VALUE_NULL_FOR_CURRENCY(2011, "The value for the currency '%s' is NULL. This plan cannot be bought in this currnency."),
+
+    /*
+     * Plans
+     */
+    CAT_PLAN_NOT_FOUND(2020,"Could not find a plan matching: (product: '%s', billing period: '%s', pricelist '%s')"),
+    CAT_NO_SUCH_PLAN(2021,"Could not find any plans named '%s'"),
+
+    /*
+     * Products
+     */
+    CAT_NO_SUCH_PRODUCT(2030,"Could not find any plans named '%s'"),
+
+    /*
+     * Phases
+     */
+    CAT_NO_SUCH_PHASE(2040,"Could not find any phases named '%s'")
     ;
 
     private int code;
diff --git a/api/src/main/java/com/ning/billing/invoice/api/BillingEventSet.java b/api/src/main/java/com/ning/billing/invoice/api/BillingEventSet.java
index c85f540..8e42a9e 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/BillingEventSet.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/BillingEventSet.java
@@ -16,12 +16,12 @@
 
 package com.ning.billing.invoice.api;
 
-import com.ning.billing.entitlement.api.billing.IBillingEvent;
+import com.ning.billing.entitlement.api.billing.BillingEvent;
 
 import java.util.ArrayList;
 
-public class BillingEventSet extends ArrayList<IBillingEvent> {
-    public IBillingEvent getLast() {
+public class BillingEventSet extends ArrayList<BillingEvent> {
+    public BillingEvent getLast() {
         if (this.size() == 0) {return null;}
 
         return this.get(this.size() - 1);
diff --git a/api/src/main/java/com/ning/billing/invoice/api/Invoice.java b/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
index 533cbe6..41d7adb 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/Invoice.java
@@ -24,11 +24,11 @@ import java.util.List;
 import java.util.UUID;
 
 public interface Invoice {
-    boolean add(IInvoiceItem item);
+    boolean add(InvoiceItem item);
 
-    boolean add(List<IInvoiceItem> items);
+    boolean add(List<InvoiceItem> items);
 
-    List<IInvoiceItem> getItems();
+    List<InvoiceItem> getItems();
 
     int getNumberOfItems();
 

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

diff --git a/beatrix/pom.xml b/beatrix/pom.xml
index 3867975..b211a46 100644
--- a/beatrix/pom.xml
+++ b/beatrix/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.0.16-SNAPSHOT</version>
+        <version>0.0.17-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-beatrix</artifactId>
diff --git a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/Lifecycle.java b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/Lifecycle.java
index f091a81..c0edf2c 100644
--- a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/Lifecycle.java
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/Lifecycle.java
@@ -16,18 +16,6 @@
 
 package com.ning.billing.beatrix.lifecycle;
 
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import com.google.common.base.Supplier;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
@@ -35,16 +23,23 @@ import com.google.common.collect.Multimaps;
 import com.google.common.collect.SetMultimap;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
-import com.ning.billing.lifecycle.IService;
-import com.ning.billing.lifecycle.LyfecycleHandlerType;
-import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
-import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel.Sequence;
+import com.ning.billing.lifecycle.KillbillService;
+import com.ning.billing.lifecycle.LifecycleHandlerType;
+import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
+import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel.Sequence;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
 
 
 public class Lifecycle {
 
     private final static Logger log = LoggerFactory.getLogger(Lifecycle.class);
-    private final SetMultimap<LyfecycleLevel, LifecycleHandler<? extends IService>> handlersByLevel;
+    private final SetMultimap<LifecycleLevel, LifecycleHandler<? extends KillbillService>> handlersByLevel;
 
     private final ServiceFinder serviceFinder;
 
@@ -54,12 +49,12 @@ public class Lifecycle {
     public Lifecycle(Injector injector) {
 
         this.serviceFinder = new ServiceFinder(Lifecycle.class.getClassLoader());
-        this.handlersByLevel = Multimaps.newSetMultimap(new ConcurrentHashMap<LyfecycleLevel, Collection<LifecycleHandler<? extends IService>>>(),
+        this.handlersByLevel = Multimaps.newSetMultimap(new ConcurrentHashMap<LifecycleLevel, Collection<LifecycleHandler<? extends KillbillService>>>(),
 
-                new Supplier<Set<LifecycleHandler<? extends IService>>>() {
+                new Supplier<Set<LifecycleHandler<? extends KillbillService>>>() {
             @Override
-            public Set<LifecycleHandler<? extends IService>> get() {
-                return new CopyOnWriteArraySet<LifecycleHandler<? extends IService>>();
+            public Set<LifecycleHandler<? extends KillbillService>> get() {
+                return new CopyOnWriteArraySet<LifecycleHandler<? extends KillbillService>>();
             }
         });
         this.injector = injector;
@@ -68,8 +63,8 @@ public class Lifecycle {
     }
 
     public void init() {
-        Set<? extends IService> services = findServices();
-        Iterator<? extends IService> it = services.iterator();
+        Set<? extends KillbillService> services = findServices();
+        Iterator<? extends KillbillService> it = services.iterator();
         while (it.hasNext()) {
             handlersByLevel.putAll(findAllHandlers(it.next()));
         }
@@ -85,28 +80,28 @@ public class Lifecycle {
     }
 
     public void fireShutdownSequencePriorEventUnRegistration() {
-        fireSequence(Sequence.SHUTOWN_PRE_EVENT_UNREGISTRATION);
+        fireSequence(Sequence.SHUTDOWN_PRE_EVENT_UNREGISTRATION);
     }
 
     public void fireShutdownSequencePostEventUnRegistration() {
-        fireSequence(Sequence.SHUTOWN_POST_EVENT_UNREGISTRATION);
+        fireSequence(Sequence.SHUTDOWN_POST_EVENT_UNREGISTRATION);
     }
 
     private void fireSequence(Sequence seq) {
-        List<LyfecycleLevel> levels = LyfecycleLevel.getLevelsForSequence(seq);
-        for (LyfecycleLevel cur : levels) {
+        List<LifecycleLevel> levels = LifecycleLevel.getLevelsForSequence(seq);
+        for (LifecycleLevel cur : levels) {
             doFireStage(cur);
         }
     }
 
-    private void doFireStage(LyfecycleLevel level) {
+    private void doFireStage(LifecycleLevel level) {
         log.info("Killbill lifecycle firing stage {}", level);
-        Set<LifecycleHandler<? extends IService>> handlers = handlersByLevel.get(level);
-        for (LifecycleHandler<? extends IService> cur : handlers) {
+        Set<LifecycleHandler<? extends KillbillService>> handlers = handlersByLevel.get(level);
+        for (LifecycleHandler<? extends KillbillService> cur : handlers) {
 
             try {
                 Method method = cur.getMethod();
-                IService target = cur.getTarget();
+                KillbillService target = cur.getTarget();
                 log.info("Killbill lifecycle calling handler {} for service {}", cur.getMethod().getName(), target.getName());
                 method.invoke(target);
             } catch (Exception e) {
@@ -117,14 +112,14 @@ public class Lifecycle {
     }
 
 
-    private Set<? extends IService> findServices() {
+    private Set<? extends KillbillService> findServices() {
 
-        Set<IService> result = new HashSet<IService>();
-        Set<Class<? extends IService>> services =  serviceFinder.getServices();
-        for (Class<? extends IService> cur : services) {
+        Set<KillbillService> result = new HashSet<KillbillService>();
+        Set<Class<? extends KillbillService>> services =  serviceFinder.getServices();
+        for (Class<? extends KillbillService> cur : services) {
             log.debug("Found service {}", cur.getName());
             try {
-                IService instance = injector.getInstance(cur);
+                KillbillService instance = injector.getInstance(cur);
                 log.debug("got instance {}", instance.getName());
                 result.add(instance);
             } catch (Exception e) {
@@ -141,14 +136,14 @@ public class Lifecycle {
         log.warn(msg, e);
     }
 
-    public Multimap<LyfecycleLevel, LifecycleHandler<? extends IService>> findAllHandlers(IService service) {
-        Multimap<LyfecycleLevel, LifecycleHandler<? extends IService>> methodsInService = HashMultimap.create();
-        Class<? extends IService> clazz = service.getClass();
+    public Multimap<LifecycleLevel, LifecycleHandler<? extends KillbillService>> findAllHandlers(KillbillService service) {
+        Multimap<LifecycleLevel, LifecycleHandler<? extends KillbillService>> methodsInService = HashMultimap.create();
+        Class<? extends KillbillService> clazz = service.getClass();
         for (Method method : clazz.getMethods()) {
-            LyfecycleHandlerType annotation = method.getAnnotation(LyfecycleHandlerType.class);
+            LifecycleHandlerType annotation = method.getAnnotation(LifecycleHandlerType.class);
             if (annotation != null) {
-                LyfecycleLevel level = annotation.value();
-                LifecycleHandler<? extends IService> handler = new  LifecycleHandler<IService>(service, method);
+                LifecycleLevel level = annotation.value();
+                LifecycleHandler<? extends KillbillService> handler = new  LifecycleHandler<KillbillService>(service, method);
                 methodsInService.put(level, handler);
             }
         }
diff --git a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java
index 6916cf1..a4a4ce2 100644
--- a/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java
@@ -17,56 +17,45 @@
 package com.ning.billing.beatrix.lifecycle;
 
 
+import com.ning.billing.lifecycle.KillbillService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.io.File;
 import java.io.IOException;
-import java.lang.reflect.Modifier;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
+import java.util.*;
 import java.util.jar.JarFile;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.ning.billing.lifecycle.IService;
-
 public class ServiceFinder {
 
     private static final Logger log = LoggerFactory.getLogger(ServiceFinder.class);
 
 	private final ClassLoader loader;
-	private final Set<Class<? extends IService>> servicesTypes;
+	private final Set<Class<? extends KillbillService>> servicesTypes;
 
 	public ServiceFinder(ClassLoader loader) {
 		this.loader = loader;
 		this.servicesTypes = initialize();
-		Iterator<Class<? extends IService>> it = servicesTypes.iterator();
+		Iterator<Class<? extends KillbillService>> it = servicesTypes.iterator();
 		while (it.hasNext()) {
-		    Class<? extends IService> svc = it.next();
+		    Class<? extends KillbillService> svc = it.next();
 			log.debug("Found IService classes {}", svc.getName());
 		}
 	}
 
-	public Set<Class<? extends IService>> getServices() {
+	public Set<Class<? extends KillbillService>> getServices() {
 	    return servicesTypes;
 	}
 
-	private Set<Class<? extends IService>> initialize() {
+	private Set<Class<? extends KillbillService>> initialize() {
 		try {
 
 		    final Set<String> packageFilter = new HashSet<String>();
 		    packageFilter.add("com.ning.billing");
 		    final String jarFilter = "killbill";
-			return findClasses(loader, IService.class.getName().toString(), jarFilter, packageFilter);
+			return findClasses(loader, KillbillService.class.getName().toString(), jarFilter, packageFilter);
 		} catch (ClassNotFoundException nfe) {
 			throw new RuntimeException("Failed to initialize ClassFinder", nfe);
 		}
@@ -76,13 +65,13 @@ public class ServiceFinder {
      *  Code originally from Kris Dover <krisdover@hotmail.com> and adapted for my purpose.
      *
      */
-	private static Set<Class<? extends IService>> findClasses(ClassLoader classLoader,
+	private static Set<Class<? extends KillbillService>> findClasses(ClassLoader classLoader,
 	        String interfaceFilter,
 	        String jarFilter,
 	        Set<String> packageFilter)
 	        throws ClassNotFoundException {
 
-	    final Set<Class<? extends IService>> result = new HashSet<Class<? extends IService>>();
+	    final Set<Class<? extends KillbillService>> result = new HashSet<Class<? extends KillbillService>>();
 
 	    Object[] classPaths;
 	    try {
@@ -165,7 +154,7 @@ public class ServiceFinder {
 	                    if (!interfaceFilter.equals(interfaceName) ) {
 	                        continue;
 	                    }
-	                    result.add((Class<? extends IService>) theClass);
+	                    result.add((Class<? extends KillbillService>) theClass);
 	                    break;
 	                }
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java b/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java
index 791b2fe..69e6a0d 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java
@@ -16,21 +16,16 @@
 
 package com.ning.billing.beatrix.lifecycle;
 
+import com.google.inject.*;
+import com.ning.billing.lifecycle.KillbillService;
+import com.ning.billing.lifecycle.LifecycleHandlerType;
+import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
-import com.ning.billing.lifecycle.IService;
-import com.ning.billing.lifecycle.LyfecycleHandlerType;
-import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
-
 
 public class TestLifecycle {
 
@@ -62,21 +57,21 @@ public class TestLifecycle {
         }
     }
 
-    public static class Service1 extends ServiceBase implements IService  {
+    public static class Service1 extends ServiceBase implements KillbillService  {
 
-        @LyfecycleHandlerType(LyfecycleLevel.INIT_BUS)
+        @LifecycleHandlerType(LifecycleLevel.INIT_BUS)
         public void initBus() {
             log.info("Service1 : got INIT_BUS");
             incrementCount();
         }
 
-        @LyfecycleHandlerType(LyfecycleLevel.START_SERVICE)
+        @LifecycleHandlerType(LifecycleLevel.START_SERVICE)
         public void startService() {
             log.info("Service1 : got START_SERVICE");
             incrementCount();
         }
 
-        @LyfecycleHandlerType(LyfecycleLevel.SHUTDOWN)
+        @LifecycleHandlerType(LifecycleLevel.SHUTDOWN)
         public void shutdownService() {
             log.info("Service1 : got SHUTDOWN");
             incrementCount();
@@ -88,27 +83,27 @@ public class TestLifecycle {
         }
     }
 
-    public static class Service2 extends ServiceBase implements IService {
+    public static class Service2 extends ServiceBase implements KillbillService {
 
-        @LyfecycleHandlerType(LyfecycleLevel.LOAD_CATALOG)
+        @LifecycleHandlerType(LifecycleLevel.LOAD_CATALOG)
         public void loadCatalog() {
             log.info("Service2 : got LOAD_CATALOG");
             incrementCount();
         }
 
-        @LyfecycleHandlerType(LyfecycleLevel.REGISTER_EVENTS)
+        @LifecycleHandlerType(LifecycleLevel.REGISTER_EVENTS)
         public void registerEvents() {
             log.info("Service2 : got REGISTER_EVENTS");
             incrementCount();
         }
 
-        @LyfecycleHandlerType(LyfecycleLevel.UNREGISTER_EVENTS)
+        @LifecycleHandlerType(LifecycleLevel.UNREGISTER_EVENTS)
         public void unregisterEvents() {
             log.info("Service2 : got UNREGISTER_EVENTS");
             incrementCount();
         }
 
-        @LyfecycleHandlerType(LyfecycleLevel.START_SERVICE)
+        @LifecycleHandlerType(LifecycleLevel.START_SERVICE)
         public void startService() {
             log.info("Service2 : got START_SERVICE");
             incrementCount();

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

diff --git a/catalog/pom.xml b/catalog/pom.xml
index fb48f3d..bf50441 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.0.16-SNAPSHOT</version>
+        <version>0.0.17-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-catalog</artifactId>
diff --git a/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java b/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java
index deb2305..8702b6f 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java
@@ -16,25 +16,24 @@
 
 package com.ning.billing.catalog.glue;
 
-import org.skife.config.ConfigurationObjectFactory;
-
 import com.google.inject.AbstractModule;
-import com.ning.billing.catalog.CatalogService;
-import com.ning.billing.catalog.CatalogUserApi;
-import com.ning.billing.catalog.api.ICatalogService;
-import com.ning.billing.catalog.api.ICatalogUserApi;
-import com.ning.billing.config.ICatalogConfig;
+import com.ning.billing.catalog.DefaultCatalogService;
+import com.ning.billing.catalog.api.CatalogService;
+import com.ning.billing.catalog.io.ICatalogLoader;
+import com.ning.billing.catalog.io.VersionedCatalogLoader;
+import com.ning.billing.config.CatalogConfig;
+import org.skife.config.ConfigurationObjectFactory;
 
 public class CatalogModule extends AbstractModule {
 
     protected void installConfig() {
-        final ICatalogConfig config = new ConfigurationObjectFactory(System.getProperties()).build(ICatalogConfig.class);
-        bind(ICatalogConfig.class).toInstance(config);
+        final CatalogConfig config = new ConfigurationObjectFactory(System.getProperties()).build(CatalogConfig.class);
+        bind(CatalogConfig.class).toInstance(config);
     }
 
     protected void installCatalog() {
-        bind(ICatalogUserApi.class).to(CatalogUserApi.class).asEagerSingleton();
-        bind(ICatalogService.class).to(CatalogService.class).asEagerSingleton();
+        bind(CatalogService.class).to(DefaultCatalogService.class).asEagerSingleton();
+        bind(ICatalogLoader.class).to(VersionedCatalogLoader.class).asEagerSingleton();
     }
 
     @Override
diff --git a/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java b/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
index 9bc2314..4ad78df 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
@@ -16,64 +16,81 @@
 
 package com.ning.billing.catalog.io;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
+import com.google.inject.Inject;
+import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.VersionedCatalog;
+import com.ning.billing.lifecycle.KillbillService.ServiceException;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.config.UriAccessor;
+import com.ning.billing.util.config.XMLLoader;
+
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.net.URLConnection;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
-import java.util.Scanner;
-
-import javax.xml.bind.JAXBException;
-import javax.xml.transform.TransformerException;
-
-import org.xml.sax.SAXException;
-
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.VersionedCatalog;
-import com.ning.billing.catalog.api.InvalidConfigException;
-import com.ning.billing.util.config.XMLLoader;
 
-public class VersionedCatalogLoader  {
+public class VersionedCatalogLoader implements ICatalogLoader  {
+	private static final Object PROTOCOL_FOR_FILE = "file";
 	private  final String XML_EXTENSION = ".xml";
 	private  final String HREF_LOW_START = "href=\""; 
 	private  final String HREF_CAPS_START = "HREF=\""; 
 	private  final String HREF_SEARCH_END = "\"";
+	private Clock clock;
 			
+	@Inject 
+	public VersionedCatalogLoader(Clock clock) {
+		this.clock = clock;
+	}
+	
 	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.io.ICatalogLoader#load(java.net.URL)
+	 * @see com.ning.billing.catalog.io.ICatalogLoader#load(java.lang.String)
 	 */
-	public  VersionedCatalog load(URL url) throws IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
-		String directoryContents = pullContentsFrom(url);
-		List<URL> xmlURLs = findXmlReferences(directoryContents, url);
-		VersionedCatalog result = new VersionedCatalog();
-		for(URL u : xmlURLs) {
-			Catalog catalog = XMLLoader.getObjectFromURL(u, Catalog.class);
-			result.add(catalog);
+	@Override
+	public  VersionedCatalog load(String uriString) throws ServiceException{
+		try {
+			List<URI> xmlURIs = null;
+			
+			if(uriString.endsWith(XML_EXTENSION)) { //assume its an xml file
+				xmlURIs = new ArrayList<URI>();
+	        	xmlURIs.add(new URI(uriString));
+			} else { //assume its a directory
+				String directoryContents = UriAccessor.accessUriAsString(uriString);
+				xmlURIs = findXmlReferences(directoryContents, new URL(uriString));
+			}
+			
+			VersionedCatalog result = new VersionedCatalog();
+			for(URI u : xmlURIs) {
+				StandaloneCatalog catalog = XMLLoader.getObjectFromUri(u, StandaloneCatalog.class);
+				result.add(catalog);
+			}
+			Date now = clock.getUTCNow().toDate();
+			result.configureEffectiveDate(now);
+			return result;
+		} catch (Exception e) {
+			throw new ServiceException("Problem encountered loading catalog", e);
 		}
-		return result;
 	}
 	
-	protected  List<URL> findXmlReferences(String directoryContents, URL url) throws MalformedURLException {
-		if(url.getProtocol().equals("file")) {
+	protected  List<URI> findXmlReferences(String directoryContents, URL url) throws URISyntaxException {
+		if(url.getProtocol().equals(PROTOCOL_FOR_FILE)) {
 			return findXmlFileReferences(directoryContents, url);
 		} 
 		return findXmlUrlReferences(directoryContents, url);
 	}
 
-	protected  List<URL> findXmlUrlReferences(String directoryContents, URL url) throws MalformedURLException {
-		List<URL> results = new ArrayList<URL>();
+	protected  List<URI> findXmlUrlReferences(String directoryContents, URL url) throws URISyntaxException {
+		List<URI> results = new ArrayList<URI>();
 		List<String> urlFragments = extractHrefs(directoryContents);
 		for(String u : urlFragments) {
 			if(u.endsWith(XML_EXTENSION)) { //points to xml
 				if(u.startsWith("/")) { //absolute path need to add the protocol
-					results.add(new URL(url.getProtocol() + ":" + u));
+					results.add(new URI(url.getProtocol() + ":" + u));
 				} else if (u.startsWith("http:")) { // full url
-					results.add(new URL(u));
+					results.add(new URI(u));
 				} else { // relative url stick the name on the end
-					results.add(appendToURL(url,u));
+					results.add(appendToURI(url,u));
 				}
 			}
 		}
@@ -108,28 +125,24 @@ public class VersionedCatalogLoader  {
 		return results;
 	}
 
-	protected  List<URL> findXmlFileReferences(String directoryContents, URL url) throws MalformedURLException {
-		List<URL> results = new ArrayList<URL>();
+	protected  List<URI> findXmlFileReferences(String directoryContents, URL url) throws URISyntaxException {
+		List<URI> results = new ArrayList<URI>();
 		String[] filenames = directoryContents.split("\\n");
 		for(String filename : filenames) {
 			if(filename.endsWith(XML_EXTENSION)) {
-				results.add(appendToURL(url,filename));
+				results.add(appendToURI(url,filename));
 			}
 		}
 		return results;
 	}
 
-	protected  URL appendToURL(final URL url, final String filename) throws MalformedURLException {
+	protected  URI appendToURI(final URL url, final String filename) throws URISyntaxException {
 		String f = filename;
 		if (!url.toString().endsWith("/")) {
 			f = "/" + filename;
 		}
-		return new URL(url.toString() + f);
+		return new URI(url.toString() + f);
 	}
 
-	protected  String pullContentsFrom(final URL url) throws IOException {
-		URLConnection connection = url.openConnection();
-		InputStream content = connection.getInputStream();
-		return new Scanner(content).useDelimiter("\\A").next();
-	}
+	
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java b/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java
index 781f44d..f667e17 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java
@@ -16,27 +16,28 @@
 
 package com.ning.billing.catalog;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-
-import com.ning.billing.catalog.api.IPriceListSet;
+import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.util.config.ValidationError;
 import com.ning.billing.util.config.ValidationErrors;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
 @XmlAccessorType(XmlAccessType.NONE)
-public class PriceListDefault extends PriceList {
+public class PriceListDefault extends DefaultPriceList {
 	
 	public PriceListDefault(){}
 	
-	public PriceListDefault(Plan[] defaultPlans) {
-		super(defaultPlans, IPriceListSet.DEFAULT_PRICELIST_NAME);
+	public PriceListDefault(DefaultPlan[] defaultPlans) {
+		super(defaultPlans, PriceListSet.DEFAULT_PRICELIST_NAME);
 	}
 
 	@Override
-	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
-		if(getName().equals(IPriceListSet.DEFAULT_PRICELIST_NAME)) {
+	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
+		super.validate(catalog, errors);
+		if(!getName().equals(PriceListSet.DEFAULT_PRICELIST_NAME)) {
 			errors.add(new ValidationError("The name of the default pricelist must be 'DEFAULT'", 
-					catalog.getCatalogURI(), PriceList.class, getName()));
+					catalog.getCatalogURI(), DefaultPriceList.class, getName()));
 			
 		}
 		return errors;
@@ -44,7 +45,7 @@ public class PriceListDefault extends PriceList {
 
 	@Override
 	public String getName() {
-		return IPriceListSet.DEFAULT_PRICELIST_NAME;
+		return PriceListSet.DEFAULT_PRICELIST_NAME;
 	}
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java b/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java
index 67f7bae..737373e 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java
@@ -16,39 +16,40 @@
 
 package com.ning.billing.catalog.rules;
 
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.PriceList;
-import com.ning.billing.catalog.Product;
+import com.ning.billing.catalog.DefaultPriceList;
+import com.ning.billing.catalog.DefaultProduct;
+import com.ning.billing.catalog.StandaloneCatalog;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationErrors;
 
-public abstract class Case<T> extends ValidatingConfig<Catalog> {
+public abstract class Case<T> extends ValidatingConfig<StandaloneCatalog> {
 
-	protected Product product;
+	protected DefaultProduct product;
 	protected ProductCategory productCategory;
 	protected BillingPeriod billingPeriod;
-	protected PriceList priceList;
+	protected DefaultPriceList priceList;
 
 	protected abstract T getResult();
 
-	public T getResult(PlanSpecifier planPhase, Catalog c) {
+	public T getResult(PlanSpecifier planPhase, StandaloneCatalog c) throws CatalogApiException {
 		if (satisfiesCase(planPhase, c)	) {
 			return getResult(); 
 		}
 		return null;
 	}
 	
-	protected boolean satisfiesCase(PlanSpecifier planPhase, Catalog c) {
-		return (product         == null || product.equals(c.getProductFromName(planPhase.getProductName()))) &&
+	protected boolean satisfiesCase(PlanSpecifier planPhase, StandaloneCatalog c) throws CatalogApiException {
+		return (product         == null || product.equals(c.findProduct(planPhase.getProductName()))) &&
 		(productCategory == null || productCategory.equals(planPhase.getProductCategory())) &&
 		(billingPeriod   == null || billingPeriod.equals(planPhase.getBillingPeriod())) &&
 		(priceList       == null || priceList.equals(c.getPriceListFromName(planPhase.getPriceListName())));
 	}
 
-	public static <K> K getResult(Case<K>[] cases, PlanSpecifier planSpec, Catalog catalog) {
+	public static <K> K getResult(Case<K>[] cases, PlanSpecifier planSpec, StandaloneCatalog catalog) throws CatalogApiException {
     	if(cases != null) {
     		for(Case<K> c : cases) {
     			K result = c.getResult(planSpec, catalog);
@@ -62,11 +63,11 @@ public abstract class Case<T> extends ValidatingConfig<Catalog> {
     }
 	
 	@Override
-	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
+	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
 		return errors;
 	}
 
-	protected Case<T> setProduct(Product product) {
+	protected Case<T> setProduct(DefaultProduct product) {
 		this.product = product;
 		return this;
 	}
@@ -81,7 +82,7 @@ public abstract class Case<T> extends ValidatingConfig<Catalog> {
 		return this;
 	}
 
-	protected Case<T> setPriceList(PriceList priceList) {
+	protected Case<T> setPriceList(DefaultPriceList priceList) {
 		this.priceList = priceList;
 		return this;
 	}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java
index e0095f8..a340fdc 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java
@@ -16,31 +16,27 @@
 
 package com.ning.billing.catalog.rules;
 
+import com.ning.billing.catalog.DefaultPriceList;
+import com.ning.billing.catalog.DefaultProduct;
+import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.api.*;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
+
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlIDREF;
 
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.PriceList;
-import com.ning.billing.catalog.Product;
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.catalog.api.PlanPhaseSpecifier;
-import com.ning.billing.catalog.api.PlanSpecifier;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.util.config.ValidatingConfig;
-import com.ning.billing.util.config.ValidationErrors;
-
 @XmlAccessorType(XmlAccessType.NONE)
-public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
+public abstract class CaseChange<T>  extends ValidatingConfig<StandaloneCatalog> {
 
 	@XmlElement(required=false)
 	private PhaseType phaseType;
 
 	@XmlElement(required=false)
 	@XmlIDREF
-	private Product fromProduct;
+	private DefaultProduct fromProduct;
 
 	@XmlElement(required=false)
 	private ProductCategory fromProductCategory;
@@ -50,11 +46,11 @@ public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
 
 	@XmlElement(required=false)
 	@XmlIDREF
-	private PriceList fromPriceList;
+	private DefaultPriceList fromPriceList;
 
 	@XmlElement(required=false)
 	@XmlIDREF
-	private Product toProduct;
+	private DefaultProduct toProduct;
 
 	@XmlElement(required=false)
 	private ProductCategory toProductCategory;
@@ -64,18 +60,18 @@ public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
 
 	@XmlElement(required=false)
 	@XmlIDREF
-	private PriceList toPriceList;
+	private DefaultPriceList toPriceList;
 
 	protected abstract T getResult();
 	
 	public T getResult(PlanPhaseSpecifier from,
-			PlanSpecifier to, Catalog catalog) {
+			PlanSpecifier to, StandaloneCatalog catalog) throws CatalogApiException {
 		if(	
 				(phaseType     	     == null || from.getPhaseType() == phaseType) &&
-				(fromProduct 	     == null || fromProduct.equals(catalog.getProductFromName(from.getProductName()))) &&
+				(fromProduct 	     == null || fromProduct.equals(catalog.findProduct(from.getProductName()))) &&
 				(fromProductCategory == null || fromProductCategory.equals(from.getProductCategory())) &&
 				(fromBillingPeriod   == null || fromBillingPeriod.equals(from.getBillingPeriod())) &&
-				(toProduct           == null || toProduct.equals(catalog.getProductFromName(to.getProductName()))) &&
+				(toProduct           == null || toProduct.equals(catalog.findProduct(to.getProductName()))) &&
 				(toProductCategory   == null || toProductCategory.equals(to.getProductCategory())) &&
 				(toBillingPeriod     == null || toBillingPeriod.equals(to.getBillingPeriod())) &&
 				(fromPriceList       == null || fromPriceList.equals(catalog.getPriceListFromName(from.getPriceListName()))) &&
@@ -87,7 +83,7 @@ public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
 	}
 	
 	static public <K> K getResult(CaseChange<K>[] cases, PlanPhaseSpecifier from,
-			PlanSpecifier to, Catalog catalog) {
+			PlanSpecifier to, StandaloneCatalog catalog) throws CatalogApiException {
     	if(cases != null) {
     		for(CaseChange<K> cc : cases) {
     			K result = cc.getResult(from, to, catalog);
@@ -101,7 +97,7 @@ public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
     }
 	
 	@Override
-	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
+	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
 		return errors;
 	}
 
@@ -110,7 +106,7 @@ public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
 		return this;
 	}
 
-	protected CaseChange<T> setFromProduct(Product fromProduct) {
+	protected CaseChange<T> setFromProduct(DefaultProduct fromProduct) {
 		this.fromProduct = fromProduct;
 		return this;
 	}
@@ -125,12 +121,12 @@ public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
 		return this;
 	}
 
-	protected CaseChange<T> setFromPriceList(PriceList fromPriceList) {
+	protected CaseChange<T> setFromPriceList(DefaultPriceList fromPriceList) {
 		this.fromPriceList = fromPriceList;
 		return this;
 	}
 
-	protected CaseChange<T> setToProduct(Product toProduct) {
+	protected CaseChange<T> setToProduct(DefaultProduct toProduct) {
 		this.toProduct = toProduct;
 		return this;
 	}
@@ -145,7 +141,7 @@ public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
 		return this;
 	}
 
-	protected CaseChange<T> setToPriceList(PriceList toPriceList) {
+	protected CaseChange<T> setToPriceList(DefaultPriceList toPriceList) {
 		this.toPriceList = toPriceList;
 		return this;
 	}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java
index afd6d4b..1a3b0b5 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java
@@ -16,24 +16,21 @@
 
 package com.ning.billing.catalog.rules;
 
-import javax.xml.bind.annotation.XmlElement;
-
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.PriceList;
-import com.ning.billing.catalog.Product;
-import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PlanSpecifier;
-import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.util.config.ValidationErrors;
 
+import javax.xml.bind.annotation.XmlElement;
+
 public abstract class CasePhase<T> extends CaseStandardNaming<T> {
 
 	@XmlElement(required=false)
 	private PhaseType phaseType;	
 	
-	public T getResult(PlanPhaseSpecifier specifier, Catalog c) {
+	public T getResult(PlanPhaseSpecifier specifier, StandaloneCatalog c) throws CatalogApiException {
 		if (	
 				(phaseType       == null || specifier.getPhaseType() == null || specifier.getPhaseType() == phaseType) &&
 				satisfiesCase(new PlanSpecifier(specifier), c)
@@ -43,7 +40,7 @@ public abstract class CasePhase<T> extends CaseStandardNaming<T> {
 		return null;
 	}
 	
-	public static <K> K getResult(CasePhase<K>[] cases, PlanPhaseSpecifier planSpec, Catalog catalog) {
+	public static <K> K getResult(CasePhase<K>[] cases, PlanPhaseSpecifier planSpec, StandaloneCatalog catalog) throws CatalogApiException {
     	if(cases != null) {
     		for(CasePhase<K> cp : cases) {
     			K result = cp.getResult(planSpec, catalog);
@@ -57,7 +54,7 @@ public abstract class CasePhase<T> extends CaseStandardNaming<T> {
     }
 
 	@Override
-	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
+	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
 		return errors;
 	}
 
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CasePriceList.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CasePriceList.java
index 2e155f8..fbb9cab 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CasePriceList.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CasePriceList.java
@@ -16,21 +16,21 @@
 
 package com.ning.billing.catalog.rules;
 
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlIDREF;
-
-import com.ning.billing.catalog.PriceList;
-import com.ning.billing.catalog.Product;
+import com.ning.billing.catalog.DefaultPriceList;
+import com.ning.billing.catalog.DefaultProduct;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
 
-public class CasePriceList extends Case<PriceList> {
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlIDREF;
+
+public class CasePriceList extends Case<DefaultPriceList> {
 
-	private PriceList toPriceList;
+	private DefaultPriceList toPriceList;
 
 	@XmlElement(required=false, name="fromProduct")
 	@XmlIDREF
-	public Product getProduct(){
+	public DefaultProduct getProduct(){
 		return product;
 	}
 
@@ -46,18 +46,18 @@ public class CasePriceList extends Case<PriceList> {
 	
 	@XmlElement(required=false, name="fromPriceList")
 	@XmlIDREF
-	public PriceList getPriceList() {
+	public DefaultPriceList getPriceList() {
 		return priceList;
 	}
 
 	@Override
 	@XmlElement(required=true, name="toPriceList")
 	@XmlIDREF
-	protected PriceList getResult() {
+	protected DefaultPriceList getResult() {
 		return toPriceList;
 	}
 
-	protected CasePriceList setToPriceList(PriceList toPriceList) {
+	protected CasePriceList setToPriceList(DefaultPriceList toPriceList) {
 		this.toPriceList = toPriceList;
 		return this;
 	}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseStandardNaming.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseStandardNaming.java
index f74a48d..cf61fcd 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseStandardNaming.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseStandardNaming.java
@@ -16,19 +16,19 @@
 
 package com.ning.billing.catalog.rules;
 
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlIDREF;
-
-import com.ning.billing.catalog.PriceList;
-import com.ning.billing.catalog.Product;
+import com.ning.billing.catalog.DefaultPriceList;
+import com.ning.billing.catalog.DefaultProduct;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
 
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlIDREF;
+
 public abstract class CaseStandardNaming<T> extends Case<T> {
 
 	@XmlElement(required=false, name="product")
 	@XmlIDREF
-	public Product getProduct(){
+	public DefaultProduct getProduct(){
 		return product;
 	}
 
@@ -44,7 +44,7 @@ public abstract class CaseStandardNaming<T> extends Case<T> {
 	
 	@XmlElement(required=false, name="priceList")
 	@XmlIDREF
-	public PriceList getPriceList() {
+	public DefaultPriceList getPriceList() {
 		return priceList;
 	}
 
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java b/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java
index 787dbaf..54aa5c7 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java
@@ -16,27 +16,19 @@
 
 package com.ning.billing.catalog.rules;
 
+import com.ning.billing.catalog.DefaultPriceList;
+import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.api.*;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
+
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.PriceList;
-import com.ning.billing.catalog.api.ActionPolicy;
-import com.ning.billing.catalog.api.BillingAlignment;
-import com.ning.billing.catalog.api.IllegalPlanChange;
-import com.ning.billing.catalog.api.PlanAlignmentChange;
-import com.ning.billing.catalog.api.PlanAlignmentCreate;
-import com.ning.billing.catalog.api.PlanChangeResult;
-import com.ning.billing.catalog.api.PlanPhaseSpecifier;
-import com.ning.billing.catalog.api.PlanSpecifier;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.util.config.ValidatingConfig;
-import com.ning.billing.util.config.ValidationErrors;
-
 @XmlAccessorType(XmlAccessType.NONE)
-public class PlanRules extends ValidatingConfig<Catalog>  {
+public class PlanRules extends ValidatingConfig<StandaloneCatalog>  {
 
 	@XmlElementWrapper(name="changePolicy")
 	@XmlElement(name="changePolicyCase", required=false)
@@ -62,20 +54,20 @@ public class PlanRules extends ValidatingConfig<Catalog>  {
 	@XmlElement(name="priceListCase", required=false)
 	private CasePriceList[] priceListCase;
 
-	public PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier, Catalog catalog) {
+	public PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier, StandaloneCatalog catalog) throws CatalogApiException {
 		return Case.getResult(createAlignmentCase, specifier, catalog);      
     }
 	
-	public ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase, Catalog catalog) {
+	public ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase, StandaloneCatalog catalog) throws CatalogApiException {
 		return CasePhase.getResult(cancelCase, planPhase, catalog);      
 	}
 
-	public BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase, Catalog catalog) {
+	public BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase, StandaloneCatalog catalog) throws CatalogApiException {
 		return CasePhase.getResult(billingAlignmentCase, planPhase, catalog);      
 	}
 
-	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to, Catalog catalog) throws IllegalPlanChange {
-		PriceList priceList = catalog.getPriceListFromName(to.getPriceListName());
+	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to, StandaloneCatalog catalog) throws CatalogApiException {
+		DefaultPriceList priceList = catalog.getPriceListFromName(to.getPriceListName());
 		if( priceList== null ) {
 			priceList = findPriceList(from.toPlanSpecifier(), catalog);
 			to = new PlanSpecifier(to.getProductName(), to.getProductCategory(), to.getBillingPeriod(), priceList.getName());
@@ -92,12 +84,12 @@ public class PlanRules extends ValidatingConfig<Catalog>  {
 	}
 	
 	public PlanAlignmentChange getPlanChangeAlignment(PlanPhaseSpecifier from,
-			PlanSpecifier to, Catalog catalog) {
+			PlanSpecifier to, StandaloneCatalog catalog) throws CatalogApiException {
 		return CaseChange.getResult(changeAlignmentCase, from, to, catalog);      
     }
 
 	public ActionPolicy getPlanChangePolicy(PlanPhaseSpecifier from,
-			PlanSpecifier to, Catalog catalog) {
+			PlanSpecifier to, StandaloneCatalog catalog) throws CatalogApiException {
 		if(from.getProductName().equals(to.getProductName()) &&
 				from.getBillingPeriod() == to.getBillingPeriod() &&
 				from.getPriceListName().equals(to.getPriceListName())) {
@@ -107,8 +99,8 @@ public class PlanRules extends ValidatingConfig<Catalog>  {
 		return CaseChange.getResult(changeCase, from, to, catalog); 
 	}
 	
-	private PriceList findPriceList(PlanSpecifier specifier, Catalog catalog) {
-		PriceList result = Case.getResult(priceListCase, specifier, catalog);
+	private DefaultPriceList findPriceList(PlanSpecifier specifier, StandaloneCatalog catalog) throws CatalogApiException {
+		DefaultPriceList result = Case.getResult(priceListCase, specifier, catalog);
 		if (result == null) {
 			result = catalog.getPriceListFromName(specifier.getPriceListName());
 		}
@@ -117,7 +109,7 @@ public class PlanRules extends ValidatingConfig<Catalog>  {
 	
 	
 	@Override
-	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
+	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
 	    //TODO: MDW - Validation: check that the plan change special case pairs are unique!
 	    //TODO: MDW - Validation: check that the each product appears in at most one tier.
 		//TODO: MDW - Unit tests for rules
diff --git a/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java b/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
index cb447ea..88a7dd4 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
@@ -15,46 +15,31 @@
  */
 package com.ning.billing.catalog;
 
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-
-import com.ning.billing.catalog.api.ActionPolicy;
-import com.ning.billing.catalog.api.BillingAlignment;
-import com.ning.billing.catalog.api.BillingPeriod;
+import com.google.inject.Inject;
+import com.ning.billing.catalog.api.*;
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.catalog.api.ICatalog;
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.catalog.api.IPlanPhase;
-import com.ning.billing.catalog.api.IProduct;
-import com.ning.billing.catalog.api.IllegalPlanChange;
-import com.ning.billing.catalog.api.PlanAlignmentChange;
-import com.ning.billing.catalog.api.PlanAlignmentCreate;
-import com.ning.billing.catalog.api.PlanChangeResult;
-import com.ning.billing.catalog.api.PlanPhaseSpecifier;
-import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationErrors;
 
-public class VersionedCatalog extends ValidatingConfig<Catalog> implements ICatalog {
+import java.net.URI;
+import java.util.*;
+
+public class VersionedCatalog extends ValidatingConfig<StandaloneCatalog> implements Catalog {
 	
-	private Catalog currentCatalog;
+	private StandaloneCatalog currentCatalog;
 	
-	private final List<Catalog> versions = new ArrayList<Catalog>();
+	private final List<StandaloneCatalog> versions = new ArrayList<StandaloneCatalog>();
 	
+	@Inject
 	public VersionedCatalog() {
-		Catalog baseline = new Catalog(new Date(0)); // init with an empty catalog may need to 
+		StandaloneCatalog baseline = new StandaloneCatalog(new Date(0)); // init with an empty catalog may need to 
 													 // populate some empty pieces here to make validation work
-		add(baseline);
+		add(baseline); 
 	}
 	
-	private Catalog versionForDate(Date date) {
-		Catalog previous = versions.get(0);
-		for(Catalog c : versions) {
+	private StandaloneCatalog versionForDate(Date date) {
+		StandaloneCatalog previous = versions.get(0);
+		for(StandaloneCatalog c : versions) {
 			if(c.getEffectiveDate().getTime() > date.getTime()) {
 				return previous;
 			}
@@ -63,20 +48,20 @@ public class VersionedCatalog extends ValidatingConfig<Catalog> implements ICata
 		return versions.get(versions.size() - 1);
 	}
 
-	public void add(Catalog e) {
+	public void add(StandaloneCatalog e) {
 		if(currentCatalog == null) {
 			currentCatalog = e;
 		}
 		versions.add(e);
-		Collections.sort(versions,new Comparator<Catalog>() {
+		Collections.sort(versions,new Comparator<StandaloneCatalog>() {
 			@Override
-			public int compare(Catalog c1, Catalog c2) {
+			public int compare(StandaloneCatalog c1, StandaloneCatalog c2) {
 				return c1.getEffectiveDate().compareTo(c2.getEffectiveDate());
 			}
 		});
 	}
 
-	public Iterator<Catalog> iterator() {
+	public Iterator<StandaloneCatalog> iterator() {
 		return versions.iterator();
 	}
 	
@@ -90,103 +75,96 @@ public class VersionedCatalog extends ValidatingConfig<Catalog> implements ICata
 	}
 
 	@Override
-	public Product[] getProducts() {
+	public DefaultProduct[] getProducts() {
 		return currentCatalog.getProducts();
 	}
 
 	@Override
-	public IPlan getPlan(String productName, BillingPeriod term,
-			String planSetName) {
-		return currentCatalog.getPlan(productName, term, planSetName);
-	}
-
-	@Override
 	public Currency[] getSupportedCurrencies() {
 		return currentCatalog.getSupportedCurrencies();
 	}
 
 	@Override
-	public Plan[] getPlans() {
+	public DefaultPlan[] getPlans() {
 		return currentCatalog.getPlans();
 	}
 
 	@Override
-	public Plan getPlanFromName(String name) {
-		return currentCatalog.getPlanFromName(name);
+	public Date getEffectiveDate() {
+		return currentCatalog.getEffectiveDate();
+	}
+
+	@Override
+	public Plan findPlan(String productName, BillingPeriod term,
+			String planSetName) throws CatalogApiException {
+		return currentCatalog.findPlan(productName, term, planSetName);
 	}
 
+	@Override
+	public DefaultPlan findPlan(String name) throws CatalogApiException {
+		return currentCatalog.findPlan(name);
+	}
 
 	@Override
-	public IPlanPhase getPhaseFromName(String name) {
-		return currentCatalog.getPhaseFromName(name);
+	public PlanPhase findPhase(String name) throws CatalogApiException {
+		return currentCatalog.findPhase(name);
 	}
 
 	@Override
-	public Date getEffectiveDate() {
-		return currentCatalog.getEffectiveDate();
+	public Product findProduct(String name) throws CatalogApiException {
+		return currentCatalog.findProduct(name);
 	}
 
 	@Override
-	public void initialize(Catalog catalog, URI sourceURI) {
-		for(Catalog c : versions) {
+	public void initialize(StandaloneCatalog catalog, URI sourceURI) {
+		for(StandaloneCatalog c : versions) {
 			c.initialize(catalog, sourceURI);
 		}
 	}
 
 	@Override
-	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
-		for(Catalog c : versions) {
+	public ValidationErrors validate(StandaloneCatalog catalog, ValidationErrors errors) {
+		for(StandaloneCatalog c : versions) {
 			errors.addAll(c.validate(c, errors));
 		}
 		return errors;
 	}
 	
 	@Override
-    public PlanPhase getPhaseFor(String name, Date date) {
-    	Catalog c = versionForDate(date);
-    	return c.getPhaseFromName(name);
-    }
-
-	@Override
-	public ActionPolicy getPlanChangePolicy(PlanPhaseSpecifier from,
-			PlanSpecifier to) {
-		return currentCatalog.getPlanChangePolicy(from, to);
-	}
-
-	@Override
-	public IProduct getProductFromName(String name) {
-		return currentCatalog.getProductFromName(name);
+	public ActionPolicy planChangePolicy(PlanPhaseSpecifier from,
+			PlanSpecifier to) throws CatalogApiException {
+		return currentCatalog.planChangePolicy(from, to);
 	}
 
 	@Override
-	public ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase) {
-		return currentCatalog.getPlanCancelPolicy(planPhase);
+	public ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase) throws CatalogApiException {
+		return currentCatalog.planCancelPolicy(planPhase);
 	}
 
 	@Override
-	public PlanAlignmentChange getPlanChangeAlignment(PlanPhaseSpecifier from,
-			PlanSpecifier to) {
-		return currentCatalog.getPlanChangeAlignment(from, to);
+	public PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from,
+			PlanSpecifier to) throws CatalogApiException {
+		return currentCatalog.planChangeAlignment(from, to);
 	}
 
 	@Override
-	public PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier) {
-		return currentCatalog.getPlanCreateAlignment(specifier);
+	public PlanAlignmentCreate planCreateAlignment(PlanSpecifier specifier) throws CatalogApiException {
+		return currentCatalog.planCreateAlignment(specifier);
 	}
 
 	@Override
-	public String getCalalogName() {
-		return currentCatalog.getCalalogName();
+	public String getCatalogName() {
+		return currentCatalog.getCatalogName();
 	}
 
 	@Override
-	public BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase) {
-		return currentCatalog.getBillingAlignment(planPhase);
+	public BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase) throws CatalogApiException {
+		return currentCatalog.billingAlignment(planPhase);
 	}
 
 	@Override
 	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to)
-			throws IllegalPlanChange {
+			throws CatalogApiException {
 		return currentCatalog.planChange(from, to);
 	}
 	
diff --git a/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java b/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java
index 3aae7fb..4367c9a 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java
@@ -16,13 +16,12 @@
 
 package com.ning.billing.catalog;
 
+import com.ning.billing.util.config.XMLSchemaGenerator;
+
 import java.io.File;
 import java.io.FileWriter;
 import java.io.Writer;
 
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.util.config.XMLSchemaGenerator;
-
 public class CreateCatalogSchema {
 
 	/**
@@ -36,7 +35,7 @@ public class CreateCatalogSchema {
 		
 		File f = new File(args[0]);
 		Writer w = new FileWriter(f);
-		w.write(XMLSchemaGenerator.xmlSchemaAsString(Catalog.class));
+		w.write(XMLSchemaGenerator.xmlSchemaAsString(StandaloneCatalog.class));
 		w.close();
 
 	}
diff --git a/catalog/src/test/java/com/ning/billing/catalog/io/TestVersionedCatalogLoader.java b/catalog/src/test/java/com/ning/billing/catalog/io/TestVersionedCatalogLoader.java
index 0035bc8..9708b99 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/io/TestVersionedCatalogLoader.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/io/TestVersionedCatalogLoader.java
@@ -15,47 +15,39 @@
  */
 package com.ning.billing.catalog.io;
 
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertTrue;
+import com.google.common.io.Resources;
+import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.VersionedCatalog;
+import com.ning.billing.catalog.api.InvalidConfigException;
+import com.ning.billing.lifecycle.KillbillService.ServiceException;
+import com.ning.billing.util.clock.DefaultClock;
+import org.joda.time.DateTime;
+import org.testng.annotations.Test;
+import org.xml.sax.SAXException;
 
+import javax.xml.bind.JAXBException;
+import javax.xml.transform.TransformerException;
 import java.io.IOException;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Iterator;
 import java.util.List;
 
-import javax.xml.bind.JAXBException;
-import javax.xml.transform.TransformerException;
-
-import org.joda.time.DateTime;
-import org.testng.annotations.Test;
-import org.xml.sax.SAXException;
-
-import com.google.common.io.Resources;
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.VersionedCatalog;
-import com.ning.billing.catalog.api.InvalidConfigException;
+import static org.testng.AssertJUnit.assertEquals;
 
 public class TestVersionedCatalogLoader {
-	private final VersionedCatalogLoader loader = new VersionedCatalogLoader();
-
+	private final VersionedCatalogLoader loader = new VersionedCatalogLoader(new DefaultClock());
 
-	@Test(enabled=true)
-	public void testPullContentsFrom() throws MalformedURLException, IOException {
-		String contents = loader.pullContentsFrom(Resources.getResource("WeaponsHireSmall.xml"));
-
-		assertTrue(contents.length() > 0);
-		
-	}
 	
 	@Test(enabled=true)
-	public void testAppendToURL() throws MalformedURLException, IOException {
+	public void testAppendToURI() throws MalformedURLException, IOException, URISyntaxException {
 		URL u1 = new URL("http://www.ning.com/foo");
-		assertEquals("http://www.ning.com/foo/bar",loader.appendToURL(u1, "bar").toString());
+		assertEquals("http://www.ning.com/foo/bar",loader.appendToURI(u1, "bar").toString());
 
 		URL u2 = new URL("http://www.ning.com/foo/");
-		assertEquals("http://www.ning.com/foo/bar",loader.appendToURL(u2, "bar").toString());
+		assertEquals("http://www.ning.com/foo/bar",loader.appendToURI(u2, "bar").toString());
 		
 	}
 	
@@ -63,12 +55,12 @@ public class TestVersionedCatalogLoader {
 
 	
 	@Test(enabled=true)
-	public void testFindXmlFileReferences() throws MalformedURLException {
+	public void testFindXmlFileReferences() throws MalformedURLException, URISyntaxException {
 		String page = "dg.xml\n" + 
 				"replica.foo\n" + 
 				"snv1/\n" + 
 				"viking.xml\n" ;
-		List<URL> urls = loader.findXmlFileReferences(page, new URL("http://ning.com/"));
+		List<URI> urls = loader.findXmlFileReferences(page, new URL("http://ning.com/"));
 		assertEquals(2, urls.size());
 		assertEquals("http://ning.com/dg.xml", urls.get(0).toString());
 		assertEquals("http://ning.com/viking.xml", urls.get(1).toString());
@@ -101,7 +93,7 @@ public class TestVersionedCatalogLoader {
 	}
 	
 	@Test(enabled=true)
-	public void testFindXmlUrlReferences() throws MalformedURLException {
+	public void testFindXmlUrlReferences() throws MalformedURLException, URISyntaxException {
 		String page = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">" + 
 				"<html>" + 
 				" <head>" + 
@@ -119,18 +111,18 @@ public class TestVersionedCatalogLoader {
 				"</ul>" + 
 				"<address>Apache/2.2.3 (CentOS) Server at <a href=\"mailto:kate@ning.com\">gepo.ningops.net</a> Port 80</address>" + 
 				"</body></html>" ;
-		List<URL> urls = loader.findXmlUrlReferences(page, new URL("http://ning.com/"));
-		assertEquals(2, urls.size());
-		assertEquals("http://ning.com/dg.xml", urls.get(0).toString());
-		assertEquals("http://ning.com/viking.xml", urls.get(1).toString());
+		List<URI> uris = loader.findXmlUrlReferences(page, new URL("http://ning.com/"));
+		assertEquals(2, uris.size());
+		assertEquals("http://ning.com/dg.xml", uris.get(0).toString());
+		assertEquals("http://ning.com/viking.xml", uris.get(1).toString());
 		
 	}
 	
 	@Test(enabled=true)
-	public void testLoad() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
-		VersionedCatalog c = loader.load(Resources.getResource("versionedCatalog"));
+	public void testLoad() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException {
+		VersionedCatalog c = loader.load(Resources.getResource("versionedCatalog").toString());
 		assertEquals(4, c.size());
-		Iterator<Catalog> it = c.iterator();
+		Iterator<StandaloneCatalog> it = c.iterator();
 		it.next(); //discard the baseline
 		DateTime dt = new DateTime("2011-01-01T00:00:00+00:00");
 		assertEquals(dt.toDate(),it.next().getEffectiveDate());
diff --git a/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java b/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java
index a75cb06..77f7248 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java
@@ -16,26 +16,17 @@
 
 package com.ning.billing.catalog.io;
 
-import java.io.IOException;
-import java.net.URISyntaxException;
-
-import javax.xml.bind.JAXBException;
-import javax.xml.transform.TransformerException;
-
-import org.testng.annotations.Test;
-import org.xml.sax.SAXException;
-
 import com.google.common.io.Resources;
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.api.InvalidConfigException; 
+import com.ning.billing.catalog.StandaloneCatalog;
 import com.ning.billing.util.config.XMLLoader;
+import org.testng.annotations.Test;
 
 public class TestXMLReader {
 
 	@Test(enabled=true)
-	public void testCatalogLoad() throws IOException, TransformerException, JAXBException, SAXException, InvalidConfigException, URISyntaxException {
-		XMLLoader.getObjectFromURL(Resources.getResource("WeaponsHire.xml"), Catalog.class);
-		XMLLoader.getObjectFromURL(Resources.getResource("WeaponsHireSmall.xml"), Catalog.class);
+	public void testCatalogLoad() throws Exception {
+		XMLLoader.getObjectFromString(Resources.getResource("WeaponsHire.xml").toExternalForm(), StandaloneCatalog.class);
+		XMLLoader.getObjectFromString(Resources.getResource("WeaponsHireSmall.xml").toExternalForm(), StandaloneCatalog.class);
 	}
 	
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java b/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
index c561457..089c1e4 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
@@ -16,17 +16,18 @@
 
 package com.ning.billing.catalog;
 
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.catalog.rules.CaseCancelPolicy;
-import com.ning.billing.catalog.rules.CaseChangePlanAlignment;
-import com.ning.billing.catalog.rules.CaseChangePlanPolicy;
-import com.ning.billing.catalog.rules.CaseCreateAlignment;
-import com.ning.billing.catalog.rules.PlanRules;
+import com.ning.billing.catalog.rules.*;
 
-public class MockCatalog extends Catalog {
+import java.util.Date;
+
+public class MockCatalog extends StandaloneCatalog {
 	private static final String[] PRODUCT_NAMES = new String[]{ "TestProduct1", "TestProduct2", "TestProduct3"};
 	
 	public MockCatalog() {
+		setEffectiveDate(new Date());
 		populateProducts();
 		populateRules();
 		populatePlans();
@@ -48,31 +49,32 @@ public class MockCatalog extends Catalog {
 
 	public void populateProducts() {
 		String[] names = getProductNames();
-		Product[] products = new Product[names.length];
+		DefaultProduct[] products = new DefaultProduct[names.length];
 		for(int i = 0; i < names.length; i++) {
-			products[i] = new Product(names[i], ProductCategory.BASE);
+			products[i] = new DefaultProduct(names[i], ProductCategory.BASE);
 		}
 		setProducts(products);
 	}
 	
 	public void populatePlans() {
-		Product[] products = getProducts();
-		Plan[] plans = new Plan[products.length];
+		DefaultProduct[] products = getProducts();
+		DefaultPlan[] plans = new DefaultPlan[products.length];
 		for(int i = 0; i < products.length; i++) {
-			plans[i] = new MockPlan().setName(products[i].getName().toLowerCase() + "-plan").setProduct(products[i]);
+			DefaultPlanPhase phase = new DefaultPlanPhase().setPhaseType(PhaseType.EVERGREEN).setBillingPeriod(BillingPeriod.MONTHLY).setReccuringPrice(new DefaultInternationalPrice());
+			plans[i] = new MockPlan().setName(products[i].getName().toLowerCase() + "-plan").setProduct(products[i]).setFinalPhase(phase);
 		}
 		setPlans(plans);
 	}
 
 	public void populatePriceLists() {
-		Plan[] plans = getPlans();
+		DefaultPlan[] plans = getPlans();
 		
-		PriceList[] priceList = new PriceList[plans.length - 1];
+		DefaultPriceList[] priceList = new DefaultPriceList[plans.length - 1];
 		for(int i = 1; i < plans.length; i++) {
-			priceList[i-1] = new PriceList(new Plan[]{plans[i]},plans[i].getName()+ "-pl");
+			priceList[i-1] = new DefaultPriceList(new DefaultPlan[]{plans[i]},plans[i].getName()+ "-pl");
 		}
 		
-		PriceListSet set = new PriceListSet(new PriceListDefault(new Plan[]{plans[0]}),priceList);
+		DefaultPriceListSet set = new DefaultPriceListSet(new PriceListDefault(new DefaultPlan[]{plans[0]}),priceList);
 		setPriceLists(set);
 	}
 	
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java b/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java
index cd9afbe..5d1af74 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockInternationalPrice.java
@@ -16,26 +16,26 @@
 
 package com.ning.billing.catalog;
 
+import com.ning.billing.catalog.api.Currency;
+
 import java.math.BigDecimal;
 import java.util.Date;
 
-import com.ning.billing.catalog.api.Currency;
-
-public class MockInternationalPrice extends InternationalPrice {
+public class MockInternationalPrice extends DefaultInternationalPrice {
 	
 	MockInternationalPrice() {
 		setEffectiveDateForExistingSubscriptons(new Date());
-		setPrices(new Price[] {
-			new Price().setCurrency(Currency.USD).setValue(new BigDecimal(1))	
+		setPrices(new DefaultPrice[] {
+			new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(1))	
 		});
 	}
 	
-	MockInternationalPrice(Date effectiveDateForExistingSubscriptions, Price[] price) {
+	MockInternationalPrice(Date effectiveDateForExistingSubscriptions, DefaultPrice[] price) {
 		setEffectiveDateForExistingSubscriptons(effectiveDateForExistingSubscriptions);
 		setPrices(price);
 	}
 
-	MockInternationalPrice(Price... price) {
+	MockInternationalPrice(DefaultPrice... price) {
 		setEffectiveDateForExistingSubscriptons(new Date());
 		setPrices(price);
 	}
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockPlan.java b/catalog/src/test/java/com/ning/billing/catalog/MockPlan.java
index cf5324d..b9e9afe 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockPlan.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockPlan.java
@@ -16,9 +16,9 @@
 
 package com.ning.billing.catalog;
 
-public class MockPlan extends Plan {
+public class MockPlan extends DefaultPlan {
 
-	public MockPlan(String name, Product product, PlanPhase[] planPhases, PlanPhase finalPhase, int plansAllowedInBundle) {
+	public MockPlan(String name, DefaultProduct product, DefaultPlanPhase[] planPhases, DefaultPlanPhase finalPhase, int plansAllowedInBundle) {
 		setName(name);
 		setProduct(product);
 		setFinalPhase(finalPhase);
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java b/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
index ede4319..fb244eb 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockPlanPhase.java
@@ -20,14 +20,14 @@ import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.TimeUnit;
 
-public class MockPlanPhase extends PlanPhase {
+public class MockPlanPhase extends DefaultPlanPhase {
 
     public MockPlanPhase(
     		BillingPeriod billingPeriod, 
     		PhaseType type, 
-    		Duration duration, 
-    		InternationalPrice recurringPrice, 
-    		InternationalPrice fixedPrice) {
+    		DefaultDuration duration, 
+    		DefaultInternationalPrice recurringPrice, 
+    		DefaultInternationalPrice fixedPrice) {
 		setBillingPeriod(billingPeriod);
 		setPhaseType(type);
 		setDuration(duration);
@@ -38,7 +38,7 @@ public class MockPlanPhase extends PlanPhase {
     public MockPlanPhase() {
 		setBillingPeriod(BillingPeriod.MONTHLY);
 		setPhaseType(PhaseType.EVERGREEN);
-		setDuration(new Duration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
+		setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
 		setReccuringPrice(new MockInternationalPrice());
 		setFixedPrice(null);
 		setPlan(new MockPlan(this));
@@ -47,7 +47,7 @@ public class MockPlanPhase extends PlanPhase {
 	public MockPlanPhase(MockPlan mockPlan) {
 		setBillingPeriod(BillingPeriod.MONTHLY);
 		setPhaseType(PhaseType.EVERGREEN);
-		setDuration(new Duration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
+		setDuration(new DefaultDuration().setNumber(-1).setUnit(TimeUnit.UNLIMITED));
 		setReccuringPrice(new MockInternationalPrice());
 		setFixedPrice(null);
 		setPlan(mockPlan);
diff --git a/catalog/src/test/java/com/ning/billing/catalog/MockProduct.java b/catalog/src/test/java/com/ning/billing/catalog/MockProduct.java
index 11620a0..7587dba 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockProduct.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockProduct.java
@@ -18,7 +18,7 @@ package com.ning.billing.catalog;
 
 import com.ning.billing.catalog.api.ProductCategory;
 
-public class MockProduct extends Product {
+public class MockProduct extends DefaultProduct {
 
 	public MockProduct() {
 		setName("TestProduct");
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java
index 3cd031b..c00f1c4 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java
@@ -16,22 +16,17 @@
 
 package com.ning.billing.catalog.rules;
 
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNull;
+import com.ning.billing.catalog.DefaultPriceList;
+import com.ning.billing.catalog.DefaultProduct;
+import com.ning.billing.catalog.MockCatalog;
+import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.api.*;
+import org.testng.annotations.Test;
 
 import javax.xml.bind.annotation.XmlElement;
 
-import org.testng.annotations.Test;
-
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.MockCatalog;
-import com.ning.billing.catalog.PriceList;
-import com.ning.billing.catalog.Product;
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IPriceListSet;
-import com.ning.billing.catalog.api.PlanSpecifier;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.catalog.rules.Case;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
 
 public class TestCase {
 
@@ -40,7 +35,7 @@ public class TestCase {
 		@XmlElement(required=true)
 		private Result policy;
 
-		public CaseResult(Product product, ProductCategory productCategory, BillingPeriod billingPeriod, PriceList priceList,
+		public CaseResult(DefaultProduct product, ProductCategory productCategory, BillingPeriod billingPeriod, DefaultPriceList priceList,
 				 Result policy) {
 			setProduct(product);
 			setProductCategory(productCategory);
@@ -56,11 +51,11 @@ public class TestCase {
 	}
 
 	@Test(enabled=true)
-	public void testBasic(){
+	public void testBasic() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
 		CaseResult cr = new CaseResult(
@@ -71,18 +66,18 @@ public class TestCase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-		assertionNull(cr, "lala", ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+		assertionNull(cr, cat.getProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
 	}
 
 	@Test(enabled=true)
-	public void testWildCardProduct(){
+	public void testWildCardProduct() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
 		CaseResult cr = new CaseResult(
@@ -94,18 +89,18 @@ public class TestCase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
-		assertion(Result.FOO, cr,"lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
+		assertion(Result.FOO, cr, cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
 	}
 	
 	@Test(enabled=true)
-	public void testWildCardProductCategory(){
+	public void testWildCardProductCategory() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
 		CaseResult cr = new CaseResult(
@@ -117,18 +112,18 @@ public class TestCase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-		assertionNull(cr, "lala", ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
 	}
 	
 	@Test(enabled=true)
-	public void testWildCardBillingPeriod(){
+	public void testWildCardBillingPeriod() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
 		CaseResult cr = new CaseResult(
@@ -140,18 +135,18 @@ public class TestCase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-		assertionNull(cr, "lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertion(Result.FOO,cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
 	}
 
 	@Test(enabled=true)
-	public void testWildCardPriceList(){
+	public void testWildCardPriceList() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
 		CaseResult cr = new CaseResult(
@@ -163,18 +158,18 @@ public class TestCase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
-		assertionNull(cr, "lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
 	}
 	
 	@Test
-	public void testCaseOrder() {
+	public void testCaseOrder() throws CatalogApiException {
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
 
 		CaseResult cr0 = new CaseResult(
@@ -217,11 +212,11 @@ public class TestCase {
 	
 
 
-	protected void assertionNull(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, Catalog cat){
+	protected void assertionNull(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, StandaloneCatalog cat) throws CatalogApiException{
 		assertNull(cr.getResult(new PlanSpecifier(productName, productCategory, bp, priceListName), cat));
 	}
 
-	protected void assertion(Result result, CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName,Catalog cat){
+	protected void assertion(Result result, CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName,StandaloneCatalog cat) throws CatalogApiException{
 		assertEquals(result, cr.getResult(new PlanSpecifier(productName, productCategory, bp, priceListName), cat));
 	}
 
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java
index 34f055d..af13162 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java
@@ -16,23 +16,18 @@
 
 package com.ning.billing.catalog.rules;
 
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNull;
+import com.ning.billing.catalog.DefaultPriceList;
+import com.ning.billing.catalog.DefaultProduct;
+import com.ning.billing.catalog.MockCatalog;
+import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.api.*;
+import org.testng.Assert;
+import org.testng.annotations.Test;
 
 import javax.xml.bind.annotation.XmlElement;
 
-import org.testng.annotations.Test;
-
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.MockCatalog;
-import com.ning.billing.catalog.PriceList;
-import com.ning.billing.catalog.Product;
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IPriceListSet;
-import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.catalog.api.PlanPhaseSpecifier;
-import com.ning.billing.catalog.api.PlanSpecifier;
-import com.ning.billing.catalog.api.ProductCategory;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
 
 public class TestCaseChange {
 	protected static class CaseChangeResult extends CaseChange<Result>  {
@@ -40,10 +35,10 @@ public class TestCaseChange {
 		@XmlElement(required=true)
 		private Result result;
 
-		public CaseChangeResult(Product from, Product to, 
+		public CaseChangeResult(DefaultProduct from, DefaultProduct to, 
 				ProductCategory fromProductCategory, ProductCategory toProductCategory, 
 				BillingPeriod fromBP, BillingPeriod toBP, 
-				PriceList fromPriceList, PriceList toPriceList,
+				DefaultPriceList fromPriceList, DefaultPriceList toPriceList,
 				PhaseType fromType, 
 				Result result) {
 			setFromProduct(from);
@@ -68,11 +63,11 @@ public class TestCaseChange {
 	public void testBasic(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -91,14 +86,14 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -136,14 +131,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -158,11 +153,11 @@ public class TestCaseChange {
 	public void testWildcardFromProduct(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -181,7 +176,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertion(Result.FOO,cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -202,7 +197,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -219,14 +214,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -241,11 +236,11 @@ public class TestCaseChange {
 	public void testWildcardToProduct(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -264,7 +259,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -285,7 +280,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertion(Result.FOO, cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -309,14 +304,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -331,11 +326,11 @@ public class TestCaseChange {
 	public void testWildcardFromProductCategory(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -354,14 +349,14 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -399,14 +394,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -421,11 +416,11 @@ public class TestCaseChange {
 	public void testWildcardToProductCategory(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -444,14 +439,14 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -489,14 +484,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -511,11 +506,11 @@ public class TestCaseChange {
 	public void testWildcardFromBillingPeriod(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -534,7 +529,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -555,7 +550,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -579,14 +574,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -602,11 +597,11 @@ public class TestCaseChange {
 	public void testWildCardToBillingPeriod(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -625,7 +620,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -646,7 +641,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -670,14 +665,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -692,11 +687,11 @@ public class TestCaseChange {
 	public void testWildCardFromPriceList(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -715,7 +710,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -736,7 +731,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -760,14 +755,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -782,11 +777,11 @@ public class TestCaseChange {
 	public void testWildcardToPriceList(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -805,7 +800,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -826,7 +821,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -850,14 +845,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertion(Result.FOO,cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -872,11 +867,11 @@ public class TestCaseChange {
 	public void testWildcardPlanPhase(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -895,7 +890,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -916,7 +911,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -940,14 +935,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertion(Result.FOO,cr, 
@@ -960,14 +955,14 @@ public class TestCaseChange {
 	
 	
 	@Test(enabled=true)
-	public void testOrder(){
+	public void testOrder() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
+		DefaultProduct product2 = cat.getProducts()[2];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr0 = new CaseChangeResult(
@@ -1030,9 +1025,13 @@ public class TestCaseChange {
 			ProductCategory fromProductCategory, ProductCategory toProductCategory, 
 			BillingPeriod fromBp, BillingPeriod toBp,
 			String fromPriceListName, String toPriceListName,
-			PhaseType phaseType, Catalog cat){
-		assertNull(cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory, fromBp, fromPriceListName, phaseType), 
-								new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat));
+			PhaseType phaseType, StandaloneCatalog cat){
+		try {
+			assertNull(cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory, fromBp, fromPriceListName, phaseType), 
+									new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat));
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
+		}
 	}
 
 	protected void assertion(Result result, CaseChangeResult cr, 
@@ -1040,9 +1039,13 @@ public class TestCaseChange {
 			ProductCategory fromProductCategory, ProductCategory toProductCategory, 
 			BillingPeriod fromBp, BillingPeriod toBp,
 			String fromPriceListName, String toPriceListName,
-			PhaseType phaseType, Catalog cat){
-		assertEquals(result, cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory,fromBp, fromPriceListName, phaseType), 
-								new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat));
+			PhaseType phaseType, StandaloneCatalog cat){
+		try {
+			assertEquals(result, cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory,fromBp, fromPriceListName, phaseType), 
+					new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat));
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
+		}
 	}
 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java
index 32c8354..fe505f4 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java
@@ -16,22 +16,15 @@
 
 package com.ning.billing.catalog.rules;
 
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNull;
-
-import javax.xml.bind.annotation.XmlElement;
-
+import com.ning.billing.catalog.DefaultPriceList;
+import com.ning.billing.catalog.DefaultProduct;
+import com.ning.billing.catalog.MockCatalog;
+import com.ning.billing.catalog.StandaloneCatalog;
+import com.ning.billing.catalog.api.*;
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.MockCatalog;
-import com.ning.billing.catalog.PriceList;
-import com.ning.billing.catalog.Product;
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.catalog.api.PlanPhaseSpecifier;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.catalog.rules.CasePhase;
+import javax.xml.bind.annotation.XmlElement;
 
 public class TestCasePhase {
 	protected class CaseResult extends CasePhase<Result>  {
@@ -39,7 +32,7 @@ public class TestCasePhase {
 		@XmlElement(required=true)
 		private Result policy;
 
-		public CaseResult(Product product, ProductCategory productCategory, BillingPeriod billingPeriod, PriceList priceList,
+		public CaseResult(DefaultProduct product, ProductCategory productCategory, BillingPeriod billingPeriod, DefaultPriceList priceList,
 				PhaseType phaseType, Result policy) {
 			setProduct(product);
 			setProductCategory(productCategory);
@@ -60,8 +53,8 @@ public class TestCasePhase {
 	public void testBasic(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -73,7 +66,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, "lala", ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -84,8 +77,8 @@ public class TestCasePhase {
 	public void testWildCardProduct(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -97,7 +90,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertion(Result.FOO, cr,"lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertion(Result.FOO, cr, cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -108,8 +101,8 @@ public class TestCasePhase {
 	public void testWildCardProductCategory(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -121,7 +114,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, "lala", ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -132,8 +125,8 @@ public class TestCasePhase {
 	public void testWildCardBillingPeriod(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -145,7 +138,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, "lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertion(Result.FOO,cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -156,8 +149,8 @@ public class TestCasePhase {
 	public void testWildCardPriceList(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -169,7 +162,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, "lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -180,8 +173,8 @@ public class TestCasePhase {
 	public void testWildCardPhaseType(){
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -193,7 +186,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, "lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -201,11 +194,11 @@ public class TestCasePhase {
 	}
 	
 	@Test(enabled=true)
-	public void testOrder(){
+	public void testOrder() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
-		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
+		DefaultProduct product = cat.getProducts()[0];
+		DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr0 = new CaseResult(
@@ -251,22 +244,30 @@ public class TestCasePhase {
 		Result r1 = CasePhase.getResult(new CaseResult[]{cr0, cr1, cr2,cr3,cr4}, 
 				new PlanPhaseSpecifier(product.getName(), product.getCategory(), BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN), cat);
 		
-		assertEquals(Result.FOO, r1);
+		Assert.assertEquals(Result.FOO, r1);
 
 		Result r2 = CasePhase.getResult(new CaseResult[]{cr0, cr1, cr2,cr3,cr4}, 
 				new PlanPhaseSpecifier(product.getName(), product.getCategory(), BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN), cat);
 		
-		assertEquals(Result.DIPSY, r2);
+		Assert.assertEquals(Result.DIPSY, r2);
 
 	}
 
 
-	protected void assertionNull(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, PhaseType phaseType, Catalog cat){
-		assertNull(cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+	protected void assertionNull(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, PhaseType phaseType, StandaloneCatalog cat){
+		try {
+			Assert.assertNull(cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
+		}
 	}
 
-	protected void assertion(Result result, CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, PhaseType phaseType, Catalog cat){
-		assertEquals(result, cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+	protected void assertion(Result result, CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, PhaseType phaseType, StandaloneCatalog cat){
+		try {
+			Assert.assertEquals(result, cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
+		}
 	}
 
 
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java
index fac41a2..e41d506 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java
@@ -16,26 +16,16 @@
 
 package com.ning.billing.catalog.rules;
 
-import junit.framework.Assert;
-
+import com.ning.billing.catalog.DefaultPriceList;
+import com.ning.billing.catalog.DefaultProduct;
+import com.ning.billing.catalog.MockCatalog;
+import com.ning.billing.catalog.api.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testng.Assert;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
-import com.ning.billing.catalog.MockCatalog;
-import com.ning.billing.catalog.PriceList;
-import com.ning.billing.catalog.Product;
-import com.ning.billing.catalog.api.ActionPolicy;
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IPriceListSet;
-import com.ning.billing.catalog.api.IllegalPlanChange;
-import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.catalog.api.PlanAlignmentChange;
-import com.ning.billing.catalog.api.PlanChangeResult;
-import com.ning.billing.catalog.api.PlanPhaseSpecifier;
-import com.ning.billing.catalog.api.PlanSpecifier;
-
 public class TestPlanRules {
 	Logger log = LoggerFactory.getLogger(TestPlanRules.class);
 
@@ -45,7 +35,7 @@ public class TestPlanRules {
 	public void setup() {
 		cat = new MockCatalog();
 
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[0];
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[0];
 
 		CaseChangePlanPolicy casePolicy = new CaseChangePlanPolicy().setPolicy(ActionPolicy.END_OF_TERM);
 		CaseChangePlanAlignment caseAlignment = new CaseChangePlanAlignment().setAlignment(PlanAlignmentChange.START_OF_SUBSCRIPTION);
@@ -59,8 +49,8 @@ public class TestPlanRules {
 
 	@Test
 	public void testCannotChangeToSamePlan() {
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 		
 		PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
 		PlanSpecifier to = new PlanSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName());
@@ -70,14 +60,16 @@ public class TestPlanRules {
 			Assert.fail("We did not see an exception when  trying to change plan to the same plan");
 		} catch (IllegalPlanChange e) {
 			log.info("Correct - cannot change to the same plan:", e);
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
 		}
 
 	}
 	
 	@Test
 	public void testExistingPriceListIsKept() {
-		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
 		
 		PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
 		PlanSpecifier to = new PlanSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.ANNUAL, priceList1.getName());
@@ -88,6 +80,8 @@ public class TestPlanRules {
 		} catch (IllegalPlanChange e) {
 			log.info("Correct - cannot change to the same plan:", e);
 			Assert.fail("We should not have triggered this error");
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
 		}
 		
 		Assert.assertEquals(result.getPolicy(), ActionPolicy.END_OF_TERM);
@@ -99,10 +93,10 @@ public class TestPlanRules {
 	
 	@Test
 	public void testBaseCase() {
-		Product product1 = cat.getProducts()[0];
-		Product product2 = cat.getProducts()[1];
-		PriceList priceList1 = cat.getPriceListFromName(IPriceListSet.DEFAULT_PRICELIST_NAME);
-		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[0];
+		DefaultProduct product1 = cat.getProducts()[0];
+		DefaultProduct product2 = cat.getProducts()[1];
+		DefaultPriceList priceList1 = cat.getPriceListFromName(PriceListSet.DEFAULT_PRICELIST_NAME);
+		DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[0];
 		
 		PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), product1.getCategory(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
 		PlanSpecifier to = new PlanSpecifier(product2.getName(), product2.getCategory(), BillingPeriod.MONTHLY, null);
@@ -113,6 +107,8 @@ public class TestPlanRules {
 		} catch (IllegalPlanChange e) {
 			log.info("Correct - cannot change to the same plan:", e);
 			Assert.fail("We should not have triggered this error");
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
 		}
 		
 		Assert.assertEquals(result.getPolicy(), ActionPolicy.END_OF_TERM);
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java b/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
index cfa959c..0f75459 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
@@ -15,29 +15,36 @@
  */
 package com.ning.billing.catalog;
 
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.config.ValidationErrors;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import java.math.BigDecimal;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.util.Date;
 
 public class TestInternationalPrice {
+	private static final Logger log = LoggerFactory.getLogger(TestInternationalPrice.class);
+	
   @Test
-  public void testZeroValue() throws URISyntaxException {
-	  Catalog c = new MockCatalog();
+  public void testZeroValue() throws URISyntaxException, CatalogApiException {
+	  StandaloneCatalog c = new MockCatalog();
 	  c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
-	  InternationalPrice p0 =  new MockInternationalPrice();
+	  DefaultInternationalPrice p0 =  new MockInternationalPrice();
 	  p0.setPrices(null);
 	  p0.initialize(c, new URI("foo:bar"));
-	  InternationalPrice p1 =  new MockInternationalPrice();
-	  p1.setPrices(new Price[] {
-			  new Price().setCurrency(Currency.GBP).setValue(new BigDecimal(1)),
-			  new Price().setCurrency(Currency.EUR).setValue(new BigDecimal(1)),
-			  new Price().setCurrency(Currency.USD).setValue(new BigDecimal(1)),
-			  new Price().setCurrency(Currency.BRL).setValue(new BigDecimal(1)),
-			  new Price().setCurrency(Currency.MXN).setValue(new BigDecimal(1)),		  
+	  DefaultInternationalPrice p1 =  new MockInternationalPrice();
+	  p1.setPrices(new DefaultPrice[] {
+			  new DefaultPrice().setCurrency(Currency.GBP).setValue(new BigDecimal(1)),
+			  new DefaultPrice().setCurrency(Currency.EUR).setValue(new BigDecimal(1)),
+			  new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(1)),
+			  new DefaultPrice().setCurrency(Currency.BRL).setValue(new BigDecimal(1)),
+			  new DefaultPrice().setCurrency(Currency.MXN).setValue(new BigDecimal(1)),		  
 	  });
 	  p1.initialize(c, new URI("foo:bar"));
 
@@ -54,4 +61,44 @@ public class TestInternationalPrice {
 	  Assert.assertEquals(p1.getPrice(Currency.MXN), new BigDecimal(1));
 	  
   }
+  
+  @Test
+  public void testPriceInitialization() throws URISyntaxException, CatalogApiException  {
+	  StandaloneCatalog c = new MockCatalog();
+	  c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+	  c.initialize(c, new URI("foo://bar"));
+	  Assert.assertEquals(c.getPlans()[0].getFinalPhase().getRecurringPrice().getPrice(Currency.GBP), new BigDecimal(0));
+  }
+  
+  @Test
+  public void testNegativeValuePrices(){
+	  StandaloneCatalog c = new MockCatalog();
+	  c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+	
+	  DefaultInternationalPrice p1 =  new MockInternationalPrice();
+	  p1.setPrices(new DefaultPrice[] {
+			  new DefaultPrice().setCurrency(Currency.GBP).setValue(new BigDecimal(-1)),
+			  new DefaultPrice().setCurrency(Currency.EUR).setValue(new BigDecimal(-1)),
+			  new DefaultPrice().setCurrency(Currency.USD).setValue(new BigDecimal(-1)),
+			  new DefaultPrice().setCurrency(Currency.BRL).setValue(new BigDecimal(1)),
+			  new DefaultPrice().setCurrency(Currency.MXN).setValue(new BigDecimal(1)),		  
+	  });
+	  
+	 ValidationErrors errors = p1.validate(c, new ValidationErrors());
+	 errors.log(log);
+	 Assert.assertEquals(errors.size(), 3);
+  }
+  @Test
+  public void testDateValidation(){
+	 StandaloneCatalog c = new MockCatalog();
+	 c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+	 DefaultInternationalPrice p1 =  new MockInternationalPrice();
+	 p1.setEffectiveDateForExistingSubscriptons(new Date((new Date().getTime()) - (1000 * 60 * 60 * 24)));
+	 ValidationErrors errors = p1.validate(c, new ValidationErrors());
+	 Assert.assertEquals(errors.size(), 1);
+	 errors.log(log);
+  }
+  
+  
+  
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java b/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
index b38a823..4bfcf30 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
@@ -16,14 +16,13 @@
 
 package com.ning.billing.catalog;
 
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.util.config.ValidationErrors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.util.config.ValidationErrors;
-
 public class TestPlanPhase {
 	Logger log = LoggerFactory.getLogger(TestPlanPhase.class);
 	
@@ -31,7 +30,7 @@ public class TestPlanPhase {
 	public void testValidation() {
 		log.info("Testing Plan Phase Validation");
 		
-		PlanPhase pp = new MockPlanPhase().setBillCycleDuration(BillingPeriod.MONTHLY).setReccuringPrice(null);
+		DefaultPlanPhase pp = new MockPlanPhase().setBillCycleDuration(BillingPeriod.MONTHLY).setReccuringPrice(null).setFixedPrice(new DefaultInternationalPrice());
 		ValidationErrors errors = pp.validate(new MockCatalog(), new ValidationErrors());
 		errors.log(log);
 		Assert.assertEquals(errors.size(), 1);
@@ -40,5 +39,10 @@ public class TestPlanPhase {
 		errors = pp.validate(new MockCatalog(), new ValidationErrors());
 		errors.log(log);
 		Assert.assertEquals(errors.size(), 1);
-	}
+
+		pp = new MockPlanPhase().setReccuringPrice(null).setFixedPrice(null).setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD);
+		errors = pp.validate(new MockCatalog(), new ValidationErrors());
+		errors.log(log);
+		Assert.assertEquals(errors.size(), 1);
+}
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestPriceListSet.java b/catalog/src/test/java/com/ning/billing/catalog/TestPriceListSet.java
index 4aedb25..09024ce 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestPriceListSet.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestPriceListSet.java
@@ -16,68 +16,69 @@
 
 package com.ning.billing.catalog;
 
-import static com.ning.billing.catalog.api.BillingPeriod.*;
-import static com.ning.billing.catalog.api.PhaseType.*;
-
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
 import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IPriceListSet;
 import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import static com.ning.billing.catalog.api.BillingPeriod.ANNUAL;
+import static com.ning.billing.catalog.api.BillingPeriod.MONTHLY;
+import static com.ning.billing.catalog.api.PhaseType.DISCOUNT;
+import static com.ning.billing.catalog.api.PhaseType.EVERGREEN;
 
 public class TestPriceListSet {
 	@Test(enabled=true)
 	public void testOverriding() {
-		Product foo = new Product("Foo", ProductCategory.BASE);
-		Product bar = new Product("Bar", ProductCategory.BASE);
-		Plan[] defaultPlans = new Plan[]{ 
+		DefaultProduct foo = new DefaultProduct("Foo", ProductCategory.BASE);
+		DefaultProduct bar = new DefaultProduct("Bar", ProductCategory.BASE);
+		DefaultPlan[] defaultPlans = new DefaultPlan[]{ 
 				new MockPlan().setName("plan-foo-monthly").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
 				new MockPlan().setName("plan-bar-monthly").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
 				new MockPlan().setName("plan-foo-annual").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(EVERGREEN)),
 				new MockPlan().setName("plan-bar-annual").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(EVERGREEN))
 				};
-		Plan[] childPlans = new Plan[]{ 
+		DefaultPlan[] childPlans = new DefaultPlan[]{ 
 				new MockPlan().setName("plan-foo").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT)),
 				new MockPlan().setName("plan-bar").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT))
 				};
 		PriceListDefault defaultPriceList = new PriceListDefault(defaultPlans);
-		PriceList[] childPriceLists = new PriceList[] {
-				new PriceList(childPlans, "child")
+		DefaultPriceList[] childPriceLists = new DefaultPriceList[] {
+				new DefaultPriceList(childPlans, "child")
 		};
-		PriceListSet set = new PriceListSet(defaultPriceList, childPriceLists);
+		DefaultPriceListSet set = new DefaultPriceListSet(defaultPriceList, childPriceLists);
 		
-		Assert.assertEquals(set.getPlanListFrom(IPriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
-		Assert.assertEquals(set.getPlanListFrom(IPriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+		Assert.assertEquals(set.getPlanListFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+		Assert.assertEquals(set.getPlanListFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
 		Assert.assertEquals(set.getPlanListFrom("child", foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.DISCOUNT);
 		Assert.assertEquals(set.getPlanListFrom("child", foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
 	}
 	
 	public void testForNullBillingPeriod() {
-		Product foo = new Product("Foo", ProductCategory.BASE);
-		Product bar = new Product("Bar", ProductCategory.BASE);
-		Plan[] defaultPlans = new Plan[]{ 
+		DefaultProduct foo = new DefaultProduct("Foo", ProductCategory.BASE);
+		DefaultProduct bar = new DefaultProduct("Bar", ProductCategory.BASE);
+		DefaultPlan[] defaultPlans = new DefaultPlan[]{ 
 				new MockPlan().setName("plan-foo-monthly").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
 				new MockPlan().setName("plan-bar-monthly").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(MONTHLY).setPhaseType(EVERGREEN)),
 				new MockPlan().setName("plan-foo-annual").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(null).setPhaseType(EVERGREEN)),
 				new MockPlan().setName("plan-bar-annual").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(null).setPhaseType(EVERGREEN))
 				};
-		Plan[] childPlans = new Plan[]{ 
+		DefaultPlan[] childPlans = new DefaultPlan[]{ 
 				new MockPlan().setName("plan-foo").setProduct(foo).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT)),
 				new MockPlan().setName("plan-bar").setProduct(bar).setFinalPhase(new MockPlanPhase().setBillCycleDuration(ANNUAL).setPhaseType(DISCOUNT))
 				};
 
 		PriceListDefault defaultPriceList = new PriceListDefault(defaultPlans);
-		PriceList[] childPriceLists = new PriceList[] {
-				new PriceList(childPlans, "child")
+		DefaultPriceList[] childPriceLists = new DefaultPriceList[] {
+				new DefaultPriceList(childPlans, "child")
 		};
-		PriceListSet set = new PriceListSet(defaultPriceList, childPriceLists);
+		DefaultPriceListSet set = new DefaultPriceListSet(defaultPriceList, childPriceLists);
 		
 		Assert.assertEquals(set.getPlanListFrom("child", foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.DISCOUNT);
 		Assert.assertEquals(set.getPlanListFrom("child", foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
-		Assert.assertEquals(set.getPlanListFrom(IPriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
-		Assert.assertEquals(set.getPlanListFrom(IPriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+		Assert.assertEquals(set.getPlanListFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.ANNUAL).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
+		Assert.assertEquals(set.getPlanListFrom(PriceListSet.DEFAULT_PRICELIST_NAME, foo, BillingPeriod.MONTHLY).getFinalPhase().getPhaseType(), PhaseType.EVERGREEN);
 	}
 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java b/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
index fc456ac..bc07e3e 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
@@ -15,39 +15,37 @@
  */
 package com.ning.billing.catalog;
 
-import static org.testng.AssertJUnit.assertEquals;
+import com.google.common.io.Resources;
+import com.ning.billing.catalog.api.InvalidConfigException;
+import com.ning.billing.catalog.io.VersionedCatalogLoader;
+import com.ning.billing.lifecycle.KillbillService.ServiceException;
+import com.ning.billing.util.clock.DefaultClock;
+import org.joda.time.DateTime;
+import org.testng.annotations.Test;
+import org.xml.sax.SAXException;
 
+import javax.xml.bind.JAXBException;
+import javax.xml.transform.TransformerException;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.util.Date;
 
-import javax.xml.bind.JAXBException;
-import javax.xml.transform.TransformerException;
-
-import org.joda.time.DateTime;
-import org.testng.annotations.Test;
-import org.xml.sax.SAXException;
-
-import com.google.common.io.Resources;
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.VersionedCatalog;
-import com.ning.billing.catalog.api.InvalidConfigException;
-import com.ning.billing.catalog.io.VersionedCatalogLoader;
+import static org.testng.AssertJUnit.assertEquals;
 
 public class TestVersionedCatalog {
-	private final VersionedCatalogLoader loader = new VersionedCatalogLoader();
+	private final VersionedCatalogLoader loader = new VersionedCatalogLoader(new DefaultClock());
 
 	@Test(enabled=true)
-	public void testAddCatalog() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
-		VersionedCatalog vc = loader.load(Resources.getResource("versionedCatalog"));
-		vc.add(new Catalog(new Date()));
+	public void testAddCatalog() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException {
+		VersionedCatalog vc = loader.load(Resources.getResource("versionedCatalog").toString());
+		vc.add(new StandaloneCatalog(new Date()));
 		assertEquals(5, vc.size());
 	}
 	
 	@Test(enabled=true)
-	public void testApplyEffectiveDate() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
-		VersionedCatalog vc = loader.load(Resources.getResource("versionedCatalog"));
+	public void testApplyEffectiveDate() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException {
+		VersionedCatalog vc = loader.load(Resources.getResource("versionedCatalog").toString());
 		Date d = new Date(1L);
 		vc.configureEffectiveDate(d);
 		assertEquals(new Date(0), vc.getEffectiveDate()); // Start at the begining of time
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 618b0b8..89039ff 100644
--- a/entitlement/pom.xml
+++ b/entitlement/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.0.16-SNAPSHOT</version>
+        <version>0.0.17-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-entitlement</artifactId>
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
index fdcbb9b..083aef5 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
@@ -17,97 +17,151 @@
 package com.ning.billing.entitlement.alignment;
 
 import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.*;
-import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
+import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
-import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.DefaultClock;
 import org.joda.time.DateTime;
 
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
-public class PlanAligner implements IPlanAligner {
+/**
+ *
+ * PlanAligner offers specific APIs to return the correct {@code TimedPhase} when creating, changing Plan or to compute next Phase on current Plan.
+ * <p>
+ *
+ */
+public class PlanAligner  {
 
-    private final ICatalogService catalogService;
+    private final CatalogService catalogService;
 
     @Inject
-    public PlanAligner(ICatalogService catalogService) {
+    public PlanAligner(CatalogService catalogService) {
         this.catalogService = catalogService;
     }
 
-
     private enum WhichPhase {
         CURRENT,
         NEXT
     }
 
-    @Override
-    public TimedPhase getCurrentTimedPhaseOnCreate(Subscription subscription,
-            IPlan plan, String priceList, DateTime effectiveDate) {
-        return getTimedPhaseOnCreate(subscription, plan, priceList, effectiveDate, WhichPhase.CURRENT);
-    }
-
-    @Override
-    public TimedPhase getNextTimedPhaseOnCreate(Subscription subscription,
-            IPlan plan, String priceList, DateTime effectiveDate) {
-            return getTimedPhaseOnCreate(subscription, plan, priceList, effectiveDate, WhichPhase.NEXT);
+    /**
+     * Returns the current and next phase for the subscription in creation
+     * <p>
+     * @param subscription the subscription in creation
+     * @param plan the current Plan
+     * @param initialPhase the initialPhase on which we should create that subscription. can be null
+     * @param priceList the priceList
+     * @param effectiveDate the effective creation date
+     * @return
+     * @throws CatalogApiException
+     * @throws EntitlementUserApiException
+     */
+    public TimedPhase [] getCurrentAndNextTimedPhaseOnCreate(SubscriptionData subscription,
+            Plan plan, PhaseType initialPhase, String priceList, DateTime effectiveDate)
+        throws CatalogApiException, EntitlementUserApiException {
+        List<TimedPhase> timedPhases = getTimedPhaseOnCreate(subscription, plan, initialPhase, priceList, effectiveDate);
+        TimedPhase [] result = new TimedPhase[2];
+        result[0] = getTimedPhase(timedPhases, effectiveDate, WhichPhase.CURRENT);
+        result[1] = getTimedPhase(timedPhases, effectiveDate, WhichPhase.NEXT);
+        return result;
     }
 
-    @Override
-    public TimedPhase getCurrentTimedPhaseOnChange(Subscription subscription,
-            IPlan plan, String priceList, DateTime effectiveDate) {
+    /**
+     *
+     * Returns current Phase for that Plan change
+     * <p>
+     * @param subscription the subscription in creation
+     * @param plan the current Plan
+     * @param priceList the priceList on which we should change that subscription.
+     * @param effectiveDate the effective change date
+     * @return
+     * @throws CatalogApiException
+     * @throws EntitlementUserApiException
+     */
+    public TimedPhase getCurrentTimedPhaseOnChange(SubscriptionData subscription,
+            Plan plan, String priceList, DateTime effectiveDate)
+        throws CatalogApiException, EntitlementUserApiException {
         return getTimedPhaseOnChange(subscription, plan, priceList, effectiveDate, WhichPhase.CURRENT);
     }
 
-    @Override
-    public TimedPhase getNextTimedPhaseOnChange(Subscription subscription,
-            IPlan plan, String priceList, DateTime effectiveDate) {
+    /**
+     * Returns next Phase for that Plan change
+     * <p>
+     * @param subscription the subscription in creation
+     * @param plan the current Plan
+     * @param priceList the priceList on which we should change that subscription.
+     * @param effectiveDate the effective change date
+     * @return
+     * @throws CatalogApiException
+     * @throws EntitlementUserApiException
+     */
+    public TimedPhase getNextTimedPhaseOnChange(SubscriptionData subscription,
+            Plan plan, String priceList, DateTime effectiveDate)
+        throws CatalogApiException, EntitlementUserApiException {
         return getTimedPhaseOnChange(subscription, plan, priceList, effectiveDate, WhichPhase.NEXT);
     }
 
-
-
-    @Override
-    public TimedPhase getNextTimedPhase(Subscription subscription,
-            IPlan plan, DateTime effectiveDate, DateTime planStartDate) {
-        List<TimedPhase> timedPhases = getPhaseAlignments(subscription, plan, effectiveDate, planStartDate);
-        return getTimedPhase(timedPhases, effectiveDate, WhichPhase.NEXT);
+    /**
+     * Returns next future phase for that Plan based on effectiveDate
+     *
+     * @param plan
+     * @param initialPhase the initial phase that subscription started on that Plan
+     * @param effectiveDate the date used to consider what is future
+     * @param initialStartPhase the date for when we started on that Plan/initialPhase
+     * @return
+     * @throws EntitlementError
+     */
+    public TimedPhase getNextTimedPhase(Plan plan, PhaseType initialPhase, DateTime effectiveDate, DateTime initialStartPhase)
+        throws EntitlementError {
+        try {
+            List<TimedPhase> timedPhases = getPhaseAlignments(plan, initialPhase, initialStartPhase);
+            return getTimedPhase(timedPhases, effectiveDate, WhichPhase.NEXT);
+        } catch (EntitlementUserApiException e) {
+            throw new EntitlementError(String.format("Could not compute next phase change for plan %s with initialPhase %s", plan.getName(), initialPhase));
+        }
     }
 
-    private TimedPhase getTimedPhaseOnCreate(Subscription subscription,
-            IPlan plan, String priceList, DateTime effectiveDate, WhichPhase which) {
+    private List<TimedPhase> getTimedPhaseOnCreate(SubscriptionData subscription,
+            Plan plan, PhaseType initialPhase, String priceList, DateTime effectiveDate)
+        throws CatalogApiException, EntitlementUserApiException  {
 
-        ICatalog catalog = catalogService.getCatalog();
+        Catalog catalog = catalogService.getCatalog();
 
-            PlanSpecifier planSpecifier = new PlanSpecifier(plan.getProduct().getName(),
-                    plan.getProduct().getCategory(),
-                    plan.getBillingPeriod(),
-                    priceList);
+        PlanSpecifier planSpecifier = new PlanSpecifier(plan.getProduct().getName(),
+                plan.getProduct().getCategory(),
+                plan.getBillingPeriod(),
+                priceList);
 
-            DateTime planStartDate = null;
-            PlanAlignmentCreate alignement =  catalog.getPlanCreateAlignment(planSpecifier);
-            switch(alignement) {
-            case START_OF_SUBSCRIPTION:
-                planStartDate = subscription.getStartDate();
-                break;
-            case START_OF_BUNDLE:
-                planStartDate = subscription.getBundleStartDate();
-                break;
-            default:
-                throw new EntitlementError(String.format("Unknwon PlanAlignmentCreate %s", alignement));
-            }
-            List<TimedPhase> timedPhases = getPhaseAlignments(subscription, plan, effectiveDate, planStartDate);
-            return getTimedPhase(timedPhases, effectiveDate, which);
+        DateTime planStartDate = null;
+        PlanAlignmentCreate alignement = null;
+        alignement = catalog.planCreateAlignment(planSpecifier);
+
+        switch(alignement) {
+        case START_OF_SUBSCRIPTION:
+            planStartDate = subscription.getStartDate();
+            break;
+        case START_OF_BUNDLE:
+            planStartDate = subscription.getBundleStartDate();
+            break;
+        default:
+            throw new EntitlementError(String.format("Unknwon PlanAlignmentCreate %s", alignement));
+        }
+        return getPhaseAlignments(plan, initialPhase, planStartDate);
     }
 
-    private TimedPhase getTimedPhaseOnChange(Subscription subscription,
-            IPlan plan, String priceList, DateTime effectiveDate, WhichPhase which) {
+    private TimedPhase getTimedPhaseOnChange(SubscriptionData subscription,
+            Plan plan, String priceList, DateTime effectiveDate, WhichPhase which)
+        throws CatalogApiException, EntitlementUserApiException {
 
-        ICatalog catalog = catalogService.getCatalog();
+        Catalog catalog = catalogService.getCatalog();
 
-        IPlanPhase currentPhase = subscription.getCurrentPhase();
-        IPlan currentPlan = subscription.getCurrentPlan();
+        PlanPhase currentPhase = subscription.getCurrentPhase();
+        Plan currentPlan = subscription.getCurrentPlan();
         String currentPriceList = subscription.getCurrentPriceList();
 
         PlanPhaseSpecifier fromPlanPhaseSpecifier = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
@@ -122,7 +176,9 @@ public class PlanAligner implements IPlanAligner {
                 priceList);
 
         DateTime planStartDate = null;
-        PlanAlignmentChange alignment = catalog.getPlanChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier);
+
+        PlanAlignmentChange alignment = null;
+        alignment = catalog.planChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier);
         switch(alignment) {
         case START_OF_SUBSCRIPTION:
             planStartDate = subscription.getStartDate();
@@ -137,40 +193,43 @@ public class PlanAligner implements IPlanAligner {
         default:
             throw new EntitlementError(String.format("Unknwon PlanAlignmentChange %s", alignment));
         }
-        List<TimedPhase> timedPhases = getPhaseAlignments(subscription, plan, effectiveDate, planStartDate);
+        List<TimedPhase> timedPhases = getPhaseAlignments(plan, null, planStartDate);
         return getTimedPhase(timedPhases, effectiveDate, which);
     }
 
-    private List<TimedPhase> getPhaseAlignments(Subscription subscription, IPlan plan,
-            DateTime effectiveDate, DateTime planStartDate) {
 
-        // The plan can be null with the nasty endpoint from test API.
+    private List<TimedPhase> getPhaseAlignments(Plan plan, PhaseType initialPhase, DateTime initialPhaseStartDate)
+        throws EntitlementUserApiException {
         if (plan == null) {
             return Collections.emptyList();
         }
 
-        List<TimedPhase> result = new LinkedList<IPlanAligner.TimedPhase>();
-
-        DateTime curPhaseStart = planStartDate;
-        if (plan.getInitialPhases() == null) {
-            result.add(new TimedPhase(plan.getFinalPhase(), curPhaseStart));
-            return result;
-        }
-
+        List<TimedPhase> result = new LinkedList<TimedPhase>();
+        DateTime curPhaseStart = (initialPhase == null) ? initialPhaseStartDate : null;
         DateTime nextPhaseStart = null;
-        for (IPlanPhase cur : plan.getInitialPhases()) {
+        for (PlanPhase cur : plan.getAllPhases()) {
+            if (curPhaseStart == null) {
+                if (initialPhase != cur.getPhaseType()) {
+                    continue;
+                }
+                curPhaseStart = initialPhaseStartDate;
+            }
 
             result.add(new TimedPhase(cur, curPhaseStart));
 
-            IDuration curPhaseDuration = cur.getDuration();
-            nextPhaseStart = Clock.addDuration(curPhaseStart, curPhaseDuration);
-            if (nextPhaseStart == null) {
-                throw new EntitlementError(String.format("Unexpected non ending UNLIMITED phase for plan %s",
-                        plan.getName()));
+            if (cur.getPhaseType() != PhaseType.EVERGREEN) {
+                Duration curPhaseDuration = cur.getDuration();
+                nextPhaseStart = DefaultClock.addDuration(curPhaseStart, curPhaseDuration);
+                if (nextPhaseStart == null) {
+                    throw new EntitlementError(String.format("Unexpected non ending UNLIMITED phase for plan %s",
+                            plan.getName()));
+                }
+                curPhaseStart = nextPhaseStart;
             }
-            curPhaseStart = nextPhaseStart;
         }
-        result.add(new TimedPhase(plan.getFinalPhase(), nextPhaseStart));
+        if (initialPhase != null && curPhaseStart == null) {
+            throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_BAD_PHASE, initialPhase);
+        }
         return result;
     }
 
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
new file mode 100644
index 0000000..3b3ff73
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionApiService.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.entitlement.api.user;
+
+import com.google.inject.Inject;
+import com.ning.billing.ErrorCode;
+import com.ning.billing.catalog.api.*;
+import com.ning.billing.entitlement.alignment.PlanAligner;
+import com.ning.billing.entitlement.alignment.TimedPhase;
+import com.ning.billing.entitlement.api.user.Subscription.SubscriptionState;
+import com.ning.billing.entitlement.api.user.SubscriptionFactory.SubscriptionBuilder;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
+import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.entitlement.events.phase.PhaseEvent;
+import com.ning.billing.entitlement.events.phase.PhaseEventData;
+import com.ning.billing.entitlement.events.user.*;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.clock.DefaultClock;
+import org.joda.time.DateTime;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SubscriptionApiService {
+
+    private final Clock clock;
+    private final EntitlementDao dao;
+    private final CatalogService catalogService;
+    private final PlanAligner planAligner;
+
+    @Inject
+    public SubscriptionApiService(Clock clock, EntitlementDao dao, CatalogService catalogService, PlanAligner planAligner) {
+        this.clock = clock;
+        this.catalogService = catalogService;
+        this.planAligner = planAligner;
+        this.dao = dao;
+    }
+
+
+
+    public SubscriptionData createBasePlan(SubscriptionBuilder builder, Plan plan, PhaseType initialPhase,
+            String realPriceList, DateTime requestedDate, DateTime effectiveDate, DateTime processedDate)
+        throws EntitlementUserApiException {
+
+        try {
+            SubscriptionData subscription = new SubscriptionData(builder, this, clock);
+
+
+            TimedPhase [] curAndNextPhases = planAligner.getCurrentAndNextTimedPhaseOnCreate(subscription, plan, initialPhase, realPriceList, effectiveDate);
+            ApiEventCreate creationEvent = new ApiEventCreate(new ApiEventBuilder()
+            .setSubscriptionId(subscription.getId())
+            .setEventPlan(plan.getName())
+            .setEventPlanPhase(curAndNextPhases[0].getPhase().getName())
+            .setEventPriceList(realPriceList)
+            .setActiveVersion(subscription.getActiveVersion())
+            .setProcessedDate(processedDate)
+            .setEffectiveDate(effectiveDate)
+            .setRequestedDate(requestedDate));
+
+            PhaseEvent nextPhaseEvent = PhaseEventData.getNextPhaseEvent(curAndNextPhases[1], subscription, processedDate);
+            List<EntitlementEvent> events = new ArrayList<EntitlementEvent>();
+            events.add(creationEvent);
+            if (nextPhaseEvent != null) {
+                events.add(nextPhaseEvent);
+            }
+            dao.createSubscription(subscription, events);
+            subscription.rebuildTransitions(events, catalogService.getCatalog());
+            return subscription;
+        } catch (CatalogApiException e) {
+            throw new EntitlementUserApiException(e);
+        }
+    }
+
+    public void cancel(SubscriptionData subscription, DateTime requestedDate, boolean eot)
+        throws EntitlementUserApiException {
+
+        try {
+            SubscriptionState currentState = subscription.getState();
+            if (currentState != SubscriptionState.ACTIVE) {
+                throw new EntitlementUserApiException(ErrorCode.ENT_CANCEL_BAD_STATE, subscription.getId(), currentState);
+            }
+
+            DateTime now = clock.getUTCNow();
+            requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : null;
+            if (requestedDate != null && requestedDate.isAfter(now)) {
+                throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE, requestedDate.toString());
+            }
+
+            Plan currentPlan = subscription.getCurrentPlan();
+            PlanPhaseSpecifier planPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
+                    currentPlan.getProduct().getCategory(),
+                    subscription.getCurrentPlan().getBillingPeriod(),
+                    subscription.getCurrentPriceList(),
+                    subscription.getCurrentPhase().getPhaseType());
+
+            ActionPolicy policy = null;
+            policy = catalogService.getCatalog().planCancelPolicy(planPhase);
+            DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, now);
+
+            EntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
+            .setSubscriptionId(subscription.getId())
+            .setActiveVersion(subscription.getActiveVersion())
+            .setProcessedDate(now)
+            .setEffectiveDate(effectiveDate)
+            .setRequestedDate(now));
+
+            dao.cancelSubscription(subscription.getId(), cancelEvent);
+            subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getCatalog());
+        } catch (CatalogApiException e) {
+            throw new EntitlementUserApiException(e);
+        }
+    }
+
+
+    public void uncancel(SubscriptionData subscription)
+    throws EntitlementUserApiException {
+
+        if (!subscription.isSubscriptionFutureCancelled()) {
+            throw new EntitlementUserApiException(ErrorCode.ENT_UNCANCEL_BAD_STATE, subscription.getId().toString());
+        }
+
+        DateTime now = clock.getUTCNow();
+        EntitlementEvent uncancelEvent = new ApiEventUncancel(new ApiEventBuilder()
+        .setSubscriptionId(subscription.getId())
+        .setActiveVersion(subscription.getActiveVersion())
+        .setProcessedDate(now)
+        .setRequestedDate(now)
+        .setEffectiveDate(now));
+
+        List<EntitlementEvent> uncancelEvents = new ArrayList<EntitlementEvent>();
+        uncancelEvents.add(uncancelEvent);
+
+        DateTime planStartDate = subscription.getCurrentPlanStart();
+        TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription.getCurrentPlan(), subscription.getInitialPhaseOnCurrentPlan().getPhaseType(), now, planStartDate);
+        PhaseEvent nextPhaseEvent = PhaseEventData.getNextPhaseEvent(nextTimedPhase, subscription, now);
+        if (nextPhaseEvent != null) {
+            uncancelEvents.add(nextPhaseEvent);
+        }
+        dao.uncancelSubscription(subscription.getId(), uncancelEvents);
+        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getCatalog());
+    }
+
+    public void changePlan(SubscriptionData subscription, String productName, BillingPeriod term,
+            String priceList, DateTime requestedDate)
+        throws EntitlementUserApiException {
+
+        try {
+        requestedDate = (requestedDate != null) ? DefaultClock.truncateMs(requestedDate) : null;
+        String currentPriceList = subscription.getCurrentPriceList();
+
+        SubscriptionState currentState = subscription.getState();
+        if (currentState != SubscriptionState.ACTIVE) {
+            throw new EntitlementUserApiException(ErrorCode.ENT_CHANGE_NON_ACTIVE, subscription.getId(), currentState);
+        }
+
+        if (subscription.isSubscriptionFutureCancelled()) {
+            throw new EntitlementUserApiException(ErrorCode.ENT_CHANGE_FUTURE_CANCELLED, subscription.getId());
+        }
+
+        DateTime now = clock.getUTCNow();
+        PlanChangeResult planChangeResult = null;
+        try {
+
+            Product destProduct = catalogService.getCatalog().findProduct(productName);
+            Plan currentPlan = subscription.getCurrentPlan();
+            PlanPhaseSpecifier fromPlanPhase = new PlanPhaseSpecifier(currentPlan.getProduct().getName(),
+                    currentPlan.getProduct().getCategory(),
+                    currentPlan.getBillingPeriod(),
+                    currentPriceList, subscription.getCurrentPhase().getPhaseType());
+            PlanSpecifier toPlanPhase = new PlanSpecifier(productName,
+                    destProduct.getCategory(),
+                    term,
+                    priceList);
+
+            planChangeResult = catalogService.getCatalog().planChange(fromPlanPhase, toPlanPhase);
+        } catch (CatalogApiException e) {
+            throw new EntitlementUserApiException(e);
+        }
+
+        ActionPolicy policy = planChangeResult.getPolicy();
+        PriceList newPriceList = planChangeResult.getNewPriceList();
+
+        Plan newPlan = catalogService.getCatalog().findPlan(productName, term, newPriceList.getName());
+        DateTime effectiveDate = subscription.getPlanChangeEffectiveDate(policy, now);
+
+        TimedPhase currentTimedPhase = planAligner.getCurrentTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), effectiveDate);
+
+        EntitlementEvent changeEvent = new ApiEventChange(new ApiEventBuilder()
+        .setSubscriptionId(subscription.getId())
+        .setEventPlan(newPlan.getName())
+        .setEventPlanPhase(currentTimedPhase.getPhase().getName())
+        .setEventPriceList(newPriceList.getName())
+        .setActiveVersion(subscription.getActiveVersion())
+        .setProcessedDate(now)
+        .setEffectiveDate(effectiveDate)
+        .setRequestedDate(now));
+
+        TimedPhase nextTimedPhase = planAligner.getNextTimedPhaseOnChange(subscription, newPlan, newPriceList.getName(), effectiveDate);
+        PhaseEvent nextPhaseEvent = PhaseEventData.getNextPhaseEvent(nextTimedPhase, subscription, now);
+        List<EntitlementEvent> changeEvents = new ArrayList<EntitlementEvent>();
+        // Only add the PHASE if it does not coincide with the CHANGE, if not this is 'just' a CHANGE.
+        if (nextPhaseEvent != null && ! nextPhaseEvent.getEffectiveDate().equals(changeEvent.getEffectiveDate())) {
+            changeEvents.add(nextPhaseEvent);
+        }
+        changeEvents.add(changeEvent);
+        dao.changePlan(subscription.getId(), changeEvents);
+        subscription.rebuildTransitions(dao.getEventsForSubscription(subscription.getId()), catalogService.getCatalog());
+        } catch (CatalogApiException e) {
+            throw new EntitlementUserApiException(e);
+        }
+    }
+}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java
index 02b7c74..66dfb88 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionEvents.java
@@ -16,39 +16,39 @@
 
 package com.ning.billing.entitlement.api.user;
 
+import com.ning.billing.entitlement.events.EntitlementEvent;
+
 import java.util.LinkedList;
 import java.util.UUID;
 
-import com.ning.billing.entitlement.events.IEvent;
-
 public class SubscriptionEvents {
 
     public static final long INITIAL_VERSION = 1;
 
     private final UUID subscriptionId;
-    private final LinkedList<IEvent> events;
+    private final LinkedList<EntitlementEvent> events;
 
     private long activeVersion;
 
     public SubscriptionEvents(UUID subscriptionId) {
         super();
         this.subscriptionId = subscriptionId;
-        this.events = new LinkedList<IEvent>();
+        this.events = new LinkedList<EntitlementEvent>();
         this.activeVersion = INITIAL_VERSION;
     }
 
-    public void addEvent(IEvent ev) {
+    public void addEvent(EntitlementEvent ev) {
         events.add(ev);
     }
 
-    public LinkedList<IEvent> getCurrentView() {
+    public LinkedList<EntitlementEvent> getCurrentView() {
         return getViewForVersion(activeVersion);
     }
 
-    public LinkedList<IEvent> getViewForVersion(final long version) {
+    public LinkedList<EntitlementEvent> getViewForVersion(final long version) {
 
-        LinkedList<IEvent> result = new LinkedList<IEvent>();
-        for (IEvent cur : events) {
+        LinkedList<EntitlementEvent> result = new LinkedList<EntitlementEvent>();
+        for (EntitlementEvent cur : events) {
             if (cur.getActiveVersion() == version) {
                 result.add(cur);
             }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorBase.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorBase.java
index 704c7a5..cfeaca7 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorBase.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorBase.java
@@ -19,10 +19,10 @@ package com.ning.billing.entitlement.engine.core;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.inject.Inject;
-import com.ning.billing.config.IEntitlementConfig;
-import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
-import com.ning.billing.entitlement.events.IEvent;
-import com.ning.billing.util.clock.IClock;
+import com.ning.billing.config.EntitlementConfig;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
+import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.util.clock.Clock;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -33,7 +33,7 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
 
-public abstract class ApiEventProcessorBase implements IApiEventProcessor {
+public abstract class ApiEventProcessorBase implements EventNotifier {
 
     // Wait for max 60 sec when shutting down the EventProcessor
     private final long STOP_WAIT_TIMEOUT_MS = 60000;
@@ -44,20 +44,20 @@ public abstract class ApiEventProcessorBase implements IApiEventProcessor {
     protected final UUID apiProcessorId;
 
     private static final String API_EVENT_THREAD_NAME = "ApiEventNotification";
-    protected final static Logger log = LoggerFactory.getLogger(ApiEventProcessor.class);
+    protected final static Logger log = LoggerFactory.getLogger(DefaultApiEventProcessor.class);
 
-    protected final IEntitlementDao dao;
-    protected final IClock clock;
+    protected final EntitlementDao dao;
+    protected final Clock clock;
 
     private Executor executor;
-    private final IEntitlementConfig config;
-    protected IEventListener listener;
+    private final EntitlementConfig config;
+    protected EventListener listener;
 
     protected long nbProcessedEvents;
     protected volatile boolean isProcessingEvents;
 
     @Inject
-    public ApiEventProcessorBase(IClock clock, IEntitlementDao dao, IEntitlementConfig config) {
+    public ApiEventProcessorBase(Clock clock, EntitlementDao dao, EntitlementConfig config) {
         this.clock = clock;
         this.dao = dao;
         this.config = config;
@@ -70,7 +70,7 @@ public abstract class ApiEventProcessorBase implements IApiEventProcessor {
 
 
     @Override
-    public void startNotifications(final IEventListener listener) {
+    public void startNotifications(final EventListener listener) {
 
         this.listener = listener;
         this.isProcessingEvents = true;
@@ -198,9 +198,9 @@ public abstract class ApiEventProcessorBase implements IApiEventProcessor {
         int curSequenceId = sequenceId.getAndIncrement();
 
         //Get all current ready events
-        List<IEvent> claimedEvents = new LinkedList<IEvent>();
+        List<EntitlementEvent> claimedEvents = new LinkedList<EntitlementEvent>();
         do {
-            List<IEvent> tmpEvents = dao.getEventsReady(apiProcessorId, curSequenceId);
+            List<EntitlementEvent> tmpEvents = dao.getEventsReady(apiProcessorId, curSequenceId);
             if (tmpEvents.size() == 0) {
                 break;
             }
@@ -211,14 +211,14 @@ public abstract class ApiEventProcessorBase implements IApiEventProcessor {
         }
 
         // Filter for specific subscriptions if needed
-        Collection<IEvent> claimedEventsFiltered = null;
+        Collection<EntitlementEvent> claimedEventsFiltered = null;
         if (subscriptionsIds.length == 0) {
             claimedEventsFiltered = claimedEvents;
         } else {
 
-            claimedEventsFiltered = Collections2.filter(claimedEvents, new Predicate<IEvent>() {
+            claimedEventsFiltered = Collections2.filter(claimedEvents, new Predicate<EntitlementEvent>() {
                 @Override
-                public boolean apply(IEvent input) {
+                public boolean apply(EntitlementEvent input) {
                     for (UUID cur : subscriptionsIds) {
                         if (cur.equals(input.getSubscriptionId())) {
                             return true;
@@ -234,7 +234,7 @@ public abstract class ApiEventProcessorBase implements IApiEventProcessor {
 
         // If only one event is requested extract it
         if (oneEventOnly) {
-            List<IEvent> oneEventList = new ArrayList<IEvent>(1);
+            List<EntitlementEvent> oneEventList = new ArrayList<EntitlementEvent>(1);
             oneEventList.add(claimedEventsFiltered.iterator().next());
             claimedEventsFiltered = oneEventList;
         }
@@ -249,5 +249,5 @@ public abstract class ApiEventProcessorBase implements IApiEventProcessor {
     }
 
     protected abstract boolean doProcessEvents(int sequenceId);
-    protected abstract boolean doProcessEventsFromList(int sequenceId, Collection<IEvent> events);
+    protected abstract boolean doProcessEventsFromList(int sequenceId, Collection<EntitlementEvent> events);
 }
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 af61186..aed7937 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
@@ -17,33 +17,33 @@
 package com.ning.billing.entitlement.engine.core;
 
 import com.google.inject.Inject;
-import com.ning.billing.config.IEntitlementConfig;
-import com.ning.billing.entitlement.alignment.IPlanAligner;
-import com.ning.billing.entitlement.alignment.IPlanAligner.TimedPhase;
-import com.ning.billing.entitlement.api.IEntitlementService;
+import com.ning.billing.config.EntitlementConfig;
+import com.ning.billing.entitlement.alignment.PlanAligner;
+import com.ning.billing.entitlement.alignment.TimedPhase;
+import com.ning.billing.entitlement.api.EntitlementService;
+import com.ning.billing.entitlement.api.billing.DefaultEntitlementBillingApi;
 import com.ning.billing.entitlement.api.billing.EntitlementBillingApi;
-import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
+import com.ning.billing.entitlement.api.test.DefaultEntitlementTestApi;
 import com.ning.billing.entitlement.api.test.EntitlementTestApi;
-import com.ning.billing.entitlement.api.test.IEntitlementTestApi;
+import com.ning.billing.entitlement.api.user.DefaultEntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
-import com.ning.billing.entitlement.api.user.IEntitlementUserApi;
-import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
-import com.ning.billing.entitlement.events.IEvent;
-import com.ning.billing.entitlement.events.IEvent.EventType;
-import com.ning.billing.entitlement.events.phase.IPhaseEvent;
+import com.ning.billing.entitlement.api.user.SubscriptionData;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
+import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
+import com.ning.billing.entitlement.events.phase.PhaseEventData;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
-import com.ning.billing.lifecycle.LyfecycleHandlerType;
-import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
-import com.ning.billing.util.clock.IClock;
-import com.ning.billing.util.eventbus.IEventBus;
-import com.ning.billing.util.eventbus.IEventBus.EventBusException;
+import com.ning.billing.lifecycle.LifecycleHandlerType;
+import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.eventbus.EventBus;
+import com.ning.billing.util.eventbus.EventBus.EventBusException;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class Engine implements IEventListener, IEntitlementService {
+public class Engine implements EventListener, EntitlementService {
 
     private static final String ENTITLEMENT_SERVICE_NAME = "entitlement-service";
 
@@ -53,21 +53,21 @@ public class Engine implements IEventListener, IEntitlementService {
 
     private final static Logger log = LoggerFactory.getLogger(Engine.class);
 
-    private final IClock clock;
-    private final IEntitlementDao dao;
-    private final IApiEventProcessor apiEventProcessor;
-    private final IPlanAligner planAligner;
-    private final IEntitlementUserApi userApi;
-    private final IEntitlementBillingApi billingApi;
-    private final IEntitlementTestApi testApi;
-    private final IEventBus eventBus;
+    private final Clock clock;
+    private final EntitlementDao dao;
+    private final EventNotifier apiEventProcessor;
+    private final PlanAligner planAligner;
+    private final EntitlementUserApi userApi;
+    private final EntitlementBillingApi billingApi;
+    private final EntitlementTestApi testApi;
+    private final EventBus eventBus;
 
     private boolean startedNotificationThread;
 
     @Inject
-    public Engine(IClock clock, IEntitlementDao dao, IApiEventProcessor apiEventProcessor,
-            IPlanAligner planAligner, IEntitlementConfig config, EntitlementUserApi userApi,
-            EntitlementBillingApi billingApi, EntitlementTestApi testApi, IEventBus eventBus) {
+    public Engine(Clock clock, EntitlementDao dao, EventNotifier apiEventProcessor,
+            PlanAligner planAligner, EntitlementConfig config, DefaultEntitlementUserApi userApi,
+            DefaultEntitlementBillingApi billingApi, DefaultEntitlementTestApi testApi, EventBus eventBus) {
         super();
         this.clock = clock;
         this.dao = dao;
@@ -87,41 +87,41 @@ public class Engine implements IEventListener, IEntitlementService {
     }
 
 
-    @LyfecycleHandlerType(LyfecycleLevel.INIT_SERVICE)
+    @LifecycleHandlerType(LifecycleLevel.INIT_SERVICE)
     public void initialize() {
     }
 
-    @LyfecycleHandlerType(LyfecycleLevel.START_SERVICE)
+    @LifecycleHandlerType(LifecycleLevel.START_SERVICE)
     public void start() {
         apiEventProcessor.startNotifications(this);
         waitForNotificationStartCompletion();
     }
 
-    @LyfecycleHandlerType(LyfecycleLevel.STOP_SERVICE)
+    @LifecycleHandlerType(LifecycleLevel.STOP_SERVICE)
     public void stop() {
         apiEventProcessor.stopNotifications();
         startedNotificationThread = false;
     }
 
     @Override
-    public IEntitlementUserApi getUserApi() {
+    public EntitlementUserApi getUserApi() {
         return userApi;
     }
 
     @Override
-    public IEntitlementBillingApi getBillingApi() {
+    public EntitlementBillingApi getBillingApi() {
         return billingApi;
     }
 
 
     @Override
-    public IEntitlementTestApi getTestApi() {
+    public EntitlementTestApi getTestApi() {
         return testApi;
     }
 
     @Override
-    public void processEventReady(IEvent event) {
-        Subscription subscription = (Subscription) dao.getSubscriptionFromId(event.getSubscriptionId());
+    public void processEventReady(EntitlementEvent event) {
+        SubscriptionData subscription = (SubscriptionData) dao.getSubscriptionFromId(event.getSubscriptionId());
         if (subscription == null) {
             log.warn("Failed to retrieve subscription for id %s", event.getSubscriptionId());
             return;
@@ -165,22 +165,23 @@ public class Engine implements IEventListener, IEntitlementService {
                     (System.nanoTime() - ini) / NANO_TO_MS < MAX_NOTIFICATION_THREAD_WAIT_MS);
 
             if (!startedNotificationThread) {
-                log.error("Could not start notification thread in {} msec !!!", MAX_NOTIFICATION_THREAD_WAIT_MS);
+                log.error("Could not start notification thread in %d msec !!!", MAX_NOTIFICATION_THREAD_WAIT_MS);
                 throw new EntitlementError("Failed to start service!!");
             }
             log.info("Notification thread has been started in {} ms", (System.nanoTime() - ini) / NANO_TO_MS);
         }
     }
 
-    private void insertNextPhaseEvent(Subscription subscription) {
-
-        DateTime now = clock.getUTCNow();
-
-        TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription, subscription.getCurrentPlan(), now, subscription.getCurrentPlanStart());
-        IPhaseEvent nextPhaseEvent = PhaseEvent.getNextPhaseEvent(nextTimedPhase, subscription, now);
-        if (nextPhaseEvent != null) {
-            dao.createNextPhaseEvent(subscription.getId(), nextPhaseEvent);
+    private void insertNextPhaseEvent(SubscriptionData subscription) {
+        try {
+            DateTime now = clock.getUTCNow();
+            TimedPhase nextTimedPhase = planAligner.getNextTimedPhase(subscription.getCurrentPlan(), subscription.getInitialPhaseOnCurrentPlan().getPhaseType(), now, subscription.getCurrentPlanStart());
+            PhaseEvent nextPhaseEvent = PhaseEventData.getNextPhaseEvent(nextTimedPhase, subscription, now);
+            if (nextPhaseEvent != null) {
+                dao.createNextPhaseEvent(subscription.getId(), nextPhaseEvent);
+            }
+        } catch (EntitlementError e) {
+            log.error(String.format("Failed to insert next phase for subscription %s", subscription.getId()), e);
         }
     }
-
 }
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 ccbe23c..6c87a40 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
@@ -16,298 +16,56 @@
 
 package com.ning.billing.entitlement.engine.dao;
 
-import com.google.inject.Inject;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.config.IEntitlementConfig;
-import com.ning.billing.entitlement.api.user.*;
-import com.ning.billing.entitlement.events.IEvent;
-import com.ning.billing.entitlement.events.IEvent.EventType;
-import com.ning.billing.entitlement.events.user.ApiEventType;
-import com.ning.billing.entitlement.events.user.IApiEvent;
-import com.ning.billing.entitlement.exceptions.EntitlementError;
-import com.ning.billing.util.Hostname;
-import com.ning.billing.util.clock.IClock;
-import org.skife.jdbi.v2.DBI;
-import org.skife.jdbi.v2.Transaction;
-import org.skife.jdbi.v2.TransactionStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import com.ning.billing.entitlement.api.user.Subscription;
+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.events.EntitlementEvent;
 
-import java.util.*;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
 
-public class EntitlementDao implements IEntitlementDao {
+public interface EntitlementDao {
 
-    private final static Logger log = LoggerFactory.getLogger(EntitlementDao.class);
 
-    private final IClock clock;
-    private final ISubscriptionSqlDao subscriptionsDao;
-    private final IBundleSqlDao bundlesDao;
-    private final IEventSqlDao eventsDao;
-    private final IEntitlementConfig config;
-    private final String hostname;
+    // Bundle apis
+    public List<SubscriptionBundle> getSubscriptionBundleForAccount(UUID accountId);
 
-    @Inject
-    public EntitlementDao(DBI dbi, IClock clock, IEntitlementConfig config) {
-        this.clock = clock;
-        this.config = config;
-        this.subscriptionsDao = dbi.onDemand(ISubscriptionSqlDao.class);
-        this.eventsDao = dbi.onDemand(IEventSqlDao.class);
-        this.bundlesDao = dbi.onDemand(IBundleSqlDao.class);
-        this.hostname = Hostname.get();
-    }
+    public SubscriptionBundle getSubscriptionBundleFromId(UUID bundleId);
 
-    @Override
-    public List<ISubscriptionBundle> getSubscriptionBundleForAccount(
-            UUID accountId) {
-        return bundlesDao.getBundleFromAccount(accountId.toString());
-    }
+    public SubscriptionBundle createSubscriptionBundle(SubscriptionBundleData bundle);
 
-    @Override
-    public ISubscriptionBundle getSubscriptionBundleFromId(UUID bundleId) {
-        return bundlesDao.getBundleFromId(bundleId.toString());
-    }
+    public Subscription getSubscriptionFromId(UUID subscriptionId);
 
-    @Override
-    public ISubscriptionBundle createSubscriptionBundle(SubscriptionBundle bundle) {
-        bundlesDao.insertBundle(bundle);
-        return bundle;
-    }
 
-    @Override
-    public ISubscription getSubscriptionFromId(UUID subscriptionId) {
-        return subscriptionsDao.getSubscriptionFromId(subscriptionId.toString());
-    }
+    // Subscription retrieval
+    public Subscription getBaseSubscription(UUID bundleId);
 
-    @Override
-    public ISubscription getBaseSubscription(final UUID bundleId) {
+    public List<Subscription> getSubscriptions(UUID bundleId);
 
-        List<ISubscription> subscriptions = subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString());
-        for (ISubscription cur : subscriptions) {
-            if (((Subscription)cur).getCategory() == ProductCategory.BASE) {
-                return cur;
-            }
-        }
-        return null;
-    }
+    public List<Subscription> getSubscriptionsForKey(String bundleKey);
 
-    @Override
-    public List<ISubscription> getSubscriptions(UUID bundleId) {
-        return subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString());
-    }
+    // Update
+    public void updateSubscription(SubscriptionData subscription);
 
-    @Override
-    public List<ISubscription> getSubscriptionsForKey(String bundleKey) {
-        ISubscriptionBundle bundle =  bundlesDao.getBundleFromKey(bundleKey);
-        if (bundle == null) {
-            return Collections.emptyList();
-        }
-        return subscriptionsDao.getSubscriptionsFromBundleId(bundle.getId().toString());
-    }
+    // Event apis
+    public void createNextPhaseEvent(UUID subscriptionId, EntitlementEvent nextPhase);
 
-    @Override
-    public void updateSubscription(Subscription subscription) {
-        Date ctd = (subscription.getChargedThroughDate() != null)  ? subscription.getChargedThroughDate().toDate() : null;
-        Date ptd = (subscription.getPaidThroughDate() != null)  ? subscription.getPaidThroughDate().toDate() : null;
-        subscriptionsDao.updateSubscription(subscription.getId().toString(), subscription.getActiveVersion(), ctd, ptd);
-    }
+    public List<EntitlementEvent> getEventsForSubscription(UUID subscriptionId);
 
-    @Override
-    public void createNextPhaseEvent(final UUID subscriptionId, final IEvent nextPhase) {
-        eventsDao.inTransaction(new Transaction<Void, IEventSqlDao>() {
+    public List<EntitlementEvent> getPendingEventsForSubscription(UUID subscriptionId);
 
-            @Override
-            public Void inTransaction(IEventSqlDao dao,
-                    TransactionStatus status) throws Exception {
-                cancelNextPhaseEventFromTransaction(subscriptionId, dao);
-                dao.insertEvent(nextPhase);
-                return null;
-            }
-        });
-    }
+    public List<EntitlementEvent> getEventsReady(UUID ownerId, int sequenceId);
 
+    public void clearEventsReady(UUID ownerId, Collection<EntitlementEvent> cleared);
 
-    @Override
-    public List<IEvent> getEventsForSubscription(UUID subscriptionId) {
-        List<IEvent> events = eventsDao.getEventsForSubscription(subscriptionId.toString());
-        return events;
-    }
+    // Subscription creation, cancellation, changePlan apis
+    public void createSubscription(SubscriptionData subscription, List<EntitlementEvent> initialEvents);
 
-    @Override
-    public List<IEvent> getPendingEventsForSubscription(UUID subscriptionId) {
-        Date now = clock.getUTCNow().toDate();
-        List<IEvent> results = eventsDao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
-        return results;
-    }
+    public void cancelSubscription(UUID subscriptionId, EntitlementEvent cancelEvent);
 
-    @Override
-    public List<IEvent> getEventsReady(final UUID ownerId, final int sequenceId) {
+    public void uncancelSubscription(UUID subscriptionId, List<EntitlementEvent> uncancelEvents);
 
-        final Date now = clock.getUTCNow().toDate();
-        final Date nextAvailable = clock.getUTCNow().plus(config.getDaoClaimTimeMs()).toDate();
-
-        log.debug(String.format("EntitlementDao getEventsReady START effectiveNow =  %s", now));
-
-        List<IEvent> events = eventsDao.inTransaction(new Transaction<List<IEvent>, IEventSqlDao>() {
-
-            @Override
-            public List<IEvent> inTransaction(IEventSqlDao dao,
-                    TransactionStatus status) throws Exception {
-
-                List<IEvent> claimedEvents = new ArrayList<IEvent>();
-                List<IEvent> input = dao.getReadyEvents(now, config.getDaoMaxReadyEvents());
-                for (IEvent cur : input) {
-                    final boolean claimed = (dao.claimEvent(ownerId.toString(), nextAvailable, cur.getId().toString(), now) == 1);
-                    if (claimed) {
-                        claimedEvents.add(cur);
-                        dao.insertClaimedHistory(sequenceId, ownerId.toString(), hostname, now, cur.getId().toString());
-                    }
-                }
-                return claimedEvents;
-            }
-        });
-
-        for (IEvent cur : events) {
-            log.debug(String.format("EntitlementDao %s [host %s] claimed events %s", ownerId, hostname, cur.getId()));
-            if (cur.getOwner() != null && !cur.getOwner().equals(ownerId)) {
-                log.warn(String.format("EventProcessor %s stealing event %s from %s", ownerId, cur, cur.getOwner()));
-            }
-        }
-        return events;
-    }
-
-    @Override
-    public void clearEventsReady(final UUID ownerId, final Collection<IEvent> cleared) {
-
-        log.debug(String.format("EntitlementDao clearEventsReady START cleared size = %d", cleared.size()));
-
-        eventsDao.inTransaction(new Transaction<Void, IEventSqlDao>() {
-
-            @Override
-            public Void inTransaction(IEventSqlDao dao,
-                    TransactionStatus status) throws Exception {
-                // STEPH Same here batch would nice
-                for (IEvent cur : cleared) {
-                    dao.clearEvent(cur.getId().toString(), ownerId.toString());
-                    log.debug(String.format("EntitlementDao %s [host %s] cleared events %s", ownerId, hostname, cur.getId()));
-                }
-                return null;
-            }
-        });
-    }
-
-    @Override
-    public ISubscription createSubscription(final Subscription subscription,
-            final List<IEvent> initialEvents) {
-
-        subscriptionsDao.inTransaction(new Transaction<Void, ISubscriptionSqlDao>() {
-
-            @Override
-            public Void inTransaction(ISubscriptionSqlDao dao,
-                    TransactionStatus status) throws Exception {
-
-                dao.insertSubscription(subscription);
-                // STEPH batch as well
-                IEventSqlDao eventsDaoFromSameTranscation = dao.become(IEventSqlDao.class);
-                for (IEvent cur : initialEvents) {
-                    eventsDaoFromSameTranscation.insertEvent(cur);
-                }
-                return null;
-            }
-        });
-        return new Subscription(new SubscriptionBuilder(subscription), true);
-    }
-
-    @Override
-    public void cancelSubscription(final UUID subscriptionId, final IEvent cancelEvent) {
-
-        eventsDao.inTransaction(new Transaction<Void, IEventSqlDao>() {
-            @Override
-            public Void inTransaction(IEventSqlDao dao,
-                    TransactionStatus status) throws Exception {
-                cancelNextChangeEventFromTransaction(subscriptionId, dao);
-                cancelNextPhaseEventFromTransaction(subscriptionId, dao);
-                dao.insertEvent(cancelEvent);
-                return null;
-            }
-        });
-    }
-
-    @Override
-    public void uncancelSubscription(final UUID subscriptionId, final List<IEvent> uncancelEvents) {
-
-        eventsDao.inTransaction(new Transaction<Void, IEventSqlDao>() {
-
-            @Override
-            public Void inTransaction(IEventSqlDao dao,
-                    TransactionStatus status) throws Exception {
-
-                UUID existingCancelId = null;
-                Date now = clock.getUTCNow().toDate();
-                List<IEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
-
-                for (IEvent cur : events) {
-                    if (cur.getType() == EventType.API_USER && ((IApiEvent) cur).getEventType() == ApiEventType.CANCEL) {
-                        if (existingCancelId != null) {
-                            throw new EntitlementError(String.format("Found multiple cancel active events for subscriptions %s", subscriptionId.toString()));
-                        }
-                        existingCancelId = cur.getId();
-                    }
-                }
-
-                if (existingCancelId != null) {
-                    dao.unactiveEvent(existingCancelId.toString(), now);
-                    for (IEvent cur : uncancelEvents) {
-                        dao.insertEvent(cur);
-                    }
-                }
-                return null;
-            }
-        });
-    }
-
-    @Override
-    public void changePlan(final UUID subscriptionId, final List<IEvent> changeEvents) {
-        eventsDao.inTransaction(new Transaction<Void, IEventSqlDao>() {
-            @Override
-            public Void inTransaction(IEventSqlDao dao,
-                    TransactionStatus status) throws Exception {
-                cancelNextChangeEventFromTransaction(subscriptionId, dao);
-                cancelNextPhaseEventFromTransaction(subscriptionId, dao);
-                for (IEvent cur : changeEvents) {
-                    dao.insertEvent(cur);
-                }
-                return null;
-            }
-        });
-    }
-
-    private void cancelNextPhaseEventFromTransaction(final UUID subscriptionId, final IEventSqlDao dao) {
-        cancelFutureEventFromTransaction(subscriptionId, dao, EventType.PHASE, null);
-    }
-
-    private void cancelNextChangeEventFromTransaction(final UUID subscriptionId, final IEventSqlDao dao) {
-        cancelFutureEventFromTransaction(subscriptionId, dao, EventType.API_USER, ApiEventType.CHANGE);
-    }
-
-    private void cancelFutureEventFromTransaction(final UUID subscriptionId, final IEventSqlDao dao, EventType type, ApiEventType apiType) {
-
-        UUID futureEventId = null;
-        Date now = clock.getUTCNow().toDate();
-        List<IEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
-        for (IEvent cur : events) {
-            if (cur.getType() == type &&
-                    (apiType == null || apiType == ((IApiEvent) cur).getEventType() )) {
-                if (futureEventId != null) {
-                    throw new EntitlementError(
-                            String.format("Found multiple future events for type %s for subscriptions %s",
-                                    type, subscriptionId.toString()));
-                }
-                futureEventId = cur.getId();
-            }
-        }
-
-        if (futureEventId != null) {
-            dao.unactiveEvent(futureEventId.toString(), now);
-        }
-    }
+    public void changePlan(UUID subscriptionId, List<EntitlementEvent> changeEvents);
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
new file mode 100644
index 0000000..3838845
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/dao/EntitlementSqlDao.java
@@ -0,0 +1,332 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.entitlement.engine.dao;
+
+import com.google.inject.Inject;
+import com.ning.billing.catalog.api.ProductCategory;
+import com.ning.billing.config.EntitlementConfig;
+import com.ning.billing.entitlement.api.user.*;
+import com.ning.billing.entitlement.api.user.SubscriptionFactory.SubscriptionBuilder;
+import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.entitlement.events.EntitlementEvent.EventType;
+import com.ning.billing.entitlement.events.user.ApiEvent;
+import com.ning.billing.entitlement.events.user.ApiEventType;
+import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.util.Hostname;
+import com.ning.billing.util.clock.Clock;
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+public class EntitlementSqlDao implements EntitlementDao {
+
+    private final static Logger log = LoggerFactory.getLogger(EntitlementSqlDao.class);
+
+    private final Clock clock;
+    private final SubscriptionSqlDao subscriptionsDao;
+    private final BundleSqlDao bundlesDao;
+    private final EventSqlDao eventsDao;
+    private final EntitlementConfig config;
+    private final String hostname;
+    private final SubscriptionFactory factory;
+
+    @Inject
+    public EntitlementSqlDao(DBI dbi, Clock clock, EntitlementConfig config, SubscriptionFactory factory) {
+        this.clock = clock;
+        this.config = config;
+        this.factory = factory;
+        this.subscriptionsDao = dbi.onDemand(SubscriptionSqlDao.class);
+        this.eventsDao = dbi.onDemand(EventSqlDao.class);
+        this.bundlesDao = dbi.onDemand(BundleSqlDao.class);
+        this.hostname = Hostname.get();
+    }
+
+    @Override
+    public List<SubscriptionBundle> getSubscriptionBundleForAccount(
+            UUID accountId) {
+        return bundlesDao.getBundleFromAccount(accountId.toString());
+    }
+
+    @Override
+    public SubscriptionBundle getSubscriptionBundleFromId(UUID bundleId) {
+        return bundlesDao.getBundleFromId(bundleId.toString());
+    }
+
+    @Override
+    public SubscriptionBundle createSubscriptionBundle(SubscriptionBundleData bundle) {
+        bundlesDao.insertBundle(bundle);
+        return bundle;
+    }
+
+    @Override
+    public Subscription getSubscriptionFromId(UUID subscriptionId) {
+        return buildSubscription(subscriptionsDao.getSubscriptionFromId(subscriptionId.toString()));
+    }
+
+    @Override
+    public Subscription getBaseSubscription(final UUID bundleId) {
+
+        List<Subscription> subscriptions = subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString());
+        for (Subscription cur : subscriptions) {
+            if (((SubscriptionData)cur).getCategory() == ProductCategory.BASE) {
+                return  buildSubscription(cur);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public List<Subscription> getSubscriptions(UUID bundleId) {
+        return buildSubscription(subscriptionsDao.getSubscriptionsFromBundleId(bundleId.toString()));
+    }
+
+    @Override
+    public List<Subscription> getSubscriptionsForKey(String bundleKey) {
+        SubscriptionBundle bundle =  bundlesDao.getBundleFromKey(bundleKey);
+        if (bundle == null) {
+            return Collections.emptyList();
+        }
+        return buildSubscription(subscriptionsDao.getSubscriptionsFromBundleId(bundle.getId().toString()));
+    }
+
+    @Override
+    public void updateSubscription(SubscriptionData subscription) {
+        Date ctd = (subscription.getChargedThroughDate() != null)  ? subscription.getChargedThroughDate().toDate() : null;
+        Date ptd = (subscription.getPaidThroughDate() != null)  ? subscription.getPaidThroughDate().toDate() : null;
+        subscriptionsDao.updateSubscription(subscription.getId().toString(), subscription.getActiveVersion(), ctd, ptd);
+    }
+
+    @Override
+    public void createNextPhaseEvent(final UUID subscriptionId, final EntitlementEvent nextPhase) {
+        eventsDao.inTransaction(new Transaction<Void, EventSqlDao>() {
+
+            @Override
+            public Void inTransaction(EventSqlDao dao,
+                    TransactionStatus status) throws Exception {
+                cancelNextPhaseEventFromTransaction(subscriptionId, dao);
+                dao.insertEvent(nextPhase);
+                return null;
+            }
+        });
+    }
+
+
+    @Override
+    public List<EntitlementEvent> getEventsForSubscription(UUID subscriptionId) {
+        List<EntitlementEvent> events = eventsDao.getEventsForSubscription(subscriptionId.toString());
+        return events;
+    }
+
+    @Override
+    public List<EntitlementEvent> getPendingEventsForSubscription(UUID subscriptionId) {
+        Date now = clock.getUTCNow().toDate();
+        List<EntitlementEvent> results = eventsDao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
+        return results;
+    }
+
+    @Override
+    public List<EntitlementEvent> getEventsReady(final UUID ownerId, final int sequenceId) {
+
+        final Date now = clock.getUTCNow().toDate();
+        final Date nextAvailable = clock.getUTCNow().plus(config.getDaoClaimTimeMs()).toDate();
+
+        log.debug(String.format("EntitlementDao getEventsReady START effectiveNow =  %s", now));
+
+        List<EntitlementEvent> events = eventsDao.inTransaction(new Transaction<List<EntitlementEvent>, EventSqlDao>() {
+
+            @Override
+            public List<EntitlementEvent> inTransaction(EventSqlDao dao,
+                    TransactionStatus status) throws Exception {
+
+                List<EntitlementEvent> claimedEvents = new ArrayList<EntitlementEvent>();
+                List<EntitlementEvent> input = dao.getReadyEvents(now, config.getDaoMaxReadyEvents());
+                for (EntitlementEvent cur : input) {
+                    final boolean claimed = (dao.claimEvent(ownerId.toString(), nextAvailable, cur.getId().toString(), now) == 1);
+                    if (claimed) {
+                        claimedEvents.add(cur);
+                        dao.insertClaimedHistory(sequenceId, ownerId.toString(), hostname, now, cur.getId().toString());
+                    }
+                }
+                return claimedEvents;
+            }
+        });
+
+        for (EntitlementEvent cur : events) {
+            log.debug(String.format("EntitlementDao %s [host %s] claimed events %s", ownerId, hostname, cur.getId()));
+            if (cur.getOwner() != null && !cur.getOwner().equals(ownerId)) {
+                log.warn(String.format("EventProcessor %s stealing event %s from %s", ownerId, cur, cur.getOwner()));
+            }
+        }
+        return events;
+    }
+
+    @Override
+    public void clearEventsReady(final UUID ownerId, final Collection<EntitlementEvent> cleared) {
+
+        log.debug(String.format("EntitlementDao clearEventsReady START cleared size = %d", cleared.size()));
+
+        eventsDao.inTransaction(new Transaction<Void, EventSqlDao>() {
+
+            @Override
+            public Void inTransaction(EventSqlDao dao,
+                    TransactionStatus status) throws Exception {
+                // STEPH Same here batch would nice
+                for (EntitlementEvent cur : cleared) {
+                    dao.clearEvent(cur.getId().toString(), ownerId.toString());
+                    log.debug(String.format("EntitlementDao %s [host %s] cleared events %s", ownerId, hostname, cur.getId()));
+                }
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public void createSubscription(final SubscriptionData subscription,
+            final List<EntitlementEvent> initialEvents) {
+
+        subscriptionsDao.inTransaction(new Transaction<Void, SubscriptionSqlDao>() {
+
+            @Override
+            public Void inTransaction(SubscriptionSqlDao dao,
+                    TransactionStatus status) throws Exception {
+
+                dao.insertSubscription(subscription);
+                // STEPH batch as well
+                EventSqlDao eventsDaoFromSameTranscation = dao.become(EventSqlDao.class);
+                for (EntitlementEvent cur : initialEvents) {
+                    eventsDaoFromSameTranscation.insertEvent(cur);
+                }
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public void cancelSubscription(final UUID subscriptionId, final EntitlementEvent cancelEvent) {
+
+        eventsDao.inTransaction(new Transaction<Void, EventSqlDao>() {
+            @Override
+            public Void inTransaction(EventSqlDao dao,
+                    TransactionStatus status) throws Exception {
+                cancelNextChangeEventFromTransaction(subscriptionId, dao);
+                cancelNextPhaseEventFromTransaction(subscriptionId, dao);
+                dao.insertEvent(cancelEvent);
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public void uncancelSubscription(final UUID subscriptionId, final List<EntitlementEvent> uncancelEvents) {
+
+        eventsDao.inTransaction(new Transaction<Void, EventSqlDao>() {
+
+            @Override
+            public Void inTransaction(EventSqlDao dao,
+                    TransactionStatus status) throws Exception {
+
+                UUID existingCancelId = null;
+                Date now = clock.getUTCNow().toDate();
+                List<EntitlementEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
+
+                for (EntitlementEvent cur : events) {
+                    if (cur.getType() == EventType.API_USER && ((ApiEvent) cur).getEventType() == ApiEventType.CANCEL) {
+                        if (existingCancelId != null) {
+                            throw new EntitlementError(String.format("Found multiple cancel active events for subscriptions %s", subscriptionId.toString()));
+                        }
+                        existingCancelId = cur.getId();
+                    }
+                }
+
+                if (existingCancelId != null) {
+                    dao.unactiveEvent(existingCancelId.toString(), now);
+                    for (EntitlementEvent cur : uncancelEvents) {
+                        dao.insertEvent(cur);
+                    }
+                }
+                return null;
+            }
+        });
+    }
+
+    @Override
+    public void changePlan(final UUID subscriptionId, final List<EntitlementEvent> changeEvents) {
+        eventsDao.inTransaction(new Transaction<Void, EventSqlDao>() {
+            @Override
+            public Void inTransaction(EventSqlDao dao,
+                    TransactionStatus status) throws Exception {
+                cancelNextChangeEventFromTransaction(subscriptionId, dao);
+                cancelNextPhaseEventFromTransaction(subscriptionId, dao);
+                for (EntitlementEvent cur : changeEvents) {
+                    dao.insertEvent(cur);
+                }
+                return null;
+            }
+        });
+    }
+
+    private void cancelNextPhaseEventFromTransaction(final UUID subscriptionId, final EventSqlDao dao) {
+        cancelFutureEventFromTransaction(subscriptionId, dao, EventType.PHASE, null);
+    }
+
+    private void cancelNextChangeEventFromTransaction(final UUID subscriptionId, final EventSqlDao dao) {
+        cancelFutureEventFromTransaction(subscriptionId, dao, EventType.API_USER, ApiEventType.CHANGE);
+    }
+
+    private void cancelFutureEventFromTransaction(final UUID subscriptionId, final EventSqlDao dao, EventType type, ApiEventType apiType) {
+
+        UUID futureEventId = null;
+        Date now = clock.getUTCNow().toDate();
+        List<EntitlementEvent> events = dao.getFutureActiveEventForSubscription(subscriptionId.toString(), now);
+        for (EntitlementEvent cur : events) {
+            if (cur.getType() == type &&
+                    (apiType == null || apiType == ((ApiEvent) cur).getEventType() )) {
+                if (futureEventId != null) {
+                    throw new EntitlementError(
+                            String.format("Found multiple future events for type %s for subscriptions %s",
+                                    type, subscriptionId.toString()));
+                }
+                futureEventId = cur.getId();
+            }
+        }
+
+        if (futureEventId != null) {
+            dao.unactiveEvent(futureEventId.toString(), now);
+        }
+    }
+
+    private Subscription buildSubscription(Subscription input) {
+        if (input == null) {
+            return null;
+        }
+        return buildSubscription(Collections.singletonList(input)).get(0);
+    }
+
+    private List<Subscription> buildSubscription(List<Subscription> input) {
+        List<Subscription> result = new ArrayList<Subscription>(input.size());
+        for (Subscription cur : input) {
+            List<EntitlementEvent> events = eventsDao.getEventsForSubscription(cur.getId().toString());
+            Subscription reloaded =   factory.createSubscription(new SubscriptionBuilder((SubscriptionData) cur), events);
+            result.add(reloaded);
+        }
+        return result;
+    }
+}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java
index e909be6..d0db679 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBase.java
@@ -16,13 +16,13 @@
 
 package com.ning.billing.entitlement.events;
 
-import com.ning.billing.entitlement.events.user.IApiEvent;
+import com.ning.billing.entitlement.events.user.ApiEvent;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
 import org.joda.time.DateTime;
 
 import java.util.UUID;
 
-public abstract class EventBase implements IEvent {
+public abstract class EventBase implements EntitlementEvent {
 
     private final UUID uuid;
     private final UUID subscriptionId;
@@ -35,7 +35,7 @@ public abstract class EventBase implements IEvent {
     private boolean isActive;
     private UUID processingOwner;
     private DateTime nextAvailableProcessingTime;
-    private IEventLyfecycleState processingState;
+    private EventLifecycleState processingState;
 
     public EventBase(EventBaseBuilder builder) {
         this.uuid = builder.getUuid();
@@ -54,14 +54,14 @@ public abstract class EventBase implements IEvent {
     public EventBase(UUID subscriptionId, DateTime requestedDate,
             DateTime effectiveDate, DateTime processedDate,
             long activeVersion, boolean isActive) {
-        this(subscriptionId, requestedDate, effectiveDate, processedDate, activeVersion, isActive, null, null, IEventLyfecycleState.AVAILABLE);
+        this(subscriptionId, requestedDate, effectiveDate, processedDate, activeVersion, isActive, null, null, EventLifecycleState.AVAILABLE);
     }
 
     private EventBase(UUID subscriptionId, DateTime requestedDate,
             DateTime effectiveDate, DateTime processedDate,
             long activeVersion, boolean isActive,
             UUID processingOwner, DateTime nextAvailableProcessingTime,
-            IEventLyfecycleState processingState) {
+            EventLifecycleState processingState) {
         this(UUID.randomUUID(), subscriptionId, requestedDate, effectiveDate, processedDate, activeVersion, isActive,
                 processingOwner, nextAvailableProcessingTime, processingState);
     }
@@ -70,7 +70,7 @@ public abstract class EventBase implements IEvent {
             DateTime effectiveDate, DateTime processedDate,
             long activeVersion, boolean isActive,
             UUID processingOwner, DateTime nextAvailableProcessingTime,
-            IEventLyfecycleState processingState) {
+            EventLifecycleState processingState) {
         this.uuid = id;
         this.subscriptionId = subscriptionId;
         this.requestedDate = requestedDate;
@@ -160,12 +160,12 @@ public abstract class EventBase implements IEvent {
 
 
     @Override
-    public IEventLyfecycleState getProcessingState() {
+    public EventLifecycleState getProcessingState() {
         return processingState;
     }
 
     @Override
-    public void setProcessingState(IEventLyfecycleState processingState) {
+    public void setProcessingState(EventLifecycleState processingState) {
         this.processingState = processingState;
     }
 
@@ -204,7 +204,7 @@ public abstract class EventBase implements IEvent {
     // - If all that is not enough return consistent by random ordering based on UUID
     //
     @Override
-    public int compareTo(IEvent other) {
+    public int compareTo(EntitlementEvent other) {
         if (other == null) {
             throw new NullPointerException("IEvent is compared to a null instance");
         }
@@ -224,7 +224,7 @@ public abstract class EventBase implements IEvent {
         } else if (getType() != other.getType()) {
             return (getType() == EventType.PHASE) ? -1 : 1;
         } else if (getType() == EventType.API_USER) {
-            return ((IApiEvent) this).getEventType().compareTo(((IApiEvent) other).getEventType());
+            return ((ApiEvent) this).getEventType().compareTo(((ApiEvent) other).getEventType());
         } else {
             return uuid.compareTo(other.getId());
         }
@@ -233,10 +233,10 @@ public abstract class EventBase implements IEvent {
 
     @Override
     public boolean equals(Object other) {
-      if (! (other instanceof IEvent)) {
+      if (! (other instanceof EntitlementEvent)) {
           return false;
       }
-      return (this.compareTo((IEvent) other) == 0);
+      return (this.compareTo((EntitlementEvent) other) == 0);
     }
 
     @Override
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java
index 03b0483..104fbef 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/EventBaseBuilder.java
@@ -16,7 +16,7 @@
 
 package com.ning.billing.entitlement.events;
 
-import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
+import com.ning.billing.entitlement.events.EventLifecycle.EventLifecycleState;
 import org.joda.time.DateTime;
 
 import java.util.UUID;
@@ -34,13 +34,13 @@ public class EventBaseBuilder<T extends EventBaseBuilder<T>> {
     private boolean isActive;
     private UUID processingOwner;
     private DateTime nextAvailableProcessingTime;
-    private IEventLyfecycleState processingState;
+    private EventLifecycleState processingState;
 
 
     public EventBaseBuilder() {
         this.uuid = UUID.randomUUID();
         this.isActive = true;
-        this.processingState = IEventLyfecycleState.AVAILABLE;
+        this.processingState = EventLifecycleState.AVAILABLE;
     }
 
     public EventBaseBuilder(EventBaseBuilder<?> copy) {
@@ -102,7 +102,7 @@ public class EventBaseBuilder<T extends EventBaseBuilder<T>> {
         return (T) this;
     }
 
-    public T setProcessingState(IEventLyfecycleState processingState) {
+    public T setProcessingState(EventLifecycleState processingState) {
         this.processingState = processingState;
         return (T) this;
     }
@@ -143,7 +143,7 @@ public class EventBaseBuilder<T extends EventBaseBuilder<T>> {
         return nextAvailableProcessingTime;
     }
 
-    public IEventLyfecycleState getProcessingState() {
+    public EventLifecycleState getProcessingState() {
         return processingState;
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEvent.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEvent.java
index 1e98a27..8e9ab2c 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEvent.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEvent.java
@@ -16,55 +16,9 @@
 
 package com.ning.billing.entitlement.events.phase;
 
+import com.ning.billing.entitlement.events.EntitlementEvent;
 
-import com.ning.billing.entitlement.alignment.IPlanAligner.TimedPhase;
-import com.ning.billing.entitlement.api.user.Subscription;
-import com.ning.billing.entitlement.events.EventBase;
-import org.joda.time.DateTime;
+public interface PhaseEvent extends EntitlementEvent {
 
-
-public class PhaseEvent extends EventBase implements IPhaseEvent {
-
-    private final String phaseName;
-
-    public PhaseEvent(PhaseEventBuilder builder) {
-        super(builder);
-        this.phaseName = builder.getPhaseName();
-    }
-
-    @Override
-    public EventType getType() {
-        return EventType.PHASE;
-    }
-
-    @Override
-    public String getPhase() {
-        return phaseName;
-    }
-
-    @Override
-    public String toString() {
-        return "PhaseEvent [getId()= " + getId()
-        		+ ", phaseName=" + phaseName
-        		+ ", getType()=" + getType()
-                + ", getPhase()=" + getPhase()
-                + ", getRequestedDate()=" + getRequestedDate()
-                + ", getEffectiveDate()=" + getEffectiveDate()
-                + ", getActiveVersion()=" + getActiveVersion()
-                + ", getProcessedDate()=" + getProcessedDate()
-                + ", getSubscriptionId()=" + getSubscriptionId()
-                + ", isActive()=" + isActive() + "]\n";
-    }
-
-    public static final IPhaseEvent getNextPhaseEvent(TimedPhase nextTimedPhase, Subscription subscription, DateTime now) {
-        return (nextTimedPhase == null) ?
-                null :
-                    new PhaseEvent(new PhaseEventBuilder()
-                        .setSubscriptionId(subscription.getId())
-                        .setRequestedDate(now)
-                        .setEffectiveDate(nextTimedPhase.getStartPhase())
-                        .setProcessedDate(now)
-                        .setActiveVersion(subscription.getActiveVersion())
-                        .setPhaseName(nextTimedPhase.getPhase().getName()));
-    }
+    public String getPhase();
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventData.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventData.java
new file mode 100644
index 0000000..be0ab6c
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/phase/PhaseEventData.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.entitlement.events.phase;
+
+
+import com.ning.billing.entitlement.alignment.TimedPhase;
+import com.ning.billing.entitlement.api.user.SubscriptionData;
+import com.ning.billing.entitlement.events.EventBase;
+import org.joda.time.DateTime;
+
+
+public class PhaseEventData extends EventBase implements PhaseEvent {
+
+    private final String phaseName;
+
+    public PhaseEventData(PhaseEventBuilder builder) {
+        super(builder);
+        this.phaseName = builder.getPhaseName();
+    }
+
+    @Override
+    public EventType getType() {
+        return EventType.PHASE;
+    }
+
+    @Override
+    public String getPhase() {
+        return phaseName;
+    }
+
+    @Override
+    public String toString() {
+        return "PhaseEvent [getId()= " + getId()
+        		+ ", phaseName=" + phaseName
+        		+ ", getType()=" + getType()
+                + ", getPhase()=" + getPhase()
+                + ", getRequestedDate()=" + getRequestedDate()
+                + ", getEffectiveDate()=" + getEffectiveDate()
+                + ", getActiveVersion()=" + getActiveVersion()
+                + ", getProcessedDate()=" + getProcessedDate()
+                + ", getSubscriptionId()=" + getSubscriptionId()
+                + ", isActive()=" + isActive() + "]\n";
+    }
+
+    public static final PhaseEvent getNextPhaseEvent(TimedPhase nextTimedPhase, SubscriptionData subscription, DateTime now) {
+        return (nextTimedPhase == null) ?
+                null :
+                    new PhaseEventData(new PhaseEventBuilder()
+                        .setSubscriptionId(subscription.getId())
+                        .setRequestedDate(now)
+                        .setEffectiveDate(nextTimedPhase.getStartPhase())
+                        .setProcessedDate(now)
+                        .setActiveVersion(subscription.getActiveVersion())
+                        .setPhaseName(nextTimedPhase.getPhase().getName()));
+    }
+}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java
index 825a4a5..3f033a4 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventBase.java
@@ -21,7 +21,7 @@ import org.joda.time.DateTime;
 
 import java.util.UUID;
 
-public class ApiEventBase extends EventBase implements IApiEvent {
+public class ApiEventBase extends EventBase implements ApiEvent {
 
     private final ApiEventType eventType;
     // Only valid for CREATE/CHANGE
@@ -60,7 +60,7 @@ public class ApiEventBase extends EventBase implements IApiEvent {
 
     public ApiEventBase(UUID id, UUID subscriptionId, DateTime processed, String eventPlan, String eventPhase,
             String priceList, DateTime requestedDate,  ApiEventType eventType, DateTime effectiveDate, long activeVersion,
-            boolean isActive, UUID processingOwner, DateTime nextAvailableProcessingTime,IEventLyfecycleState processingState) {
+            boolean isActive, UUID processingOwner, DateTime nextAvailableProcessingTime,EventLifecycleState processingState) {
         super(id, subscriptionId, requestedDate, effectiveDate, processed, activeVersion, isActive, processingOwner, nextAvailableProcessingTime, processingState);
         this.eventType = eventType;
         this.eventPlan = eventPlan;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventType.java b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventType.java
index 3d66a5b..c28941e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventType.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/events/user/ApiEventType.java
@@ -16,7 +16,7 @@
 
 package com.ning.billing.entitlement.events.user;
 
-import com.ning.billing.entitlement.api.user.ISubscriptionTransition.SubscriptionTransitionType;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition.SubscriptionTransitionType;
 
 
 public enum ApiEventType {
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java b/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
index 89b58c8..1a9fffc 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/glue/EntitlementModule.java
@@ -16,26 +16,25 @@
 
 package com.ning.billing.entitlement.glue;
 
-import org.skife.config.ConfigurationObjectFactory;
-
 import com.google.inject.AbstractModule;
-import com.ning.billing.config.IEntitlementConfig;
-import com.ning.billing.entitlement.alignment.IPlanAligner;
+import com.ning.billing.config.EntitlementConfig;
 import com.ning.billing.entitlement.alignment.PlanAligner;
-import com.ning.billing.entitlement.api.IEntitlementService;
+import com.ning.billing.entitlement.api.EntitlementService;
+import com.ning.billing.entitlement.api.billing.DefaultEntitlementBillingApi;
 import com.ning.billing.entitlement.api.billing.EntitlementBillingApi;
-import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
+import com.ning.billing.entitlement.api.test.DefaultEntitlementTestApi;
 import com.ning.billing.entitlement.api.test.EntitlementTestApi;
-import com.ning.billing.entitlement.api.test.IEntitlementTestApi;
+import com.ning.billing.entitlement.api.user.DefaultEntitlementUserApi;
 import com.ning.billing.entitlement.api.user.EntitlementUserApi;
-import com.ning.billing.entitlement.api.user.IEntitlementUserApi;
-import com.ning.billing.entitlement.engine.core.ApiEventProcessor;
+import com.ning.billing.entitlement.api.user.SubscriptionApiService;
+import com.ning.billing.entitlement.engine.core.DefaultApiEventProcessor;
 import com.ning.billing.entitlement.engine.core.Engine;
-import com.ning.billing.entitlement.engine.core.IApiEventProcessor;
+import com.ning.billing.entitlement.engine.core.EventNotifier;
 import com.ning.billing.entitlement.engine.dao.EntitlementDao;
-import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
+import com.ning.billing.entitlement.engine.dao.EntitlementSqlDao;
 import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.clock.IClock;
+import com.ning.billing.util.clock.DefaultClock;
+import org.skife.config.ConfigurationObjectFactory;
 
 
 
@@ -43,38 +42,34 @@ public class EntitlementModule extends AbstractModule {
 
 
     protected void installClock() {
-        bind(IClock.class).to(Clock.class).asEagerSingleton();
+        bind(Clock.class).to(DefaultClock.class).asEagerSingleton();
     }
 
     protected void installConfig() {
-        final IEntitlementConfig config = new ConfigurationObjectFactory(System.getProperties()).build(IEntitlementConfig.class);
-        bind(IEntitlementConfig.class).toInstance(config);
+        final EntitlementConfig config = new ConfigurationObjectFactory(System.getProperties()).build(EntitlementConfig.class);
+        bind(EntitlementConfig.class).toInstance(config);
     }
 
     protected void installApiEventProcessor() {
-        bind(IApiEventProcessor.class).to(ApiEventProcessor.class).asEagerSingleton();
+        bind(EventNotifier.class).to(DefaultApiEventProcessor.class).asEagerSingleton();
     }
 
     protected void installEntitlementDao() {
-        bind(IEntitlementDao.class).to(EntitlementDao.class).asEagerSingleton();
+        bind(EntitlementDao.class).to(EntitlementSqlDao.class).asEagerSingleton();
     }
 
     protected void installEntitlementCore() {
-        bind(IEntitlementService.class).to(Engine.class).asEagerSingleton();
+        bind(SubscriptionApiService.class).asEagerSingleton();
+        bind(EntitlementService.class).to(Engine.class).asEagerSingleton();
         bind(Engine.class).asEagerSingleton();
-        bind(IPlanAligner.class).to(PlanAligner.class).asEagerSingleton();
-        bind(IEntitlementTestApi.class).to(EntitlementTestApi.class).asEagerSingleton();
-        bind(IEntitlementUserApi.class).to(EntitlementUserApi.class).asEagerSingleton();
-        bind(IEntitlementBillingApi.class).to(EntitlementBillingApi.class).asEagerSingleton();
-    }
-
-    protected void installInjectorMagic() {
-        bind(InjectorMagic.class).asEagerSingleton();
+        bind(PlanAligner.class).asEagerSingleton();
+        bind(EntitlementTestApi.class).to(DefaultEntitlementTestApi.class).asEagerSingleton();
+        bind(EntitlementUserApi.class).to(DefaultEntitlementUserApi.class).asEagerSingleton();
+        bind(EntitlementBillingApi.class).to(DefaultEntitlementBillingApi.class).asEagerSingleton();
     }
 
     @Override
     protected void configure() {
-        installInjectorMagic();
         installConfig();
         installClock();
         installApiEventProcessor();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java
index d142cf5..f76f775 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/ApiTestListener.java
@@ -18,8 +18,8 @@ package com.ning.billing.entitlement.api;
 
 import com.google.common.base.Joiner;
 import com.google.common.eventbus.Subscribe;
-import com.ning.billing.entitlement.api.user.ISubscriptionTransition;
-import com.ning.billing.util.eventbus.IEventBus;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
+import com.ning.billing.util.eventbus.EventBus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,13 +44,13 @@ public class ApiTestListener {
         PHASE
     }
 
-    public ApiTestListener(IEventBus eventBus) {
+    public ApiTestListener(EventBus eventBus) {
         this.nextExpectedEvent = new Stack<NextEvent>();
         this.completed = false;
     }
 
     @Subscribe
-    public void handleEntitlementEvent(ISubscriptionTransition event) {
+    public void handleEntitlementEvent(SubscriptionTransition event) {
         switch (event.getTransitionType()) {
         case CREATE:
             subscriptionCreated(event);
@@ -135,35 +135,35 @@ public class ApiTestListener {
     }
 
 
-    public void subscriptionCreated(ISubscriptionTransition created) {
+    public void subscriptionCreated(SubscriptionTransition created) {
         log.debug("-> Got event CREATED");
         assertEqualsNicely(NextEvent.CREATE);
         notifyIfStackEmpty();
     }
 
 
-    public void subscriptionCancelled(ISubscriptionTransition cancelled) {
+    public void subscriptionCancelled(SubscriptionTransition cancelled) {
         log.debug("-> Got event CANCEL");
         assertEqualsNicely(NextEvent.CANCEL);
         notifyIfStackEmpty();
     }
 
 
-    public void subscriptionChanged(ISubscriptionTransition changed) {
+    public void subscriptionChanged(SubscriptionTransition changed) {
         log.debug("-> Got event CHANGE");
         assertEqualsNicely(NextEvent.CHANGE);
         notifyIfStackEmpty();
     }
 
 
-    public void subscriptionPaused(ISubscriptionTransition paused) {
+    public void subscriptionPaused(SubscriptionTransition paused) {
         log.debug("-> Got event PAUSE");
         assertEqualsNicely(NextEvent.PAUSE);
         notifyIfStackEmpty();
     }
 
 
-    public void subscriptionResumed(ISubscriptionTransition resumed) {
+    public void subscriptionResumed(SubscriptionTransition resumed) {
         log.debug("-> Got event RESUME");
         assertEqualsNicely(NextEvent.RESUME);
         notifyIfStackEmpty();
@@ -171,7 +171,7 @@ public class ApiTestListener {
 
 
     public void subscriptionPhaseChanged(
-            ISubscriptionTransition phaseChanged) {
+            SubscriptionTransition phaseChanged) {
         log.debug("-> Got event PHASE");
         assertEqualsNicely(NextEvent.PHASE);
         notifyIfStackEmpty();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiBase.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiBase.java
index 9f7e3a6..e2fe2f3 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiBase.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiBase.java
@@ -19,26 +19,25 @@ package com.ning.billing.entitlement.api.user;
 import com.google.inject.Injector;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.FieldStore;
-import com.ning.billing.catalog.CatalogService;
+import com.ning.billing.catalog.DefaultCatalogService;
 import com.ning.billing.catalog.api.*;
-import com.ning.billing.config.IEntitlementConfig;
+import com.ning.billing.config.EntitlementConfig;
 import com.ning.billing.entitlement.api.ApiTestListener;
 import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
-import com.ning.billing.entitlement.api.IEntitlementService;
-import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
+import com.ning.billing.entitlement.api.EntitlementService;
+import com.ning.billing.entitlement.api.billing.EntitlementBillingApi;
 import com.ning.billing.entitlement.engine.core.Engine;
-import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
-import com.ning.billing.entitlement.engine.dao.IEntitlementDaoMock;
-import com.ning.billing.entitlement.events.IEvent;
-import com.ning.billing.entitlement.events.phase.IPhaseEvent;
+import com.ning.billing.entitlement.engine.dao.EntitlementDao;
+import com.ning.billing.entitlement.engine.dao.MockEntitlementDao;
+import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.entitlement.events.phase.PhaseEvent;
+import com.ning.billing.entitlement.events.user.ApiEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
-import com.ning.billing.entitlement.events.user.IApiEvent;
-import com.ning.billing.entitlement.glue.InjectorMagic;
-import com.ning.billing.lifecycle.IService.ServiceException;
+import com.ning.billing.lifecycle.KillbillService.ServiceException;
+import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
-import com.ning.billing.util.clock.IClock;
+import com.ning.billing.util.eventbus.DefaultEventBusService;
 import com.ning.billing.util.eventbus.EventBusService;
-import com.ning.billing.util.eventbus.IEventBusService;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,7 +46,6 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
-import sun.reflect.generics.reflectiveObjects.NotImplementedException;
 
 import java.io.IOException;
 import java.lang.reflect.Method;
@@ -64,19 +62,19 @@ public abstract class TestUserApiBase {
 
     protected static final long DAY_IN_MS = (24 * 3600 * 1000);
 
-    protected IEntitlementService entitlementService;
-    protected IEntitlementUserApi entitlementApi;
-    protected IEntitlementBillingApi billingApi;
-    protected ICatalogService catalogService;
-    protected IEntitlementConfig config;
-    protected IEntitlementDao dao;
+    protected EntitlementService entitlementService;
+    protected EntitlementUserApi entitlementApi;
+    protected EntitlementBillingApi billingApi;
+    protected CatalogService catalogService;
+    protected EntitlementConfig config;
+    protected EntitlementDao dao;
     protected ClockMock clock;
-    protected IEventBusService busService;
+    protected EventBusService busService;
 
     protected Account account;
-    protected ICatalog catalog;
+    protected Catalog catalog;
     protected ApiTestListener testListener;
-    protected ISubscriptionBundle bundle;
+    protected SubscriptionBundle bundle;
 
     public static void loadSystemPropertiesFromClasspath( final String resource )
     {
@@ -93,9 +91,8 @@ public abstract class TestUserApiBase {
     @AfterClass(groups={"setup"})
     public void tearDown() {
         try {
-            InjectorMagic.instance = null;
             busService.getEventBus().register(testListener);
-            ((EventBusService) busService).stopBus();
+            ((DefaultEventBusService) busService).stopBus();
         } catch (Exception e) {
             log.warn("Failed to tearDown test properly ", e);
         }
@@ -108,16 +105,16 @@ public abstract class TestUserApiBase {
         loadSystemPropertiesFromClasspath("/entitlement.properties");
         final Injector g = getInjector();
 
-        entitlementService = g.getInstance(IEntitlementService.class);
-        catalogService = g.getInstance(ICatalogService.class);
-        busService = g.getInstance(IEventBusService.class);
-        config = g.getInstance(IEntitlementConfig.class);
-        dao = g.getInstance(IEntitlementDao.class);
-        clock = (ClockMock) g.getInstance(IClock.class);
+        entitlementService = g.getInstance(EntitlementService.class);
+        catalogService = g.getInstance(CatalogService.class);
+        busService = g.getInstance(EventBusService.class);
+        config = g.getInstance(EntitlementConfig.class);
+        dao = g.getInstance(EntitlementDao.class);
+        clock = (ClockMock) g.getInstance(Clock.class);
         try {
 
-            ((CatalogService) catalogService).loadCatalog();
-            ((EventBusService) busService).startBus();
+            ((DefaultCatalogService) catalogService).loadCatalog();
+            ((DefaultEventBusService) busService).startBus();
             ((Engine) entitlementService).initialize();
             init();
         } catch (EntitlementUserApiException e) {
@@ -152,7 +149,7 @@ public abstract class TestUserApiBase {
         testListener.reset();
 
         clock.resetDeltaFromReality();
-        ((IEntitlementDaoMock) dao).reset();
+        ((MockEntitlementDao) dao).reset();
         try {
             busService.getEventBus().register(testListener);
             bundle = entitlementApi.createBundleForAccount(account, "myDefaultBundle");
@@ -194,17 +191,17 @@ public abstract class TestUserApiBase {
         }
     }
 
-    protected Subscription createSubscription(String productName, BillingPeriod term, String planSet) throws EntitlementUserApiException {
+    protected SubscriptionData createSubscription(String productName, BillingPeriod term, String planSet) throws EntitlementUserApiException {
         testListener.pushExpectedEvent(NextEvent.CREATE);
-        Subscription subscription = (Subscription) entitlementApi.createSubscription(bundle.getId(), productName, term, planSet, clock.getUTCNow());
+        SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(), productName, term, planSet, null, clock.getUTCNow());
         assertNotNull(subscription);
         assertTrue(testListener.isCompleted(5000));
         return subscription;
     }
 
-    protected void checkNextPhaseChange(Subscription subscription, int expPendingEvents, DateTime expPhaseChange) {
+    protected void checkNextPhaseChange(SubscriptionData subscription, int expPendingEvents, DateTime expPhaseChange) {
 
-        List<IEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
+        List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
         assertNotNull(events);
         printEvents(events);
         assertEquals(events.size(), expPendingEvents);
@@ -212,13 +209,13 @@ public abstract class TestUserApiBase {
             boolean foundPhase = false;
             boolean foundChange = false;
 
-            for (IEvent cur : events) {
-                if (cur instanceof IPhaseEvent) {
+            for (EntitlementEvent cur : events) {
+                if (cur instanceof PhaseEvent) {
                     assertEquals(foundPhase, false);
                     foundPhase = true;
                     assertEquals(cur.getEffectiveDate(), expPhaseChange);
-                } else if (cur instanceof IApiEvent) {
-                    IApiEvent uEvent = (IApiEvent) cur;
+                } else if (cur instanceof ApiEvent) {
+                    ApiEvent uEvent = (ApiEvent) cur;
                     assertEquals(ApiEventType.CHANGE, uEvent.getEventType());
                     assertEquals(foundChange, false);
                     foundChange = true;
@@ -235,8 +232,8 @@ public abstract class TestUserApiBase {
         assertTrue(in.isEqual(upper) || in.isBefore(upper));
     }
 
-    protected IDuration getDurationDay(final int days) {
-        IDuration result = new IDuration() {
+    protected Duration getDurationDay(final int days) {
+        Duration result = new Duration() {
             @Override
             public TimeUnit getUnit() {
                 return TimeUnit.DAYS;
@@ -249,8 +246,8 @@ public abstract class TestUserApiBase {
         return result;
     }
 
-    protected IDuration getDurationMonth(final int months) {
-        IDuration result = new IDuration() {
+    protected Duration getDurationMonth(final int months) {
+        Duration result = new Duration() {
             @Override
             public TimeUnit getUnit() {
                 return TimeUnit.MONTHS;
@@ -264,8 +261,8 @@ public abstract class TestUserApiBase {
     }
 
 
-    protected IDuration getDurationYear(final int years) {
-        IDuration result = new IDuration() {
+    protected Duration getDurationYear(final int years) {
+        Duration result = new Duration() {
             @Override
             public TimeUnit getUnit() {
                 return TimeUnit.YEARS;
@@ -280,14 +277,18 @@ public abstract class TestUserApiBase {
 
     protected Account getAccount() {
         Account account = new Account() {
+            private final UUID id = UUID.randomUUID();
+
             @Override
             public String getName() {
-                return "accountFirstName accountLastName";
+                return "firstName lastName";
             }
+
             @Override
             public int getFirstNameLength() {
-                return "accountFirstName".length();
+                return "firstName".length();
             }
+
             @Override
             public String getEmail() {
                 return "accountName@yahoo.com";
@@ -308,29 +309,28 @@ public abstract class TestUserApiBase {
             public Currency getCurrency() {
                 return Currency.USD;
             }
+
             @Override
             public UUID getId() {
-                return UUID.randomUUID();
+                return id;
             }
 
             @Override
             public String getIdAsString() {
-                throw new NotImplementedException();
+                return id.toString();
             }
 
             @Override
             public String getFieldValue(String fieldName) {
-                throw new NotImplementedException();
+                return null;
             }
 
             @Override
-            public void setFieldValue(String fieldName, String fieldValue) {
-                throw new NotImplementedException();
-            }
+            public void setFieldValue(String fieldName, String fieldValue) {}
 
             @Override
             public FieldStore getFields() {
-                throw new NotImplementedException();
+                return null;  //To change body of implemented methods use File | Settings | File Templates.
             }
 
             @Override
@@ -342,14 +342,14 @@ public abstract class TestUserApiBase {
     }
 
 
-    protected void printEvents(List<IEvent> events) {
-        for (IEvent cur : events) {
+    protected void printEvents(List<EntitlementEvent> events) {
+        for (EntitlementEvent cur : events) {
             log.debug("Inspect event " + cur);
         }
     }
 
-    protected void printSubscriptionTransitions(List<ISubscriptionTransition> transitions) {
-        for (ISubscriptionTransition cur : transitions) {
+    protected void printSubscriptionTransitions(List<SubscriptionTransition> transitions) {
+        for (SubscriptionTransition cur : transitions) {
             log.debug("Transition " + cur);
         }
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
index 6a8dee2..72e5556 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancel.java
@@ -16,24 +16,15 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-
+import com.ning.billing.catalog.api.*;
+import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
+import com.ning.billing.util.clock.DefaultClock;
 import org.joda.time.DateTime;
 import org.testng.Assert;
 
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IDuration;
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.catalog.api.IPlanPhase;
-import com.ning.billing.catalog.api.IPriceListSet;
-import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
-import com.ning.billing.util.clock.Clock;
+import java.util.List;
+
+import static org.testng.Assert.*;
 
 public abstract class TestUserApiCancel extends TestUserApiBase {
 
@@ -47,15 +38,15 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
             String prod = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = IPriceListSet.DEFAULT_PRICELIST_NAME;
+            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
-            Subscription subscription = createSubscription(prod, term, planSet);
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            SubscriptionData subscription = createSubscription(prod, term, planSet);
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
 
             // ADVANCE TIME still in trial
-            IDuration moveALittleInTime = getDurationDay(3);
+            Duration moveALittleInTime = getDurationDay(3);
             clock.setDeltaFromReality(moveALittleInTime, 0);
 
             DateTime future = clock.getUTCNow();
@@ -67,7 +58,7 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
             testListener.isCompleted(1000);
 
-            List<ISubscriptionTransition> allTransitions = subscription.getActiveTransitions();
+            List<SubscriptionTransition> allTransitions = subscription.getActiveTransitions();
             printSubscriptionTransitions(allTransitions);
 
             assertNull(currentPhase);
@@ -86,15 +77,15 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
             String prod = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = IPriceListSet.DEFAULT_PRICELIST_NAME;
+            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
-            Subscription subscription = createSubscription(prod, term, planSet);
-            IPlanPhase trialPhase = subscription.getCurrentPhase();
+            SubscriptionData subscription = createSubscription(prod, term, planSet);
+            PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             // NEXT PHASE
-            DateTime expectedPhaseTrialChange = Clock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             checkNextPhaseChange(subscription, 1, expectedPhaseTrialChange);
 
             // MOVE TO NEXT PHASE
@@ -105,10 +96,10 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
             assertEquals(trialPhase.getPhaseType(), PhaseType.EVERGREEN);
 
             // SET CTD + RE READ SUBSCRIPTION + CHANGE PLAN
-            IDuration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = Clock.addDuration(expectedPhaseTrialChange, ctd);
+            Duration ctd = getDurationMonth(1);
+            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate);
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
             testListener.pushExpectedEvent(NextEvent.CANCEL);
 
@@ -121,7 +112,7 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
             DateTime future = clock.getUTCNow();
             assertTrue(testListener.isCompleted(2000));
 
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNull(currentPhase);
             checkNextPhaseChange(subscription, 0, null);
 
@@ -139,15 +130,15 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
             String prod = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = IPriceListSet.DEFAULT_PRICELIST_NAME;
+            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
-            Subscription subscription = createSubscription(prod, term, planSet);
-            IPlanPhase trialPhase = subscription.getCurrentPhase();
+            SubscriptionData subscription = createSubscription(prod, term, planSet);
+            PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             // NEXT PHASE
-            DateTime expectedPhaseTrialChange = Clock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             checkNextPhaseChange(subscription, 1, expectedPhaseTrialChange);
 
             // MOVE TO NEXT PHASE
@@ -163,7 +154,7 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
             subscription.cancel(clock.getUTCNow(), false);
             assertTrue(testListener.isCompleted(2000));
 
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNull(currentPhase);
             checkNextPhaseChange(subscription, 0, null);
 
@@ -183,29 +174,29 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
             String prod = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = IPriceListSet.DEFAULT_PRICELIST_NAME;
+            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
-            Subscription subscription = createSubscription(prod, term, planSet);
-            IPlanPhase trialPhase = subscription.getCurrentPhase();
+            SubscriptionData subscription = createSubscription(prod, term, planSet);
+            PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             // NEXT PHASE
-            DateTime expectedPhaseTrialChange = Clock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             checkNextPhaseChange(subscription, 1, expectedPhaseTrialChange);
 
             // MOVE TO NEXT PHASE
             testListener.pushExpectedEvent(NextEvent.PHASE);
             clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
             assertTrue(testListener.isCompleted(2000));
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
 
             // SET CTD + RE READ SUBSCRIPTION + CHANGE PLAN
-            IDuration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = Clock.addDuration(expectedPhaseTrialChange, ctd);
+            Duration ctd = getDurationMonth(1);
+            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate);
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
             testListener.pushExpectedEvent(NextEvent.CANCEL);
 
@@ -220,7 +211,7 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
             DateTime future = clock.getUTCNow();
             assertFalse(testListener.isCompleted(2000));
 
-            IPlan currentPlan = subscription.getCurrentPlan();
+            Plan currentPlan = subscription.getCurrentPlan();
             assertEquals(currentPlan.getProduct().getName(), prod);
             currentPhase = subscription.getCurrentPhase();
             assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
index 00c2bab..962a6ef 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelMemory.java
@@ -16,20 +16,18 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import org.testng.annotations.Test;
-
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.CatalogModuleMock;
-import com.ning.billing.entitlement.glue.EngineModuleMemoryMock;
+import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
+import org.testng.annotations.Test;
 
 public class TestUserApiCancelMemory extends TestUserApiCancel {
 
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.PRODUCTION, new EngineModuleMemoryMock(), new CatalogModuleMock());
+        return Guice.createInjector(Stage.PRODUCTION, new MockEngineModuleMemory());
     }
 
     @Test(enabled=true, groups={"fast"})
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
index 58e8891..682fa06 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCancelSql.java
@@ -16,13 +16,11 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import org.testng.annotations.Test;
-
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.CatalogModuleMock;
-import com.ning.billing.entitlement.glue.EngineModuleSqlMock;
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+import org.testng.annotations.Test;
 
 public class TestUserApiCancelSql extends TestUserApiCancel {
 
@@ -31,7 +29,7 @@ public class TestUserApiCancelSql extends TestUserApiCancel {
 
     @Override
     public Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock(), new CatalogModuleMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
     @Test(enabled= true, groups={"stress"})
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
index 32f1dc9..76f6d44 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlan.java
@@ -16,43 +16,33 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
+import com.ning.billing.catalog.api.*;
+import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
+import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.entitlement.events.user.ApiEvent;
+import com.ning.billing.util.clock.DefaultClock;
+import org.joda.time.DateTime;
+import org.testng.Assert;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import org.joda.time.DateTime;
-import org.testng.Assert;
-
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IDuration;
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.catalog.api.IPlanPhase;
-import com.ning.billing.catalog.api.IPriceListSet;
-import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
-import com.ning.billing.entitlement.events.IEvent;
-import com.ning.billing.entitlement.events.user.IApiEvent;
-import com.ning.billing.util.clock.Clock;
+import static org.testng.Assert.*;
 
 public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
 
 
-    private void checkChangePlan(Subscription subscription, String expProduct, ProductCategory expCategory,
+    private void checkChangePlan(SubscriptionData subscription, String expProduct, ProductCategory expCategory,
             BillingPeriod expBillingPeriod, PhaseType expPhase) {
 
-        IPlan currentPlan = subscription.getCurrentPlan();
+        Plan currentPlan = subscription.getCurrentPlan();
         assertNotNull(currentPlan);
         assertEquals(currentPlan.getProduct().getName(),expProduct);
         assertEquals(currentPlan.getProduct().getCategory(), expCategory);
         assertEquals(currentPlan.getBillingPeriod(), expBillingPeriod);
 
-        IPlanPhase currentPhase = subscription.getCurrentPhase();
+        PlanPhase currentPhase = subscription.getCurrentPhase();
         assertNotNull(currentPhase);
         assertEquals(currentPhase.getPhaseType(), expPhase);
     }
@@ -60,7 +50,7 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
 
     protected void testChangePlanBundleAlignEOTWithNoChargeThroughDateReal() {
-        tChangePlanBundleAlignEOTWithNoChargeThroughDate("Shotgun", BillingPeriod.MONTHLY, IPriceListSet.DEFAULT_PRICELIST_NAME, "Pistol", BillingPeriod.MONTHLY, IPriceListSet.DEFAULT_PRICELIST_NAME);
+        tChangePlanBundleAlignEOTWithNoChargeThroughDate("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, "Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
     }
 
 
@@ -72,14 +62,14 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
         try {
 
             // CREATE
-            Subscription subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
+            SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
 
             // MOVE TO NEXT PHASE
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             testListener.pushExpectedEvent(NextEvent.PHASE);
             clock.setDeltaFromReality(currentPhase.getDuration(), DAY_IN_MS);
             DateTime futureNow = clock.getUTCNow();
-            DateTime nextExpectedPhaseChange = Clock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
+            DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
             assertTrue(futureNow.isAfter(nextExpectedPhaseChange));
             assertTrue(testListener.isCompleted(3000));
 
@@ -109,9 +99,9 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
         try {
 
             // CREATE
-            Subscription subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
-            IPlanPhase trialPhase = subscription.getCurrentPhase();
-            DateTime expectedPhaseTrialChange = Clock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
+            PlanPhase trialPhase = subscription.getCurrentPhase();
+            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
 
@@ -119,18 +109,18 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
             testListener.pushExpectedEvent(NextEvent.PHASE);
             clock.setDeltaFromReality(trialPhase.getDuration(), DAY_IN_MS);
             assertTrue(testListener.isCompleted(2000));
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
 
 
             // SET CTD
-            IDuration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = Clock.addDuration(expectedPhaseTrialChange, ctd);
+            Duration ctd = getDurationMonth(1);
+            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate);
 
             // RE READ SUBSCRIPTION + CHANGE PLAN
             testListener.pushExpectedEvent(NextEvent.CHANGE);
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
             subscription.changePlan(toProd, toTerm, toPlanSet, clock.getUTCNow());
             assertFalse(testListener.isCompleted(2000));
             testListener.reset();
@@ -140,12 +130,12 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
             checkChangePlan(subscription, fromProd, ProductCategory.BASE, fromTerm, PhaseType.DISCOUNT);
 
             // NEXT PHASE
-            DateTime nextExpectedPhaseChange = Clock.addDuration(expectedPhaseTrialChange, currentPhase.getDuration());
+            DateTime nextExpectedPhaseChange = DefaultClock.addDuration(expectedPhaseTrialChange, currentPhase.getDuration());
             checkNextPhaseChange(subscription, 2, nextExpectedPhaseChange);
 
             // ALSO VERIFY PENDING CHANGE EVENT
-            List<IEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
-            assertTrue(events.get(0) instanceof IApiEvent);
+            List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
+            assertTrue(events.get(0) instanceof ApiEvent);
 
 
             // MOVE TO EOT
@@ -153,7 +143,7 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
             clock.addDeltaFromReality(ctd);
             assertTrue(testListener.isCompleted(5000));
 
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
             currentPhase = subscription.getCurrentPhase();
             checkChangePlan(subscription, toProd, ProductCategory.BASE, toTerm, PhaseType.DISCOUNT);
 
@@ -164,7 +154,7 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
 
     protected void testChangePlanBundleAlignIMMReal() {
-        tChangePlanBundleAlignIMM("Shotgun", BillingPeriod.MONTHLY, IPriceListSet.DEFAULT_PRICELIST_NAME, "Assault-Rifle", BillingPeriod.MONTHLY, IPriceListSet.DEFAULT_PRICELIST_NAME);
+        tChangePlanBundleAlignIMM("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, "Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
     }
 
 
@@ -175,11 +165,11 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
         try {
 
-            Subscription subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
+            SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
 
             testListener.pushExpectedEvent(NextEvent.CHANGE);
 
-            IDuration moveALittleInTime = getDurationDay(3);
+            Duration moveALittleInTime = getDurationDay(3);
             clock.setDeltaFromReality(moveALittleInTime, 0);
 
             // CHANGE PLAN IMM
@@ -188,8 +178,8 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
             assertTrue(testListener.isCompleted(2000));
 
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
-            DateTime nextExpectedPhaseChange = Clock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
+            PlanPhase currentPhase = subscription.getCurrentPhase();
+            DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
             checkNextPhaseChange(subscription, 1, nextExpectedPhaseChange);
 
             // NEXT PHASE
@@ -206,7 +196,7 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
 
     protected void testChangePlanChangePlanAlignEOTWithChargeThroughDateReal() {
-        tChangePlanChangePlanAlignEOTWithChargeThroughDate("Shotgun", BillingPeriod.ANNUAL, IPriceListSet.DEFAULT_PRICELIST_NAME, "Assault-Rifle", BillingPeriod.ANNUAL, "rescue");
+        tChangePlanChangePlanAlignEOTWithChargeThroughDate("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, "Assault-Rifle", BillingPeriod.ANNUAL, "rescue");
     }
 
     private void tChangePlanChangePlanAlignEOTWithChargeThroughDate(String fromProd, BillingPeriod fromTerm, String fromPlanSet,
@@ -218,9 +208,9 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
             DateTime currentTime = clock.getUTCNow();
 
-            Subscription subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
-            IPlanPhase trialPhase = subscription.getCurrentPhase();
-            DateTime expectedPhaseTrialChange = Clock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            SubscriptionData subscription = createSubscription(fromProd, fromTerm, fromPlanSet);
+            PlanPhase trialPhase = subscription.getCurrentPhase();
+            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             // MOVE TO NEXT PHASE
@@ -231,13 +221,13 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
             assertTrue(testListener.isCompleted(2000));
 
             // SET CTD
-            IDuration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = Clock.addDuration(expectedPhaseTrialChange, ctd);
+            Duration ctd = getDurationMonth(1);
+            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate);
 
             // RE READ SUBSCRIPTION + CHECK CURRENT PHASE
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
 
@@ -273,7 +263,7 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
             currentTime = clock.getUTCNow();
             assertFalse(testListener.isCompleted(2000));
 
-            DateTime nextExpectedPhaseChange = Clock.addDuration(newChargedThroughDate, currentPhase.getDuration());
+            DateTime nextExpectedPhaseChange = DefaultClock.addDuration(newChargedThroughDate, currentPhase.getDuration());
             checkNextPhaseChange(subscription, 1, nextExpectedPhaseChange);
 
             // MOVE TIME RIGHT AFTER NEXT EXPECTED PHASE CHANGE
@@ -289,8 +279,8 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
     protected void testMultipleChangeLastIMMReal() {
 
         try {
-            Subscription subscription = createSubscription("Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
-            IPlanPhase trialPhase = subscription.getCurrentPhase();
+            SubscriptionData subscription = createSubscription("Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
+            PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             // MOVE TO NEXT PHASE
@@ -299,14 +289,14 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
             assertTrue(testListener.isCompleted(2000));
 
             // SET CTD
-            List<IDuration> durationList = new ArrayList<IDuration>();
+            List<Duration> durationList = new ArrayList<Duration>();
             durationList.add(trialPhase.getDuration());
             //durationList.add(subscription.getCurrentPhase().getDuration());
-            DateTime startDiscountPhase = Clock.addDuration(subscription.getStartDate(), durationList);
-            IDuration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = Clock.addDuration(startDiscountPhase, ctd);
+            DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
+            Duration ctd = getDurationMonth(1);
+            DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate);
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
             // CHANGE EOT
             testListener.pushExpectedEvent(NextEvent.CHANGE);
@@ -318,13 +308,13 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
             subscription.changePlan("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow());
             assertFalse(testListener.isCompleted(2000));
 
-            IPlan currentPlan = subscription.getCurrentPlan();
+            Plan currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
             assertEquals(currentPlan.getProduct().getName(), "Assault-Rifle");
             assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
             assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.ANNUAL);
 
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
 
@@ -337,8 +327,8 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
         try {
 
-            Subscription subscription = createSubscription("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount");
-            IPlanPhase trialPhase = subscription.getCurrentPhase();
+            SubscriptionData subscription = createSubscription("Assault-Rifle", BillingPeriod.ANNUAL, "gunclubDiscount");
+            PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             testListener.pushExpectedEvent(NextEvent.PHASE);
@@ -346,13 +336,13 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
             assertTrue(testListener.isCompleted(2000));
 
             // SET CTD
-            List<IDuration> durationList = new ArrayList<IDuration>();
+            List<Duration> durationList = new ArrayList<Duration>();
             durationList.add(trialPhase.getDuration());
-            DateTime startDiscountPhase = Clock.addDuration(subscription.getStartDate(), durationList);
-            IDuration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = Clock.addDuration(startDiscountPhase, ctd);
+            DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
+            Duration ctd = getDurationMonth(1);
+            DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate);
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
             // CHANGE EOT
             testListener.pushExpectedEvent(NextEvent.CHANGE);
@@ -367,13 +357,13 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
             testListener.reset();
 
             // CHECK NO CHANGE OCCURED YET
-            IPlan currentPlan = subscription.getCurrentPlan();
+            Plan currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
             assertEquals(currentPlan.getProduct().getName(), "Assault-Rifle");
             assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
             assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.ANNUAL);
 
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
 
@@ -398,7 +388,7 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
             testListener.pushExpectedEvent(NextEvent.PHASE);
             clock.addDeltaFromReality(currentPhase.getDuration());
             assertTrue(testListener.isCompleted(3000));
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
             currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
index 8847612..173239c 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanMemory.java
@@ -16,19 +16,17 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import org.testng.annotations.Test;
-
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.CatalogModuleMock;
-import com.ning.billing.entitlement.glue.EngineModuleMemoryMock;
+import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
+import org.testng.annotations.Test;
 
 public class TestUserApiChangePlanMemory extends TestUserApiChangePlan {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.PRODUCTION, new EngineModuleMemoryMock(), new CatalogModuleMock());
+        return Guice.createInjector(Stage.PRODUCTION, new MockEngineModuleMemory());
     }
 
 
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
index 60d777d..255e894 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiChangePlanSql.java
@@ -16,13 +16,11 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import org.testng.annotations.Test;
-
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.CatalogModuleMock;
-import com.ning.billing.entitlement.glue.EngineModuleSqlMock;
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+import org.testng.annotations.Test;
 
 public class TestUserApiChangePlanSql extends TestUserApiChangePlan {
 
@@ -30,7 +28,7 @@ public class TestUserApiChangePlanSql extends TestUserApiChangePlan {
 
     @Override
     public Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock(), new CatalogModuleMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
     @Test(enabled= true, groups={"stress"})
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
index 0b476f9..365374e 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreate.java
@@ -18,9 +18,9 @@ package com.ning.billing.entitlement.api.user;
 
 import com.ning.billing.catalog.api.*;
 import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
-import com.ning.billing.entitlement.events.IEvent;
-import com.ning.billing.entitlement.events.phase.IPhaseEvent;
-import com.ning.billing.util.clock.Clock;
+import com.ning.billing.entitlement.events.EntitlementEvent;
+import com.ning.billing.entitlement.events.phase.PhaseEvent;
+import com.ning.billing.util.clock.DefaultClock;
 import org.joda.time.DateTime;
 import org.testng.Assert;
 
@@ -41,14 +41,14 @@ public abstract class TestUserApiCreate extends TestUserApiBase {
 
             String productName = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSetName = IPriceListSet.DEFAULT_PRICELIST_NAME;
+            String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
 
             testListener.pushExpectedEvent(NextEvent.PHASE);
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
 
-            Subscription subscription = (Subscription) entitlementApi.createSubscription(bundle.getId(), productName, term, planSetName, requestedDate);
+            SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(), productName, term, planSetName, null, requestedDate);
             assertNotNull(subscription);
 
             assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -63,6 +63,45 @@ public abstract class TestUserApiCreate extends TestUserApiBase {
         }
     }
 
+    protected void testCreateWithInitialPhaseReal() {
+        log.info("Starting testCreateWithInitialPhase");
+        try {
+
+
+            DateTime init = clock.getUTCNow();
+
+            String productName = "Shotgun";
+            BillingPeriod term = BillingPeriod.MONTHLY;
+            String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
+
+            testListener.pushExpectedEvent(NextEvent.CREATE);
+
+            SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(), productName, term, planSetName, PhaseType.EVERGREEN, clock.getUTCNow());
+            assertNotNull(subscription);
+
+            assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
+            //assertEquals(subscription.getAccount(), account.getId());
+            assertEquals(subscription.getBundleId(), bundle.getId());
+            assertDateWithin(subscription.getStartDate(), init, clock.getUTCNow());
+            assertDateWithin(subscription.getBundleStartDate(), init, clock.getUTCNow());
+
+            printSubscriptionTransitions(subscription.getActiveTransitions());
+
+            Plan currentPlan = subscription.getCurrentPlan();
+            assertNotNull(currentPlan);
+            assertEquals(currentPlan.getProduct().getName(), productName);
+            assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
+            assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
+
+            PlanPhase currentPhase = subscription.getCurrentPhase();
+            assertNotNull(currentPhase);
+            assertEquals(currentPhase.getPhaseType(), PhaseType.EVERGREEN);
+
+        } catch (EntitlementUserApiException e) {
+            Assert.fail(e.getMessage());
+        }
+    }
+
     protected void testSimpleCreateSubscriptionReal() {
 
         log.info("Starting testSimpleCreateSubscription");
@@ -72,11 +111,11 @@ public abstract class TestUserApiCreate extends TestUserApiBase {
 
             String productName = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSetName = IPriceListSet.DEFAULT_PRICELIST_NAME;
+            String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
-            Subscription subscription = (Subscription) entitlementApi.createSubscription(bundle.getId(), productName, term, planSetName, clock.getUTCNow());
+            SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(), productName, term, planSetName, null, clock.getUTCNow());
             assertNotNull(subscription);
 
             assertEquals(subscription.getActiveVersion(), SubscriptionEvents.INITIAL_VERSION);
@@ -87,29 +126,29 @@ public abstract class TestUserApiCreate extends TestUserApiBase {
 
             printSubscriptionTransitions(subscription.getActiveTransitions());
 
-            IPlan currentPlan = subscription.getCurrentPlan();
+            Plan currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
             assertEquals(currentPlan.getProduct().getName(), productName);
             assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
             assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.MONTHLY);
 
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
 
-            List<ISubscriptionTransition> transitions = subscription.getActiveTransitions();
+            List<SubscriptionTransition> transitions = subscription.getActiveTransitions();
             assertNotNull(transitions);
             assertEquals(transitions.size(), 1);
 
             assertTrue(testListener.isCompleted(5000));
 
-            List<IEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
+            List<EntitlementEvent> events = dao.getPendingEventsForSubscription(subscription.getId());
             assertNotNull(events);
             printEvents(events);
             assertTrue(events.size() == 1);
-            assertTrue(events.get(0) instanceof IPhaseEvent);
-            DateTime nextPhaseChange = ((IPhaseEvent ) events.get(0)).getEffectiveDate();
-            DateTime nextExpectedPhaseChange = Clock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
+            assertTrue(events.get(0) instanceof PhaseEvent);
+            DateTime nextPhaseChange = ((PhaseEvent ) events.get(0)).getEffectiveDate();
+            DateTime nextExpectedPhaseChange = DefaultClock.addDuration(subscription.getStartDate(), currentPhase.getDuration());
             assertEquals(nextPhaseChange, nextExpectedPhaseChange);
 
             testListener.pushExpectedEvent(NextEvent.PHASE);
@@ -141,10 +180,10 @@ public abstract class TestUserApiCreate extends TestUserApiBase {
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
             // CREATE SUBSCRIPTION
-            Subscription subscription = (Subscription) entitlementApi.createSubscription(bundle.getId(), productName, term, planSetName, clock.getUTCNow());
+            SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(), productName, term, planSetName, null, clock.getUTCNow());
             assertNotNull(subscription);
 
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.TRIAL);
             assertTrue(testListener.isCompleted(5000));
@@ -165,7 +204,7 @@ public abstract class TestUserApiCreate extends TestUserApiBase {
             clock.addDeltaFromReality(currentPhase.getDuration());
             assertTrue(testListener.isCompleted(2000));
 
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
             curTime = clock.getUTCNow();
             currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
@@ -184,11 +223,11 @@ public abstract class TestUserApiCreate extends TestUserApiBase {
 
             String productName = "Shotgun";
             BillingPeriod term = BillingPeriod.ANNUAL;
-            String planSetName = IPriceListSet.DEFAULT_PRICELIST_NAME;
+            String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
-            Subscription subscription = (Subscription) entitlementApi.createSubscription(bundle.getId(), productName, term, planSetName, clock.getUTCNow());
+            SubscriptionData subscription = (SubscriptionData) entitlementApi.createSubscription(bundle.getId(), productName, term, planSetName, null, clock.getUTCNow());
             assertNotNull(subscription);
 
         } catch (EntitlementUserApiException e) {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
index 0746f43..bff20db 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateMemory.java
@@ -19,8 +19,7 @@ package com.ning.billing.entitlement.api.user;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.CatalogModuleMock;
-import com.ning.billing.entitlement.glue.EngineModuleMemoryMock;
+import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
 import org.testng.annotations.Test;
 
 public class TestUserApiCreateMemory extends TestUserApiCreate {
@@ -28,7 +27,7 @@ public class TestUserApiCreateMemory extends TestUserApiCreate {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.PRODUCTION, new EngineModuleMemoryMock(), new CatalogModuleMock());
+        return Guice.createInjector(Stage.PRODUCTION, new MockEngineModuleMemory());
     }
 
     @Test(enabled=true, groups={"fast"})
@@ -37,6 +36,11 @@ public class TestUserApiCreateMemory extends TestUserApiCreate {
     }
 
     @Test(enabled=true, groups={"fast"})
+    public void testCreateWithInitialPhase() {
+        invokeRealMethod(this);
+    }
+
+    @Test(enabled=true, groups={"fast"})
     public void testSimpleCreateSubscription() {
         invokeRealMethod(this);
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
index 617582a..25996e2 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiCreateSql.java
@@ -19,15 +19,14 @@ package com.ning.billing.entitlement.api.user;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
-import com.ning.billing.entitlement.glue.CatalogModuleMock;
-import com.ning.billing.entitlement.glue.EngineModuleSqlMock;
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
 import org.testng.annotations.Test;
 
 public class TestUserApiCreateSql extends TestUserApiCreate {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock(), new CatalogModuleMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
     @Test(enabled=true, groups={"sql"})
@@ -36,6 +35,11 @@ public class TestUserApiCreateSql extends TestUserApiCreate {
     }
 
     @Test(enabled=true, groups={"sql"})
+    public void testCreateWithInitialPhase() {
+        invokeRealMethod(this);
+    }
+
+    @Test(enabled=true, groups={"sql"})
     public void testSimpleCreateSubscription() {
         invokeRealMethod(this);
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
index 90e7cde..91ac96f 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiDemos.java
@@ -16,38 +16,28 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+import com.ning.billing.catalog.api.*;
+import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+import com.ning.billing.util.clock.DefaultClock;
+import org.joda.time.DateTime;
+import org.testng.Assert;
+import org.testng.annotations.Test;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-import org.joda.time.DateTime;
-import org.slf4j.Logger;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Stage;
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IDuration;
-import com.ning.billing.catalog.api.IPlan;
-import com.ning.billing.catalog.api.IPlanPhase;
-import com.ning.billing.catalog.api.PhaseType;
-import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
-import com.ning.billing.entitlement.glue.EngineModuleSqlMock;
-import com.ning.billing.util.clock.Clock;
+import static org.testng.Assert.*;
 
 public class TestUserApiDemos extends TestUserApiBase {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
     /**
@@ -72,8 +62,8 @@ public class TestUserApiDemos extends TestUserApiBase {
             System.out.println("DEMO 1 START");
 
             /* STEP 1. CREATE SUBSCRIPTION */
-            Subscription subscription = createSubscription("Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
-            IPlanPhase trialPhase = subscription.getCurrentPhase();
+            SubscriptionData subscription = createSubscription("Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
+            PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             displayState(subscription.getId(), "STEP 1. CREATED SUBSCRIPTION");
@@ -93,14 +83,14 @@ public class TestUserApiDemos extends TestUserApiBase {
             displayState(subscription.getId(), "STEP 3. MOVE TO DISCOUNT PHASE");
 
             /* STEP 4. SET CTD AND CHANGE PLAN EOT */
-            List<IDuration> durationList = new ArrayList<IDuration>();
+            List<Duration> durationList = new ArrayList<Duration>();
             durationList.add(trialPhase.getDuration());
-            DateTime startDiscountPhase = Clock.addDuration(subscription.getStartDate(), durationList);
+            DateTime startDiscountPhase = DefaultClock.addDuration(subscription.getStartDate(), durationList);
 
-            IDuration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = Clock.addDuration(startDiscountPhase, ctd);
+            Duration ctd = getDurationMonth(1);
+            DateTime newChargedThroughDate = DefaultClock.addDuration(startDiscountPhase, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate);
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
             testListener.pushExpectedEvent(NextEvent.CHANGE);
             subscription.changePlan("Shotgun", BillingPeriod.ANNUAL, "gunclubDiscount", clock.getUTCNow());
@@ -122,13 +112,13 @@ public class TestUserApiDemos extends TestUserApiBase {
             clock.addDeltaFromReality(ctd);
             assertTrue(testListener.isCompleted(2000));
 
-            IPlan currentPlan = subscription.getCurrentPlan();
+            Plan currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
             assertEquals(currentPlan.getProduct().getName(), "Pistol");
             assertEquals(currentPlan.getProduct().getCategory(), ProductCategory.BASE);
             assertEquals(currentPlan.getBillingPeriod(), BillingPeriod.ANNUAL);
 
-            IPlanPhase currentPhase = subscription.getCurrentPhase();
+            PlanPhase currentPhase = subscription.getCurrentPhase();
             assertNotNull(currentPhase);
             assertEquals(currentPhase.getPhaseType(), PhaseType.DISCOUNT);
 
@@ -138,7 +128,7 @@ public class TestUserApiDemos extends TestUserApiBase {
             testListener.pushExpectedEvent(NextEvent.PHASE);
             clock.addDeltaFromReality(currentPhase.getDuration());
             assertTrue(testListener.isCompleted(3000));
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
             currentPlan = subscription.getCurrentPlan();
             assertNotNull(currentPlan);
@@ -170,11 +160,11 @@ public class TestUserApiDemos extends TestUserApiBase {
         System.out.println("");
         System.out.println("******\t STEP " + stepMsg + " **************");
 
-        Subscription subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscriptionId);
+        SubscriptionData subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscriptionId);
 
 
-        IPlan currentPlan = subscription.getCurrentPlan();
-        IPlanPhase currentPhase = subscription.getCurrentPhase();
+        Plan currentPlan = subscription.getCurrentPlan();
+        PlanPhase currentPhase = subscription.getCurrentPhase();
         String priceList = subscription.getCurrentPriceList();
         System.out.println("");
         System.out.println("\t CURRENT TIME = " + clock.getUTCNow());
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
index 3d8b84f..d683244 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiError.java
@@ -16,62 +16,55 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-
-import java.util.UUID;
-
-import org.joda.time.DateTime;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
 import com.ning.billing.ErrorCode;
-import com.ning.billing.catalog.PriceListSet;
 import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IDuration;
-import com.ning.billing.catalog.api.IPlanPhase;
-import com.ning.billing.catalog.api.IPriceListSet;
+import com.ning.billing.catalog.api.Duration;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
-import com.ning.billing.entitlement.glue.EngineModuleMemoryMock;
-import com.ning.billing.util.clock.Clock;
+import com.ning.billing.entitlement.glue.MockEngineModuleMemory;
+import com.ning.billing.util.clock.DefaultClock;
+import org.joda.time.DateTime;
+import org.testng.Assert;
+import org.testng.annotations.Test;
 
-public class TestUserApiError extends TestUserApiBase {
+import java.util.UUID;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+
+public class TestUserApiError extends TestUserApiBase {
 
-    /*
-     *    ENT_CREATE_BAD_CATALOG(1011, "Plan for product %s, term %s and set %s does not exist in the catalog"),
-    ENT_CREATE_NO_BUNDLE(1012, "Bundle %s does not exists"),
-    ENT_CREATE_NO_BP(1013, "Missing Base Subscription for bundle %s"),
-    ENT_CREATE_BP_EXISTS(1015, "Subscription bundle %s already has a base subscription"),
-    ENT_CHANGE_BAD_STATE(1021, "Subscription %s is in state %s"),
-    ENT_CANCEL_BAD_STATE(1031, "Subscription %s is in state %s"),
-    ENT_UNCANCEL_BAD_STATE(1070, "Subscription %s was not in a cancelled state")
-     */
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleMemory());
     }
 
+
     @Test(enabled=true)
     public void testCreateSubscriptionBadCatalog() {
         // WRONG PRODUTCS
-        tCreateSubscriptionInternal(bundle.getId(), null, BillingPeriod.ANNUAL, IPriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_BAD_CATALOG);
-        tCreateSubscriptionInternal(bundle.getId(), "Whatever", BillingPeriod.ANNUAL, IPriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_BAD_CATALOG);
+        tCreateSubscriptionInternal(bundle.getId(), null, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.CAT_NO_SUCH_PRODUCT);
+        tCreateSubscriptionInternal(bundle.getId(), "Whatever", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.CAT_NO_SUCH_PRODUCT);
+
+
+        // TODO: MARTIN TO FIX WITH CORRECT ERROR CODE. RIGHT NOW NPE
+
         // WRONG BILLING PERIOD
-        tCreateSubscriptionInternal(bundle.getId(), "Shotgun", null, IPriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_BAD_CATALOG);
+        //tCreateSubscriptionInternal(bundle.getId(), "Shotgun", null, IPriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.);
         // WRONG PLAN SET
-        tCreateSubscriptionInternal(bundle.getId(), "Shotgun", BillingPeriod.ANNUAL, null, ErrorCode.ENT_CREATE_BAD_CATALOG);
-        tCreateSubscriptionInternal(bundle.getId(), "Shotgun", BillingPeriod.ANNUAL, "Whatever", ErrorCode.ENT_CREATE_BAD_CATALOG);
+        //tCreateSubscriptionInternal(bundle.getId(), "Shotgun", BillingPeriod.ANNUAL, null, ErrorCode.);
+        //tCreateSubscriptionInternal(bundle.getId(), "Shotgun", BillingPeriod.ANNUAL, "Whatever", ErrorCode.);
 
     }
 
     @Test(enabled=true)
     public void testCreateSubscriptionNoBundle() {
-        tCreateSubscriptionInternal(null, "Shotgun", BillingPeriod.ANNUAL, IPriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_NO_BUNDLE);
+        tCreateSubscriptionInternal(null, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_NO_BUNDLE);
     }
 
     @Test(enabled=false)
@@ -82,8 +75,8 @@ public class TestUserApiError extends TestUserApiBase {
     @Test(enabled=true)
     public void testCreateSubscriptionBPExists() {
         try {
-            createSubscription("Shotgun", BillingPeriod.ANNUAL, IPriceListSet.DEFAULT_PRICELIST_NAME);
-            tCreateSubscriptionInternal(bundle.getId(), "Shotgun", BillingPeriod.ANNUAL, IPriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_BP_EXISTS);
+            createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
+            tCreateSubscriptionInternal(bundle.getId(), "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_BP_EXISTS);
         } catch (Exception e) {
             e.printStackTrace();
             Assert.assertFalse(true);
@@ -93,7 +86,7 @@ public class TestUserApiError extends TestUserApiBase {
     private void tCreateSubscriptionInternal(UUID bundleId, String productName,
             BillingPeriod term, String planSet, ErrorCode expected)  {
         try {
-            entitlementApi.createSubscription(bundleId, productName, term, planSet,clock.getUTCNow());
+            entitlementApi.createSubscription(bundleId, productName, term, planSet, null, clock.getUTCNow());
             assertFalse(true);
         } catch (EntitlementUserApiException e) {
             assertEquals(e.getCode(), expected.getCode());
@@ -109,12 +102,12 @@ public class TestUserApiError extends TestUserApiBase {
     @Test(enabled=true)
     public void testChangeSubscriptionNonActive() {
         try {
-            ISubscription subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, IPriceListSet.DEFAULT_PRICELIST_NAME);
+            Subscription subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
 
             testListener.pushExpectedEvent(NextEvent.CANCEL);
             subscription.cancel(clock.getUTCNow(), false);
             try {
-                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, IPriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow());
+                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow());
             } catch (EntitlementUserApiException e) {
                 assertEquals(e.getCode(), ErrorCode.ENT_CHANGE_NON_ACTIVE.getCode());
                 try {
@@ -133,19 +126,19 @@ public class TestUserApiError extends TestUserApiBase {
     @Test(enabled=true)
     public void testChangeSubscriptionFutureCancelled() {
         try {
-            ISubscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, IPriceListSet.DEFAULT_PRICELIST_NAME);
+            Subscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
             // SET CTD TO CANCEL IN FUTURE
-            IPlanPhase trialPhase = subscription.getCurrentPhase();
-            DateTime expectedPhaseTrialChange = Clock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
-            IDuration ctd = getDurationMonth(1);
-            DateTime newChargedThroughDate = Clock.addDuration(expectedPhaseTrialChange, ctd);
+            PlanPhase trialPhase = subscription.getCurrentPhase();
+            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            Duration ctd = getDurationMonth(1);
+            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate);
             subscription = entitlementApi.getSubscriptionFromId(subscription.getId());
 
             subscription.cancel(clock.getUTCNow(), false);
             try {
-                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, IPriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow());
+                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, clock.getUTCNow());
             } catch (EntitlementUserApiException e) {
                 assertEquals(e.getCode(), ErrorCode.ENT_CHANGE_FUTURE_CANCELLED.getCode());
                 try {
@@ -168,7 +161,7 @@ public class TestUserApiError extends TestUserApiBase {
     @Test(enabled=true)
     public void testUncancelBadState() {
         try {
-            ISubscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, IPriceListSet.DEFAULT_PRICELIST_NAME);
+            Subscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
             try {
                 subscription.uncancel();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
index 78e7cb3..7b600dd 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserApiScenarios.java
@@ -16,30 +16,27 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.assertFalse;
-
-import org.joda.time.DateTime;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
 import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.IDuration;
-import com.ning.billing.catalog.api.IPlanPhase;
+import com.ning.billing.catalog.api.Duration;
 import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.entitlement.api.ApiTestListener.NextEvent;
-import com.ning.billing.entitlement.glue.EngineModuleSqlMock;
-import com.ning.billing.util.clock.Clock;
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+import com.ning.billing.util.clock.DefaultClock;
+import org.joda.time.DateTime;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
 
 public class TestUserApiScenarios extends TestUserApiBase {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
     }
 
     @Test(enabled=true)
@@ -48,8 +45,8 @@ public class TestUserApiScenarios extends TestUserApiBase {
         log.info("Starting testChangeIMMCancelUncancelChangeEOT");
 
         try {
-            Subscription subscription = createSubscription("Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
-            IPlanPhase trialPhase = subscription.getCurrentPhase();
+            SubscriptionData subscription = createSubscription("Assault-Rifle", BillingPeriod.MONTHLY, "gunclubDiscount");
+            PlanPhase trialPhase = subscription.getCurrentPhase();
             assertEquals(trialPhase.getPhaseType(), PhaseType.TRIAL);
 
             testListener.pushExpectedEvent(NextEvent.CHANGE);
@@ -62,11 +59,11 @@ public class TestUserApiScenarios extends TestUserApiBase {
             assertTrue(testListener.isCompleted(2000));
 
             // SET CTD
-            IDuration ctd = getDurationMonth(1);
-            DateTime expectedPhaseTrialChange = Clock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
-            DateTime newChargedThroughDate = Clock.addDuration(expectedPhaseTrialChange, ctd);
+            Duration ctd = getDurationMonth(1);
+            DateTime expectedPhaseTrialChange = DefaultClock.addDuration(subscription.getStartDate(), trialPhase.getDuration());
+            DateTime newChargedThroughDate = DefaultClock.addDuration(expectedPhaseTrialChange, ctd);
             billingApi.setChargedThroughDate(subscription.getId(), newChargedThroughDate);
-            subscription = (Subscription) entitlementApi.getSubscriptionFromId(subscription.getId());
+            subscription = (SubscriptionData) entitlementApi.getSubscriptionFromId(subscription.getId());
 
             // CANCEL EOT
             testListener.pushExpectedEvent(NextEvent.CANCEL);

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

diff --git a/invoice/pom.xml b/invoice/pom.xml
index 3ef470f..5c28449 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.0.16-SNAPSHOT</version>
+        <version>0.0.17-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-invoice</artifactId>
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
index efbb495..f238b86 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
@@ -17,9 +17,9 @@
 package com.ning.billing.invoice.dao;
 
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.invoice.api.IInvoiceItem;
 import com.ning.billing.invoice.api.Invoice;
-import com.ning.billing.invoice.model.InvoiceDefault;
+import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.invoice.model.DefaultInvoice;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
@@ -104,7 +104,7 @@ public interface InvoiceDao {
             DateTime lastPaymentAttempt = lastPaymentAttemptTimeStamp == null ? null : new DateTime(lastPaymentAttemptTimeStamp);
             Currency currency = Currency.valueOf(result.getString("currency"));
 
-            return new InvoiceDefault(id, accountId, invoiceDate, targetDate, currency, lastPaymentAttempt, amountPaid, new ArrayList<IInvoiceItem>());
+            return new DefaultInvoice(id, accountId, invoiceDate, targetDate, currency, lastPaymentAttempt, amountPaid, new ArrayList<InvoiceItem>());
         }
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemDao.java
index 61e0865..1bb41b3 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemDao.java
@@ -17,8 +17,8 @@
 package com.ning.billing.invoice.dao;
 
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.invoice.api.IInvoiceItem;
-import com.ning.billing.invoice.model.InvoiceItem;
+import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.invoice.model.DefaultInvoiceItem;
 import org.joda.time.DateTime;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
@@ -38,19 +38,19 @@ import java.util.UUID;
 @RegisterMapper(InvoiceItemDao.InvoiceItemMapper.class)
 public interface InvoiceItemDao {
     @SqlQuery
-    IInvoiceItem getInvoiceItem(@Bind("id") final String invoiceItemId);
+    InvoiceItem getInvoiceItem(@Bind("id") final String invoiceItemId);
 
     @SqlQuery
-    List<IInvoiceItem> getInvoiceItemsByInvoice(@Bind("invoiceId") final String invoiceId);
+    List<InvoiceItem> getInvoiceItemsByInvoice(@Bind("invoiceId") final String invoiceId);
 
     @SqlQuery
-    List<IInvoiceItem> getInvoiceItemsByAccount(@Bind("accountId") final String accountId);
+    List<InvoiceItem> getInvoiceItemsByAccount(@Bind("accountId") final String accountId);
 
     @SqlQuery
-    List<IInvoiceItem> getInvoiceItemsBySubscription(@Bind("subscriptionId") final String subscriptionId);
+    List<InvoiceItem> getInvoiceItemsBySubscription(@Bind("subscriptionId") final String subscriptionId);
 
     @SqlUpdate
-    void createInvoiceItem(@InvoiceItemBinder final IInvoiceItem invoiceItem);
+    void createInvoiceItem(@InvoiceItemBinder final InvoiceItem invoiceItem);
 
     @SqlUpdate
     void test();
@@ -61,8 +61,8 @@ public interface InvoiceItemDao {
     public @interface InvoiceItemBinder {
         public static class InvoiceItemBinderFactory implements BinderFactory {
             public Binder build(Annotation annotation) {
-                return new Binder<InvoiceItemBinder, IInvoiceItem>() {
-                    public void bind(SQLStatement q, InvoiceItemBinder bind, IInvoiceItem item) {
+                return new Binder<InvoiceItemBinder, InvoiceItem>() {
+                    public void bind(SQLStatement q, InvoiceItemBinder bind, InvoiceItem item) {
                         q.bind("id", item.getId().toString());
                         q.bind("invoiceId", item.getInvoiceId().toString());
                         q.bind("subscriptionId", item.getSubscriptionId().toString());
@@ -78,9 +78,9 @@ public interface InvoiceItemDao {
         }
     }
 
-    public static class InvoiceItemMapper implements ResultSetMapper<IInvoiceItem> {
+    public static class InvoiceItemMapper implements ResultSetMapper<InvoiceItem> {
         @Override
-        public IInvoiceItem map(int index, ResultSet result, StatementContext context) throws SQLException {
+        public InvoiceItem map(int index, ResultSet result, StatementContext context) throws SQLException {
             UUID id = UUID.fromString(result.getString("id"));
             UUID invoiceId = UUID.fromString(result.getString("invoice_id"));
             UUID subscriptionId = UUID.fromString(result.getString("subscription_id"));
@@ -91,7 +91,7 @@ public interface InvoiceItemDao {
             BigDecimal rate = result.getBigDecimal("rate");
             Currency currency = Currency.valueOf(result.getString("currency"));
 
-            return new InvoiceItem(id, invoiceId, subscriptionId, startDate, endDate, description, amount, rate , currency);
+            return new DefaultInvoiceItem(id, invoiceId, subscriptionId, startDate, endDate, description, amount, rate , currency);
         }
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemDaoWrapper.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemDaoWrapper.java
index 57756fa..276785e 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemDaoWrapper.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceItemDaoWrapper.java
@@ -17,7 +17,7 @@
 package com.ning.billing.invoice.dao;
 
 import com.google.inject.Inject;
-import com.ning.billing.invoice.api.IInvoiceItem;
+import com.ning.billing.invoice.api.InvoiceItem;
 import org.skife.jdbi.v2.IDBI;
 
 import java.util.List;
@@ -31,27 +31,27 @@ public class InvoiceItemDaoWrapper implements InvoiceItemDao {
     }
 
     @Override
-    public IInvoiceItem getInvoiceItem(String invoiceItemId) {
+    public InvoiceItem getInvoiceItem(String invoiceItemId) {
         return dao.getInvoiceItem(invoiceItemId);
     }
 
     @Override
-    public List<IInvoiceItem> getInvoiceItemsByInvoice(String invoiceId) {
+    public List<InvoiceItem> getInvoiceItemsByInvoice(String invoiceId) {
         return dao.getInvoiceItemsByInvoice(invoiceId);
     }
 
     @Override
-    public List<IInvoiceItem> getInvoiceItemsByAccount(String accountId) {
+    public List<InvoiceItem> getInvoiceItemsByAccount(String accountId) {
         return dao.getInvoiceItemsByAccount(accountId);
     }
 
     @Override
-    public List<IInvoiceItem> getInvoiceItemsBySubscription(String subscriptionId) {
+    public List<InvoiceItem> getInvoiceItemsBySubscription(String subscriptionId) {
         return dao.getInvoiceItemsBySubscription(subscriptionId);
     }
 
     @Override
-    public void createInvoiceItem(IInvoiceItem invoiceItem) {
+    public void createInvoiceItem(InvoiceItem invoiceItem) {
         dao.createInvoiceItem(invoiceItem);
     }
 
diff --git a/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java b/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java
index ee82e5c..9318510 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/glue/InvoiceModule.java
@@ -17,7 +17,7 @@
 package com.ning.billing.invoice.glue;
 
 import com.google.inject.AbstractModule;
-import com.ning.billing.invoice.api.IInvoiceUserApi;
+import com.ning.billing.invoice.api.DefaultInvoiceUserApi;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.invoice.dao.InvoiceDao;
 import com.ning.billing.invoice.dao.InvoiceDaoWrapper;
@@ -34,7 +34,7 @@ public class InvoiceModule extends AbstractModule {
     }
 
     protected void installInvoiceUserApi() {
-        bind(IInvoiceUserApi.class).to(InvoiceUserApi.class).asEagerSingleton();
+        bind(InvoiceUserApi.class).to(DefaultInvoiceUserApi.class).asEagerSingleton();
     }
 
     @Override
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
index 360f85d..54ca894 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
@@ -18,10 +18,11 @@ package com.ning.billing.invoice.model;
 
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.entitlement.api.billing.IBillingEvent;
+import com.ning.billing.entitlement.api.billing.BillingEvent;
+import com.ning.billing.entitlement.api.billing.BillingModeType;
 import com.ning.billing.invoice.api.BillingEventSet;
-import com.ning.billing.invoice.api.IInvoiceItem;
 import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceItem;
 import org.joda.time.DateTime;
 
 import java.math.BigDecimal;
@@ -33,10 +34,10 @@ import java.util.UUID;
 public class DefaultInvoiceGenerator implements InvoiceGenerator {
     @Override
     public Invoice generateInvoice(final UUID accountId, final BillingEventSet events, final InvoiceItemList existingItems, final DateTime targetDate, final Currency targetCurrency) {
-        if (events == null) {return new InvoiceDefault(accountId, targetDate, targetCurrency);}
-        if (events.size() == 0) {return new InvoiceDefault(accountId, targetDate, targetCurrency);}
+        if (events == null) {return new DefaultInvoice(accountId, targetDate, targetCurrency);}
+        if (events.size() == 0) {return new DefaultInvoice(accountId, targetDate, targetCurrency);}
 
-        InvoiceDefault invoice = new InvoiceDefault(accountId, targetDate, targetCurrency);
+        DefaultInvoice invoice = new DefaultInvoice(accountId, targetDate, targetCurrency);
         InvoiceItemList currentItems = generateInvoiceItems(events, invoice.getId(), targetDate, targetCurrency);
         InvoiceItemList itemsToPost = reconcileInvoiceItems(invoice.getId(), currentItems, existingItems);
         invoice.add(itemsToPost);
@@ -46,8 +47,8 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
 
     private InvoiceItemList reconcileInvoiceItems(final UUID invoiceId, final InvoiceItemList currentInvoiceItems, final InvoiceItemList existingInvoiceItems) {
         InvoiceItemList currentItems = new InvoiceItemList();
-        for (IInvoiceItem item : currentInvoiceItems) {
-            currentItems.add(new InvoiceItem(item, invoiceId));
+        for (InvoiceItem item : currentInvoiceItems) {
+            currentItems.add(new DefaultInvoiceItem(item, invoiceId));
         }
 
         InvoiceItemList existingItems = (InvoiceItemList) existingInvoiceItems.clone();
@@ -55,11 +56,11 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         Collections.sort(currentItems);
         Collections.sort(existingItems);
 
-        List<IInvoiceItem> existingItemsToRemove = new ArrayList<IInvoiceItem>();
+        List<InvoiceItem> existingItemsToRemove = new ArrayList<InvoiceItem>();
 
-        for (IInvoiceItem currentItem : currentItems) {
+        for (InvoiceItem currentItem : currentItems) {
             // see if there are any existing items that are covered by the current item
-            for (IInvoiceItem existingItem : existingItems) {
+            for (InvoiceItem existingItem : existingItems) {
                 if (currentItem.duplicates(existingItem)) {
                     currentItem.subtract(existingItem);
                     existingItemsToRemove.add(existingItem);
@@ -76,7 +77,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         currentItems.removeZeroDollarItems();
 
         // add existing items that aren't covered by current items as credit items
-        for (IInvoiceItem existingItem : existingItems) {
+        for (InvoiceItem existingItem : existingItems) {
             currentItems.add(existingItem.asCredit(invoiceId));
         }
 
@@ -92,8 +93,8 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         // for each event, process it either as a terminated event (if there's a subsequent event)
         // ...or as a non-terminated event (if no subsequent event exists)
         for (int i = 0; i < (events.size() - 1); i++) {
-            IBillingEvent thisEvent = events.get(i);
-            IBillingEvent nextEvent = events.get(i + 1);
+            BillingEvent thisEvent = events.get(i);
+            BillingEvent nextEvent = events.get(i + 1);
 
             if (thisEvent.getSubscriptionId() == nextEvent.getSubscriptionId()) {
                 processEvents(invoiceId, thisEvent, nextEvent, items, targetDate, targetCurrency);
@@ -110,7 +111,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         return items;
     }
 
-    private void processEvent(UUID invoiceId, IBillingEvent event, List<IInvoiceItem> items, DateTime targetDate, Currency targetCurrency) {
+    private void processEvent(UUID invoiceId, BillingEvent event, List<InvoiceItem> items, DateTime targetDate, Currency targetCurrency) {
         BigDecimal rate = event.getPrice(targetCurrency);
         BigDecimal invoiceItemAmount = calculateInvoiceItemAmount(event, targetDate, rate);
         BillingMode billingMode = getBillingMode(event.getBillingMode());
@@ -119,7 +120,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         addInvoiceItem(invoiceId, items, event, billThroughDate, invoiceItemAmount, rate, targetCurrency);
     }
 
-    private void processEvents(UUID invoiceId, IBillingEvent firstEvent, IBillingEvent secondEvent, List<IInvoiceItem> items, DateTime targetDate, Currency targetCurrency) {
+    private void processEvents(UUID invoiceId, BillingEvent firstEvent, BillingEvent secondEvent, List<InvoiceItem> items, DateTime targetDate, Currency targetCurrency) {
         BigDecimal rate = firstEvent.getPrice(targetCurrency);
         BigDecimal invoiceItemAmount = calculateInvoiceItemAmount(firstEvent, secondEvent, targetDate, rate);
         BillingMode billingMode = getBillingMode(firstEvent.getBillingMode());
@@ -128,14 +129,14 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         addInvoiceItem(invoiceId, items, firstEvent, billThroughDate, invoiceItemAmount, rate, targetCurrency);
     }
 
-    private void addInvoiceItem(UUID invoiceId, List<IInvoiceItem> items, IBillingEvent event, DateTime billThroughDate, BigDecimal amount, BigDecimal rate, Currency currency) {
+    private void addInvoiceItem(UUID invoiceId, List<InvoiceItem> items, BillingEvent event, DateTime billThroughDate, BigDecimal amount, BigDecimal rate, Currency currency) {
         if (!(amount.compareTo(BigDecimal.ZERO) == 0)) {
-            IInvoiceItem item = new InvoiceItem(invoiceId, event.getSubscriptionId(), event.getEffectiveDate(), billThroughDate, event.getDescription(), amount, rate, currency);
+            DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, event.getSubscriptionId(), event.getEffectiveDate(), billThroughDate, event.getDescription(), amount, rate, currency);
             items.add(item);
         }
     }
 
-    private BigDecimal calculateInvoiceItemAmount(IBillingEvent event, DateTime targetDate, BigDecimal rate){
+    private BigDecimal calculateInvoiceItemAmount(BillingEvent event, DateTime targetDate, BigDecimal rate){
         BillingMode billingMode = getBillingMode(event.getBillingMode());
         DateTime startDate = event.getEffectiveDate();
         int billingCycleDay = event.getBillCycleDay();
@@ -151,7 +152,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         }
     }
 
-    private BigDecimal calculateInvoiceItemAmount(IBillingEvent firstEvent, IBillingEvent secondEvent, DateTime targetDate, BigDecimal rate) {
+    private BigDecimal calculateInvoiceItemAmount(BillingEvent firstEvent, BillingEvent secondEvent, DateTime targetDate, BigDecimal rate) {
         BillingMode billingMode = getBillingMode(firstEvent.getBillingMode());
         DateTime startDate = firstEvent.getEffectiveDate();
         int billingCycleDay = firstEvent.getBillCycleDay();
@@ -169,8 +170,8 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
         }
     }
 
-    private BillingMode getBillingMode(com.ning.billing.entitlement.api.billing.BillingMode billingMode) {
-        switch (billingMode) {
+    private BillingMode getBillingMode(BillingModeType billingModeType) {
+        switch (billingModeType) {
             case IN_ADVANCE:
                 return new InAdvanceBillingMode();
             default:
diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java
index 7d15f20..fb82f06 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/InvoiceItemList.java
@@ -16,20 +16,20 @@
 
 package com.ning.billing.invoice.model;
 
-import com.ning.billing.invoice.api.IInvoiceItem;
+import com.ning.billing.invoice.api.InvoiceItem;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
-public class InvoiceItemList extends ArrayList<IInvoiceItem> {
+public class InvoiceItemList extends ArrayList<InvoiceItem> {
     private static final int NUMBER_OF_DECIMALS = InvoicingConfiguration.getNumberOfDecimals();
 
     public BigDecimal getTotalAmount() {
         // TODO: Jeff -- naive implementation, assumes all invoice items share the same currency
         BigDecimal total = new BigDecimal("0");
 
-        for (IInvoiceItem item : this) {
+        for (InvoiceItem item : this) {
             total = total.add(item.getAmount());
         }
 
@@ -37,9 +37,9 @@ public class InvoiceItemList extends ArrayList<IInvoiceItem> {
     }
 
     public void removeZeroDollarItems() {
-        List<IInvoiceItem> itemsToRemove = new ArrayList<IInvoiceItem>();
+        List<InvoiceItem> itemsToRemove = new ArrayList<InvoiceItem>();
 
-        for (IInvoiceItem item : this) {
+        for (InvoiceItem item : this) {
             if (item.getAmount().compareTo(BigDecimal.ZERO) == 0) {
                 itemsToRemove.add(item);
             }
@@ -49,12 +49,12 @@ public class InvoiceItemList extends ArrayList<IInvoiceItem> {
     }
 
     public void removeCancellingPairs() {
-        List<IInvoiceItem> itemsToRemove = new ArrayList<IInvoiceItem>();
+        List<InvoiceItem> itemsToRemove = new ArrayList<InvoiceItem>();
 
         for (int firstItemIndex = 0; firstItemIndex < this.size(); firstItemIndex++) {
             for (int secondItemIndex = firstItemIndex + 1; secondItemIndex < this.size(); secondItemIndex++) {
-                IInvoiceItem firstItem = this.get(firstItemIndex);
-                IInvoiceItem secondItem = this.get(secondItemIndex);
+                InvoiceItem firstItem = this.get(firstItemIndex);
+                InvoiceItem secondItem = this.get(secondItemIndex);
                 if (firstItem.cancels(secondItem)) {
                     itemsToRemove.add(firstItem);
                     itemsToRemove.add(secondItem);
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
index 963bb53..3c25d8e 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
@@ -28,6 +28,18 @@ CREATE TABLE invoices (
 
 CREATE INDEX invoices_account_id ON invoices(account_id ASC);
 
+DROP TABLE IF EXISTS invoice_payments;
+CREATE TABLE invoice_payments (
+  id char(36) NOT NULL,
+  invoice_id char(36) NOT NULL,
+  payment_id char(36) NOT NULL,
+  payment_date datetime NOT NULL,
+  amount numeric(10,4) NOT NULL,
+  currency char(3) NOT NULL,
+  PRIMARY KEY(id)
+) ENGINE=innodb;
+CREATE UNIQUE INDEX invoice_payments_unique ON invoice_payments(invoice_id, payment_id);
+
 CREATE VIEW amount_remaining AS
 SELECT invoice_items.id,
        SUM(invoice_items.amount) AS amount_owed
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
index be96d86..0dd5d47 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
@@ -23,9 +23,9 @@ import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.dbi.MysqlTestingHelper;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.glue.InvoiceModuleMock;
-import com.ning.billing.invoice.model.InvoiceDefault;
-import com.ning.billing.invoice.model.InvoiceItem;
-import com.ning.billing.util.clock.Clock;
+import com.ning.billing.invoice.model.DefaultInvoice;
+import com.ning.billing.invoice.model.DefaultInvoiceItem;
+import com.ning.billing.util.clock.DefaultClock;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.testng.annotations.BeforeClass;
@@ -70,7 +70,7 @@ public class InvoiceDaoTests {
     @Test
     public void testCreationAndRetrievalByAccount() {
         UUID accountId = UUID.randomUUID();
-        Invoice invoice = new InvoiceDefault(accountId, new Clock().getUTCNow(), Currency.USD);
+        Invoice invoice = new DefaultInvoice(accountId, new DefaultClock().getUTCNow(), Currency.USD);
         DateTime invoiceDate = invoice.getInvoiceDate();
 
         dao.createInvoice(invoice);
@@ -96,7 +96,7 @@ public class InvoiceDaoTests {
     public void testAddPayment() {
         UUID accountId = UUID.randomUUID();
         DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
-        Invoice invoice = new InvoiceDefault(accountId, targetDate, Currency.USD);
+        Invoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD);
 
         DateTime paymentAttemptDate = new DateTime(2011, 6, 24, 12, 14, 36, 0);
         BigDecimal paymentAmount = new BigDecimal("14.0");
@@ -113,7 +113,7 @@ public class InvoiceDaoTests {
     public void testAddPaymentAttempt() {
         UUID accountId = UUID.randomUUID();
         DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
-        Invoice invoice = new InvoiceDefault(accountId, targetDate, Currency.USD);
+        Invoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD);
 
         DateTime paymentAttemptDate = new DateTime(2011, 6, 24, 12, 14, 36, 0);
 
@@ -134,7 +134,7 @@ public class InvoiceDaoTests {
         int existingInvoiceCount = invoices.size();
         
         UUID accountId = UUID.randomUUID();
-        Invoice invoice = new InvoiceDefault(accountId, targetDate, Currency.USD);
+        Invoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD);
 
         dao.createInvoice(invoice);
         invoices = dao.getInvoicesForPayment(notionalDate.toDate(), NUMBER_OF_DAY_BETWEEN_RETRIES);
@@ -154,7 +154,7 @@ public class InvoiceDaoTests {
         // create a new invoice with one item
         UUID accountId = UUID.randomUUID();
         DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
-        Invoice invoice = new InvoiceDefault(accountId, targetDate, Currency.USD);
+        Invoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD);
         dao.createInvoice(invoice);
 
         UUID invoiceId = invoice.getId();
@@ -163,7 +163,7 @@ public class InvoiceDaoTests {
         BigDecimal rate = new BigDecimal("9.0");
         BigDecimal amount = rate.multiply(new BigDecimal("3.0"));
 
-        InvoiceItem item = new InvoiceItem(invoiceId, subscriptionId, targetDate, endDate, "test", amount, rate, Currency.USD);
+        DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, targetDate, endDate, "test", amount, rate, Currency.USD);
         invoiceItemDao.createInvoiceItem(item);
 
         // ensure that the number of invoices for payment has increased by 1
@@ -223,7 +223,7 @@ public class InvoiceDaoTests {
 
 
         // create invoice 1 (subscriptions 1-4)
-        Invoice invoice1 = new InvoiceDefault(accountId, targetDate, Currency.USD);
+        Invoice invoice1 = new DefaultInvoice(accountId, targetDate, Currency.USD);
         dao.createInvoice(invoice1);
 
         UUID invoiceId1 = invoice1.getId();
@@ -231,20 +231,20 @@ public class InvoiceDaoTests {
         DateTime startDate = new DateTime(2011, 3, 1, 0, 0, 0, 0);
         DateTime endDate = startDate.plusMonths(1);
 
-        InvoiceItem item1 = new InvoiceItem(invoiceId1, subscriptionId1, startDate, endDate, "test A", rate1, rate1, Currency.USD);
+        DefaultInvoiceItem item1 = new DefaultInvoiceItem(invoiceId1, subscriptionId1, startDate, endDate, "test A", rate1, rate1, Currency.USD);
         invoiceItemDao.createInvoiceItem(item1);
 
-        InvoiceItem item2 = new InvoiceItem(invoiceId1, subscriptionId2, startDate, endDate, "test B", rate2, rate2, Currency.USD);
+        DefaultInvoiceItem item2 = new DefaultInvoiceItem(invoiceId1, subscriptionId2, startDate, endDate, "test B", rate2, rate2, Currency.USD);
         invoiceItemDao.createInvoiceItem(item2);
 
-        InvoiceItem item3 = new InvoiceItem(invoiceId1, subscriptionId3, startDate, endDate, "test C", rate3, rate3, Currency.USD);
+        DefaultInvoiceItem item3 = new DefaultInvoiceItem(invoiceId1, subscriptionId3, startDate, endDate, "test C", rate3, rate3, Currency.USD);
         invoiceItemDao.createInvoiceItem(item3);
 
-        InvoiceItem item4 = new InvoiceItem(invoiceId1, subscriptionId4, startDate, endDate, "test D", rate4, rate4, Currency.USD);
+        DefaultInvoiceItem item4 = new DefaultInvoiceItem(invoiceId1, subscriptionId4, startDate, endDate, "test D", rate4, rate4, Currency.USD);
         invoiceItemDao.createInvoiceItem(item4);
 
         // create invoice 2 (subscriptions 1-3)
-        InvoiceDefault invoice = new InvoiceDefault(accountId, targetDate, Currency.USD);
+        DefaultInvoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD);
         dao.createInvoice(invoice);
 
         UUID invoiceId2 = invoice.getId();
@@ -252,13 +252,13 @@ public class InvoiceDaoTests {
         startDate = endDate;
         endDate = startDate.plusMonths(1);
 
-        InvoiceItem item5 = new InvoiceItem(invoiceId2, subscriptionId1, startDate, endDate, "test A", rate1, rate1, Currency.USD);
+        DefaultInvoiceItem item5 = new DefaultInvoiceItem(invoiceId2, subscriptionId1, startDate, endDate, "test A", rate1, rate1, Currency.USD);
         invoiceItemDao.createInvoiceItem(item5);
 
-        InvoiceItem item6 = new InvoiceItem(invoiceId2, subscriptionId2, startDate, endDate, "test B", rate2, rate2, Currency.USD);
+        DefaultInvoiceItem item6 = new DefaultInvoiceItem(invoiceId2, subscriptionId2, startDate, endDate, "test B", rate2, rate2, Currency.USD);
         invoiceItemDao.createInvoiceItem(item6);
 
-        InvoiceItem item7 = new InvoiceItem(invoiceId2, subscriptionId3, startDate, endDate, "test C", rate3, rate3, Currency.USD);
+        DefaultInvoiceItem item7 = new DefaultInvoiceItem(invoiceId2, subscriptionId3, startDate, endDate, "test C", rate3, rate3, Currency.USD);
         invoiceItemDao.createInvoiceItem(item7);
 
         // check that each subscription returns the correct number of invoices
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
index 54fd71d..7e01ff2 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceItemDaoTests.java
@@ -20,10 +20,10 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.invoice.api.IInvoiceItem;
+import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.glue.InvoiceModuleMock;
-import com.ning.billing.invoice.model.InvoiceDefault;
-import com.ning.billing.invoice.model.InvoiceItem;
+import com.ning.billing.invoice.model.DefaultInvoice;
+import com.ning.billing.invoice.model.DefaultInvoiceItem;
 import org.apache.commons.io.IOUtils;
 import org.joda.time.DateTime;
 import org.testng.annotations.BeforeClass;
@@ -69,10 +69,10 @@ public class InvoiceItemDaoTests {
         DateTime endDate = new DateTime(2011, 11, 1, 0, 0, 0, 0);
         BigDecimal rate = new BigDecimal("20.00");
 
-        IInvoiceItem item = new InvoiceItem(invoiceId, subscriptionId, startDate, endDate, "test", rate, rate, Currency.USD);
+        InvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, startDate, endDate, "test", rate, rate, Currency.USD);
         dao.createInvoiceItem(item);
 
-        IInvoiceItem thisItem = dao.getInvoiceItem(item.getId().toString());
+        InvoiceItem thisItem = dao.getInvoiceItem(item.getId().toString());
         assertNotNull(thisItem);
         assertEquals(thisItem.getId(), item.getId());
         assertEquals(thisItem.getInvoiceId(), item.getInvoiceId());
@@ -93,11 +93,11 @@ public class InvoiceItemDaoTests {
 
         for (int i = 0; i < 3; i++) {
             UUID invoiceId = UUID.randomUUID();
-            InvoiceItem item = new InvoiceItem(invoiceId, subscriptionId, startDate.plusMonths(i), startDate.plusMonths(i + 1), "test", rate, rate, Currency.USD);
+            DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, startDate.plusMonths(i), startDate.plusMonths(i + 1), "test", rate, rate, Currency.USD);
             dao.createInvoiceItem(item);
         }
 
-        List<IInvoiceItem> items = dao.getInvoiceItemsBySubscription(subscriptionId.toString());
+        List<InvoiceItem> items = dao.getInvoiceItemsBySubscription(subscriptionId.toString());
         assertEquals(items.size(), 3);
     }
 
@@ -110,11 +110,11 @@ public class InvoiceItemDaoTests {
         for (int i = 0; i < 5; i++) {
             UUID subscriptionId = UUID.randomUUID();
             BigDecimal amount = rate.multiply(new BigDecimal(i + 1));
-            InvoiceItem item = new InvoiceItem(invoiceId, subscriptionId, startDate, startDate.plusMonths(1), "test", amount, amount, Currency.USD);
+            DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, startDate, startDate.plusMonths(1), "test", amount, amount, Currency.USD);
             dao.createInvoiceItem(item);
         }
 
-        List<IInvoiceItem> items = dao.getInvoiceItemsByInvoice(invoiceId.toString());
+        List<InvoiceItem> items = dao.getInvoiceItemsByInvoice(invoiceId.toString());
         assertEquals(items.size(), 5);
     }
 
@@ -122,7 +122,7 @@ public class InvoiceItemDaoTests {
     public void testGetInvoiceItemsByAccountId() {
         UUID accountId = UUID.randomUUID();
         DateTime targetDate = new DateTime(2011, 5, 23, 0, 0, 0, 0);
-        InvoiceDefault invoice = new InvoiceDefault(accountId, targetDate, Currency.USD);
+        DefaultInvoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD);
 
         invoiceDao.createInvoice(invoice);
 
@@ -131,10 +131,10 @@ public class InvoiceItemDaoTests {
         BigDecimal rate = new BigDecimal("20.00");
 
         UUID subscriptionId = UUID.randomUUID();
-        InvoiceItem item = new InvoiceItem(invoiceId, subscriptionId, startDate, startDate.plusMonths(1), "test", rate, rate, Currency.USD);
+        DefaultInvoiceItem item = new DefaultInvoiceItem(invoiceId, subscriptionId, startDate, startDate.plusMonths(1), "test", rate, rate, Currency.USD);
         dao.createInvoiceItem(item);
 
-        List<IInvoiceItem> items = dao.getInvoiceItemsByAccount(accountId.toString());
+        List<InvoiceItem> items = dao.getInvoiceItemsByAccount(accountId.toString());
         assertEquals(items.size(), 1);
     }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
index ee4d5fc..d01c470 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
@@ -18,15 +18,15 @@ package com.ning.billing.invoice.tests;
 
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.entitlement.api.billing.BillingMode;
-import com.ning.billing.entitlement.api.billing.IBillingEvent;
-import com.ning.billing.invoice.api.BillingEvent;
+import com.ning.billing.entitlement.api.billing.BillingEvent;
+import com.ning.billing.entitlement.api.billing.BillingModeType;
 import com.ning.billing.invoice.api.BillingEventSet;
-import com.ning.billing.invoice.api.IInvoiceItem;
+import com.ning.billing.invoice.api.DefaultBillingEvent;
 import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.model.DefaultInvoiceGenerator;
+import com.ning.billing.invoice.model.DefaultInvoiceItem;
 import com.ning.billing.invoice.model.InvoiceGenerator;
-import com.ning.billing.invoice.model.InvoiceItem;
 import com.ning.billing.invoice.model.InvoiceItemList;
 import org.joda.time.DateTime;
 import org.testng.annotations.Test;
@@ -72,9 +72,9 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
         DateTime startDate = buildDateTime(2011, 9, 1);
         String planName = "World Domination";
         String phaseName = "Build Space Laser";
-        IBillingEvent event = new BillingEvent(subscriptionId, startDate, planName, phaseName,
+        BillingEvent event = new DefaultBillingEvent(subscriptionId, startDate, planName, phaseName,
                                                new InternationalPriceMock(TEN), BillingPeriod.MONTHLY,
-                                               1, BillingMode.IN_ADVANCE);
+                                               1, BillingModeType.IN_ADVANCE);
 
         events.add(event);
 
@@ -98,9 +98,9 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
         String planName = "World Domination";
         String phaseName = "Build Space Laser";
         BigDecimal rate = TEN;
-        IBillingEvent event = new BillingEvent(subscriptionId, startDate, planName, phaseName,
+        BillingEvent event = new DefaultBillingEvent(subscriptionId, startDate, planName, phaseName,
                                                new InternationalPriceMock(rate), BillingPeriod.MONTHLY,
-                                               15, BillingMode.IN_ADVANCE);
+                                               15, BillingModeType.IN_ADVANCE);
 
         events.add(event);
 
@@ -123,16 +123,16 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
     public void testTwoMonthlySubscriptionsWithAlignedBillingDates() {
         BillingEventSet events = new BillingEventSet();
 
-        IBillingEvent event1 = new BillingEvent(UUID.randomUUID(), buildDateTime(2011, 9, 1),
+        BillingEvent event1 = new DefaultBillingEvent(UUID.randomUUID(), buildDateTime(2011, 9, 1),
                                                "World Domination", "Build Space Laser",
                                                new InternationalPriceMock(FIVE), BillingPeriod.MONTHLY,
-                                               1, BillingMode.IN_ADVANCE);
+                                               1, BillingModeType.IN_ADVANCE);
         events.add(event1);
 
-        IBillingEvent event2 = new BillingEvent(UUID.randomUUID(), buildDateTime(2011, 10, 1),
+        BillingEvent event2 = new DefaultBillingEvent(UUID.randomUUID(), buildDateTime(2011, 10, 1),
                                                "Groceries", "Pick Up Milk",
                                                new InternationalPriceMock(TEN), BillingPeriod.MONTHLY,
-                                               1, BillingMode.IN_ADVANCE);
+                                               1, BillingModeType.IN_ADVANCE);
         events.add(event2);
 
         InvoiceItemList existingInvoiceItems = new InvoiceItemList();
@@ -150,16 +150,16 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
         BillingEventSet events = new BillingEventSet();
 
         UUID subscriptionId = UUID.randomUUID();
-        IBillingEvent event1 = new BillingEvent(subscriptionId, buildDateTime(2011, 9, 1),
+        BillingEvent event1 = new DefaultBillingEvent(subscriptionId, buildDateTime(2011, 9, 1),
                                                "World Domination", "Build Space Laser",
                                                new InternationalPriceMock(FIVE), BillingPeriod.MONTHLY,
-                                               1, BillingMode.IN_ADVANCE);
+                                               1, BillingModeType.IN_ADVANCE);
         events.add(event1);
 
-        IBillingEvent event2 = new BillingEvent(subscriptionId, buildDateTime(2011, 10, 15),
+        BillingEvent event2 = new DefaultBillingEvent(subscriptionId, buildDateTime(2011, 10, 15),
                                                "World Domination", "Incinerate James Bond",
                                                new InternationalPriceMock(TEN), BillingPeriod.MONTHLY,
-                                               15, BillingMode.IN_ADVANCE);
+                                               15, BillingModeType.IN_ADVANCE);
         events.add(event2);
 
         InvoiceItemList existingInvoiceItems = new InvoiceItemList();
@@ -188,22 +188,22 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
         BillingEventSet events = new BillingEventSet();
 
         UUID subscriptionId = UUID.randomUUID();
-        IBillingEvent event1 = new BillingEvent(subscriptionId, buildDateTime(2011, 9, 1),
+        BillingEvent event1 = new DefaultBillingEvent(subscriptionId, buildDateTime(2011, 9, 1),
                                                "World Domination", "Build Space Laser",
                                                new InternationalPriceMock(FIVE), BillingPeriod.MONTHLY,
-                                               1, BillingMode.IN_ADVANCE);
+                                               1, BillingModeType.IN_ADVANCE);
         events.add(event1);
 
-        IBillingEvent event2 = new BillingEvent(subscriptionId, buildDateTime(2011, 10, 1),
+        BillingEvent event2 = new DefaultBillingEvent(subscriptionId, buildDateTime(2011, 10, 1),
                                                "World Domination", "Incinerate James Bond",
                                                new InternationalPriceMock(TEN), BillingPeriod.MONTHLY,
-                                               1, BillingMode.IN_ADVANCE);
+                                               1, BillingModeType.IN_ADVANCE);
         events.add(event2);
 
-        IBillingEvent event3 = new BillingEvent(subscriptionId, buildDateTime(2011, 11, 1),
+        BillingEvent event3 = new DefaultBillingEvent(subscriptionId, buildDateTime(2011, 11, 1),
                                                "World Domination", "Cackle Gleefully",
                                                new InternationalPriceMock(THIRTY), BillingPeriod.MONTHLY,
-                                               1, BillingMode.IN_ADVANCE);
+                                               1, BillingModeType.IN_ADVANCE);
         events.add(event3);
 
         InvoiceItemList existingInvoiceItems = new InvoiceItemList();
@@ -224,14 +224,14 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
         DateTime startDate = buildDateTime(2011, 9, 1);
 
         BigDecimal rate = FIVE;
-        IBillingEvent event1 = new BillingEvent(subscriptionId, startDate,
+        BillingEvent event1 = new DefaultBillingEvent(subscriptionId, startDate,
                                                "World Domination", "Build Space Laser",
                                                new InternationalPriceMock(rate), BillingPeriod.MONTHLY,
-                                               1, BillingMode.IN_ADVANCE);
+                                               1, BillingModeType.IN_ADVANCE);
         events.add(event1);
 
         InvoiceItemList existingInvoiceItems = new InvoiceItemList();
-        IInvoiceItem invoiceItem = new InvoiceItem(UUID.randomUUID(), subscriptionId, startDate, buildDateTime(2012, 1, 1), "",
+        InvoiceItem invoiceItem = new DefaultInvoiceItem(UUID.randomUUID(), subscriptionId, startDate, buildDateTime(2012, 1, 1), "",
                                                  rate.multiply(FOUR), rate, Currency.USD);
         existingInvoiceItems.add(invoiceItem);
 
@@ -396,19 +396,19 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
         testInvoiceGeneration(events, invoiceItems, buildDateTime(2011, 10, 10), 1, expectedAmount);
     }
 
-    private BillingEvent createBillingEvent(UUID subscriptionId, DateTime startDate, String planName, String planPhaseName,
+    private DefaultBillingEvent createBillingEvent(UUID subscriptionId, DateTime startDate, String planName, String planPhaseName,
                                             BigDecimal rate, int billCycleDay) {
-        return new BillingEvent(subscriptionId, startDate, planName, planPhaseName,
+        return new DefaultBillingEvent(subscriptionId, startDate, planName, planPhaseName,
                                 new InternationalPriceMock(rate), BillingPeriod.MONTHLY,
-                                billCycleDay, BillingMode.IN_ADVANCE);
+                                billCycleDay, BillingModeType.IN_ADVANCE);
 
     }
 
-    private BillingEvent createAnnualBillingEvent(UUID subscriptionId, DateTime startDate, String planName, String planPhaseName,
+    private DefaultBillingEvent createAnnualBillingEvent(UUID subscriptionId, DateTime startDate, String planName, String planPhaseName,
                                                   BigDecimal rate, int billCycleDay) {
-        return new BillingEvent(subscriptionId, startDate, planName, planPhaseName,
+        return new DefaultBillingEvent(subscriptionId, startDate, planName, planPhaseName,
                                 new InternationalPriceMock(rate), BillingPeriod.ANNUAL,
-                                billCycleDay, BillingMode.IN_ADVANCE);
+                                billCycleDay, BillingModeType.IN_ADVANCE);
 
     }
 
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/InternationalPriceMock.java b/invoice/src/test/java/com/ning/billing/invoice/tests/InternationalPriceMock.java
index 2217b6c..9198ba0 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/InternationalPriceMock.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/InternationalPriceMock.java
@@ -17,15 +17,15 @@
 package com.ning.billing.invoice.tests;
 
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.catalog.api.IInternationalPrice;
-import com.ning.billing.catalog.api.IPrice;
+import com.ning.billing.catalog.api.InternationalPrice;
+import com.ning.billing.catalog.api.Price;
 
 import java.math.BigDecimal;
 import java.util.Date;
 
 import static org.testng.Assert.fail;
 
-public class InternationalPriceMock implements IInternationalPrice {
+public class InternationalPriceMock implements InternationalPrice {
     private final BigDecimal rate;
 
     public InternationalPriceMock(BigDecimal rate) {
@@ -33,7 +33,7 @@ public class InternationalPriceMock implements IInternationalPrice {
     }
 
     @Override
-    public IPrice[] getPrices() {
+    public Price[] getPrices() {
         fail();
 
         return null;

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

diff --git a/payment/pom.xml b/payment/pom.xml
index 3592a7b..770e297 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.0.16-SNAPSHOT</version>
+        <version>0.0.17-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-payment</artifactId>

pom.xml 2(+1 -1)

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

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

diff --git a/util/pom.xml b/util/pom.xml
index e77c581..c7b6110 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -13,7 +13,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.0.16-SNAPSHOT</version>
+        <version>0.0.17-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-util</artifactId>
diff --git a/util/src/main/java/com/ning/billing/util/clock/Clock.java b/util/src/main/java/com/ning/billing/util/clock/Clock.java
index d165dab..b41a36d 100644
--- a/util/src/main/java/com/ning/billing/util/clock/Clock.java
+++ b/util/src/main/java/com/ning/billing/util/clock/Clock.java
@@ -16,58 +16,15 @@
 
 package com.ning.billing.util.clock;
 
-import com.ning.billing.catalog.api.IDuration;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
-import java.util.ArrayList;
-import java.util.List;
+public interface Clock {
 
-public class Clock implements IClock {
+    public DateTime getNow(DateTimeZone tz);
 
-    @Override
-    public DateTime getNow(DateTimeZone tz) {
-       DateTime result = new DateTime(tz);
-       return truncateMs(result);
-    }
+    public DateTime getUTCNow();
 
-    @Override
-    public DateTime getUTCNow() {
-        return getNow(DateTimeZone.UTC);
-    }
 
-
-    public static DateTime truncateMs(DateTime input) {
-        return input.minus(input.getMillisOfSecond());
-    }
-
-    public static DateTime addDuration(DateTime input, List<IDuration> durations) {
-
-        DateTime result = input;
-        for (IDuration cur : durations) {
-            switch (cur.getUnit()) {
-            case DAYS:
-                result = result.plusDays(cur.getNumber());
-                break;
-
-            case MONTHS:
-                result = result.plusMonths(cur.getNumber());
-                break;
-
-            case YEARS:
-                result = result.plusYears(cur.getNumber());
-                break;
-            case UNLIMITED:
-            default:
-                throw new RuntimeException("Trying to move to unlimited time period");
-            }
-        }
-        return result;
-    }
-
-    public static DateTime addDuration(DateTime input, IDuration duration) {
-        List<IDuration> list = new ArrayList<IDuration>();
-        list.add(duration);
-        return addDuration(input, list);
-    }
+    //public DateTime addDuration(DateTime input, IDuration duration);
 }
diff --git a/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java b/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java
new file mode 100644
index 0000000..5db2ac3
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/clock/DefaultClock.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.clock;
+
+import com.ning.billing.catalog.api.Duration;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DefaultClock implements Clock {
+
+    @Override
+    public DateTime getNow(DateTimeZone tz) {
+       DateTime result = new DateTime(tz);
+       return truncateMs(result);
+    }
+
+    @Override
+    public DateTime getUTCNow() {
+        return getNow(DateTimeZone.UTC);
+    }
+
+
+    public static DateTime truncateMs(DateTime input) {
+        return input.minus(input.getMillisOfSecond());
+    }
+
+    public static DateTime addDuration(DateTime input, List<Duration> durations) {
+
+        DateTime result = input;
+        for (Duration cur : durations) {
+            switch (cur.getUnit()) {
+            case DAYS:
+                result = result.plusDays(cur.getNumber());
+                break;
+
+            case MONTHS:
+                result = result.plusMonths(cur.getNumber());
+                break;
+
+            case YEARS:
+                result = result.plusYears(cur.getNumber());
+                break;
+            case UNLIMITED:
+            default:
+                throw new RuntimeException("Trying to move to unlimited time period");
+            }
+        }
+        return result;
+    }
+
+    public static DateTime addDuration(DateTime input, Duration duration) {
+        List<Duration> list = new ArrayList<Duration>();
+        list.add(duration);
+        return addDuration(input, list);
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/config/UriAccessor.java b/util/src/main/java/com/ning/billing/util/config/UriAccessor.java
new file mode 100644
index 0000000..e931837
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/config/UriAccessor.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.config;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Scanner;
+
+public class UriAccessor {
+	private static final String URI_SCHEME_FOR_CLASSPATH = "jar";
+	private static final String URI_SCHEME_FOR_FILE = "file";
+
+	public static InputStream accessUri(String uri)  throws IOException, URISyntaxException {
+		return accessUri(new URI(uri));
+	}
+	
+	public static InputStream accessUri(URI uri) throws IOException {
+		String scheme = uri.getScheme();
+        URL url = null;
+        if (scheme.equals(URI_SCHEME_FOR_CLASSPATH)) {
+        	return UriAccessor.class.getResourceAsStream(uri.getPath());
+        } else if (scheme.equals(URI_SCHEME_FOR_FILE) &&
+        	!uri.getSchemeSpecificPart().startsWith("/")) { // interpret URIs of this form as relative path uris
+        	url = new File(uri.getSchemeSpecificPart()).toURI().toURL();
+        }
+        url = uri.toURL();
+    	return url.openConnection().getInputStream();
+	}
+	
+	public static String accessUriAsString(String uri)  throws IOException, URISyntaxException {
+		return accessUriAsString(new URI(uri));
+	}
+	
+	public static String accessUriAsString(URI uri) throws IOException {
+		InputStream stream = accessUri(uri);
+		return new Scanner(stream).useDelimiter("\\A").next();
+	}
+}
diff --git a/util/src/main/java/com/ning/billing/util/config/ValidationError.java b/util/src/main/java/com/ning/billing/util/config/ValidationError.java
index 4a68dac..cd1ae4d 100644
--- a/util/src/main/java/com/ning/billing/util/config/ValidationError.java
+++ b/util/src/main/java/com/ning/billing/util/config/ValidationError.java
@@ -15,10 +15,10 @@
  */
 package com.ning.billing.util.config;
 
-import java.net.URI;
-
 import org.slf4j.Logger;
 
+import java.net.URI;
+
 
 public class ValidationError {
 	private final String description;
@@ -49,4 +49,8 @@ public class ValidationError {
 	public void log(Logger log) {
 		log.error(String.format("%s [%s] (%s:%s)", description, sourceURI, objectType, objectName));
 	}
+	
+	public String toString() {
+		return String.format("%s [%s] (%s:%s)\n", description, sourceURI, objectType, objectName);
+	}
 }
diff --git a/util/src/main/java/com/ning/billing/util/config/ValidationErrors.java b/util/src/main/java/com/ning/billing/util/config/ValidationErrors.java
index 901f636..c8145d2 100644
--- a/util/src/main/java/com/ning/billing/util/config/ValidationErrors.java
+++ b/util/src/main/java/com/ning/billing/util/config/ValidationErrors.java
@@ -16,11 +16,11 @@
 
 package com.ning.billing.util.config;
 
+import org.slf4j.Logger;
+
 import java.net.URI;
 import java.util.ArrayList;
 
-import org.slf4j.Logger;
-
 public class ValidationErrors extends ArrayList<ValidationError>{
 	private static final long serialVersionUID = 1L;
 
@@ -35,5 +35,13 @@ public class ValidationErrors extends ArrayList<ValidationError>{
 			error.log(log);
 		}	
 	}
+	
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		for(ValidationError error : this) {
+			builder.append(error.toString());
+		}	
+		return builder.toString();
+	}
 
 }
\ No newline at end of file
diff --git a/util/src/main/java/com/ning/billing/util/config/XMLLoader.java b/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
index 8aaaf14..d0487b8 100644
--- a/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
+++ b/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
@@ -16,12 +16,10 @@
 
 package com.ning.billing.util.config;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
+import com.ning.billing.catalog.api.InvalidConfigException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
 
 import javax.xml.XMLConstants;
 import javax.xml.bind.JAXBContext;
@@ -31,71 +29,56 @@ import javax.xml.transform.TransformerException;
 import javax.xml.transform.stream.StreamSource;
 import javax.xml.validation.Schema;
 import javax.xml.validation.SchemaFactory;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-import com.ning.billing.catalog.api.InvalidConfigException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
 
 public class XMLLoader {
-	private static final String URI_SCHEME_FOR_CLASSPATH = "jar";
-	private static final String URI_SCHEME_FOR_FILE = "file";
 	public static Logger log = LoggerFactory.getLogger(XMLLoader.class);
 
-	public static <T extends ValidatingConfig<T>> T getObjectFromProperty(String property, Class<T> objectType) throws Exception {
-		if (property == null) {
+	public static <T extends ValidatingConfig<T>> T getObjectFromString(String uri, Class<T> objectType) throws Exception {
+		if (uri == null) {
 			return null;
 		}
-		log.info("Initializing an object of class " + objectType.getName() + " from xml file at: " + property);
+		log.info("Initializing an object of class " + objectType.getName() + " from xml file at: " + uri);
 					
-		return getObjectFromURI(new URI(property), objectType);
+		return getObjectFromStream(new URI(uri), UriAccessor.accessUri(uri), objectType);
 	}
 	
-	public static <T extends ValidatingConfig<T>> T getObjectFromURI(final URI uri, final Class<T> objectType) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, URISyntaxException {
-        String scheme = uri.getScheme();
-        URI uriToCall = uri;
-        if (scheme.equals(URI_SCHEME_FOR_CLASSPATH)) {
-        	InputStream resourceStream = XMLLoader.class.getResourceAsStream(uri.getPath());
-        	return getObjectFromStream(uri, resourceStream, objectType);
-        } else if (scheme.equals(URI_SCHEME_FOR_FILE) &&
-        	!uri.getSchemeSpecificPart().startsWith("/")) { // interpret URIs of this form as relative path uris
-        	uriToCall = new File(uri.getSchemeSpecificPart()).toURI();
-        }
-        return getObjectFromURL(uriToCall.toURL(), objectType);
-    }
-
-	public static <T extends ValidatingConfig<T>> T getObjectFromURL(URL url, Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, URISyntaxException {
-        Object o = unmarshaller(clazz).unmarshal(url);
-    
-        if (clazz.isInstance(o)) {
-            @SuppressWarnings("unchecked")
-			T castObject = (T)o;
-            validate(url.toURI(),castObject);
-            return castObject;
-        } else {
-            return null;
-        }
-    }
-
-	public static <T extends ValidatingConfig<T>> T getObjectFromStream(URI uri,InputStream stream, Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException {
+	public static <T extends ValidatingConfig<T>> T getObjectFromUri(URI uri, Class<T> objectType) throws Exception {
+		if (uri == null) {
+			return null;
+		}
+		log.info("Initializing an object of class " + objectType.getName() + " from xml file at: " + uri);
+					
+		return getObjectFromStream(uri, UriAccessor.accessUri(uri), objectType);
+	}
+	
+	public static <T extends ValidatingConfig<T>> T getObjectFromStream(URI uri, InputStream stream, Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, ValidationException {
         Object o = unmarshaller(clazz).unmarshal(stream);
         if (clazz.isInstance(o)) {
         	@SuppressWarnings("unchecked")
 			T castObject = (T)o;
-            validate(uri,castObject);
+        	try {
+        		validate(uri,castObject);
+        	} catch (ValidationException e) {
+        		e.getErrors().log(log);
+        		System.err.println(e.getErrors().toString());
+        		throw e;
+        	}
             return castObject;
         } else {
             return null;
         }
-    }
-
-    
+    } 
 
-	public static <T extends ValidatingConfig<T>> void validate(URI uri, T c) {
+	public static <T extends ValidatingConfig<T>> void validate(URI uri, T c) throws ValidationException {
             c.initialize(c, uri);
             ValidationErrors errs = c.validate(c, new ValidationErrors());
-            log.info("Errors: " + errs.size() + " for " + uri);       
+            log.info("Errors: " + errs.size() + " for " + uri);  
+            if(errs.size() > 0) {
+            	throw new ValidationException(errs);
+            }
     }
     
     public static Unmarshaller unmarshaller(Class<?> clazz) throws JAXBException, SAXException, IOException, TransformerException {
diff --git a/util/src/main/java/com/ning/billing/util/eventbus/MemoryEventBus.java b/util/src/main/java/com/ning/billing/util/eventbus/MemoryEventBus.java
index 7cc0453..259736d 100644
--- a/util/src/main/java/com/ning/billing/util/eventbus/MemoryEventBus.java
+++ b/util/src/main/java/com/ning/billing/util/eventbus/MemoryEventBus.java
@@ -16,18 +16,17 @@
 
 package com.ning.billing.util.eventbus;
 
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicBoolean;
-
+import com.google.common.eventbus.AsyncEventBus;
 import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.eventbus.AsyncEventBus;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicBoolean;
 
-public class MemoryEventBus implements IEventBus {
+public class MemoryEventBus implements EventBus {
 
     // STEPH config ?
     private final static int MAX_EVENT_THREADS = 1;
@@ -93,13 +92,13 @@ public class MemoryEventBus implements IEventBus {
     }
 
     @Override
-    public void post(IEventBusType event) throws EventBusException {
+    public void post(EventBusNotification event) throws EventBusException {
         checkInitialized("post");
         delegate.post(event);
     }
 
     @Override
-    public void postFromTransaction(IEventBusType event, Transmogrifier dao) throws EventBusException {
+    public void postFromTransaction(EventBusNotification event, Transmogrifier dao) throws EventBusException {
         checkInitialized("postFromTransaction");
         delegate.post(event);
     }
diff --git a/util/src/main/java/com/ning/billing/util/glue/EventBusModule.java b/util/src/main/java/com/ning/billing/util/glue/EventBusModule.java
index e6e995a..078c331 100644
--- a/util/src/main/java/com/ning/billing/util/glue/EventBusModule.java
+++ b/util/src/main/java/com/ning/billing/util/glue/EventBusModule.java
@@ -17,17 +17,17 @@
 package com.ning.billing.util.glue;
 
 import com.google.inject.AbstractModule;
+import com.ning.billing.util.eventbus.DefaultEventBusService;
+import com.ning.billing.util.eventbus.EventBus;
 import com.ning.billing.util.eventbus.EventBusService;
-import com.ning.billing.util.eventbus.IEventBus;
-import com.ning.billing.util.eventbus.IEventBusService;
 import com.ning.billing.util.eventbus.MemoryEventBus;
 
 public class EventBusModule extends AbstractModule {
 
     @Override
     protected void configure() {
-        bind(IEventBusService.class).to(EventBusService.class);
-        bind(IEventBus.class).to(MemoryEventBus.class).asEagerSingleton();
+        bind(EventBusService.class).to(DefaultEventBusService.class);
+        bind(EventBus.class).to(MemoryEventBus.class).asEagerSingleton();
 
     }
 
diff --git a/util/src/test/java/com/ning/billing/util/clock/ClockMock.java b/util/src/test/java/com/ning/billing/util/clock/ClockMock.java
index eb7216e..0fb473d 100644
--- a/util/src/test/java/com/ning/billing/util/clock/ClockMock.java
+++ b/util/src/test/java/com/ning/billing/util/clock/ClockMock.java
@@ -16,16 +16,15 @@
 
 package com.ning.billing.util.clock;
 
-import java.util.ArrayList;
-import java.util.List;
-
+import com.ning.billing.catalog.api.Duration;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
-import com.ning.billing.catalog.api.IDuration;
+import java.util.ArrayList;
+import java.util.List;
 
 // STEPH should really be in tests but not accessible from other sub modules
-public class ClockMock extends Clock {
+public class ClockMock extends DefaultClock {
 
     private enum DeltaType {
         DELTA_NONE,
@@ -34,7 +33,7 @@ public class ClockMock extends Clock {
     }
 
     private long deltaFromRealityMs;
-    private List<IDuration> deltaFromRealityDuration;
+    private List<Duration> deltaFromRealityDuration;
     private long deltaFromRealitDurationEpsilon;
     private DeltaType deltaType;
 
@@ -55,15 +54,15 @@ public class ClockMock extends Clock {
         return getNow(DateTimeZone.UTC);
     }
 
-    public synchronized void setDeltaFromReality(IDuration delta, long epsilon) {
+    public synchronized void setDeltaFromReality(Duration delta, long epsilon) {
         deltaType = DeltaType.DELTA_DURATION;
-        deltaFromRealityDuration = new ArrayList<IDuration>();
+        deltaFromRealityDuration = new ArrayList<Duration>();
         deltaFromRealityDuration.add(delta);
         deltaFromRealitDurationEpsilon = epsilon;
         deltaFromRealityMs = 0;
     }
 
-    public synchronized void addDeltaFromReality(IDuration delta) {
+    public synchronized void addDeltaFromReality(Duration delta) {
         if (deltaType != DeltaType.DELTA_DURATION) {
             throw new RuntimeException("ClockMock should be set with type DELTA_DURATION");
         }
@@ -100,7 +99,7 @@ public class ClockMock extends Clock {
     private DateTime adjustFromDuration(DateTime input) {
 
         DateTime result = input;
-        for (IDuration cur : deltaFromRealityDuration) {
+        for (Duration cur : deltaFromRealityDuration) {
 
             int length = cur.getNumber();
             switch (cur.getUnit()) {
diff --git a/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java b/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java
index 02fbcd2..6721ee8 100644
--- a/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java
+++ b/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java
@@ -16,23 +16,19 @@
 
 package com.ning.billing.util.config;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
+import com.ning.billing.catalog.api.InvalidConfigException;
+import org.testng.annotations.Test;
+import org.xml.sax.SAXException;
 
+import javax.xml.bind.JAXBException;
+import javax.xml.transform.TransformerException;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.util.Date;
-
-import javax.xml.bind.JAXBException;
-import javax.xml.transform.TransformerException;
 
-import org.testng.annotations.Test;
-import org.xml.sax.SAXException;
-
-import com.ning.billing.catalog.api.InvalidConfigException;
+import static org.testng.Assert.assertEquals;
 
 
 public class TestXMLLoader {
@@ -44,7 +40,7 @@ public class TestXMLLoader {
 			"</xmlTestClass>";
 	
 	@Test
-	public void test() throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, URISyntaxException {
+	public void test() throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, URISyntaxException, ValidationException {
 		InputStream is = new ByteArrayInputStream(TEST_XML.getBytes());
 		XmlTestClass test = XMLLoader.getObjectFromStream(new URI("internal:/"), is, XmlTestClass.class);
 		assertEquals(test.getFoo(), "foo");
diff --git a/util/src/test/java/com/ning/billing/util/eventbus/TestEventBus.java b/util/src/test/java/com/ning/billing/util/eventbus/TestEventBus.java
index e4e41df..47691be 100644
--- a/util/src/test/java/com/ning/billing/util/eventbus/TestEventBus.java
+++ b/util/src/test/java/com/ning/billing/util/eventbus/TestEventBus.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.util.eventbus;
 
+import com.google.common.eventbus.Subscribe;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
@@ -23,13 +24,11 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import com.google.common.eventbus.Subscribe;
-
 public class TestEventBus {
 
     private static final Logger log = LoggerFactory.getLogger(TestEventBus.class);
 
-    private IEventBus eventBus;
+    private EventBus eventBus;
 
 
     @BeforeClass
@@ -43,7 +42,7 @@ public class TestEventBus {
         eventBus.stop();
     }
 
-    public static final class MyEvent implements IEventBusType {
+    public static final class MyEvent implements EventBusNotification {
         String name;
         Long value;