killbill-uncached

Changes

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

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

beatrix/pom.xml 97(+97 -0)

catalog/pom.xml 34(+10 -24)

invoice/pom.xml 7(+5 -2)

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

pom.xml 19(+13 -6)

util/pom.xml 7(+6 -1)

Details

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

diff --git a/account/pom.xml b/account/pom.xml
index 1641419..0ac8223 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.6-SNAPSHOT</version>
+        <version>0.0.10-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-account</artifactId>
diff --git a/account/src/main/java/com/ning/billing/account/api/AccountService.java b/account/src/main/java/com/ning/billing/account/api/AccountService.java
new file mode 100644
index 0000000..0ce4941
--- /dev/null
+++ b/account/src/main/java/com/ning/billing/account/api/AccountService.java
@@ -0,0 +1,47 @@
+/*
+ * 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.account.api;
+
+import com.google.inject.Inject;
+import com.ning.billing.lifecycle.LyfecycleHandlerType;
+import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
+
+public class AccountService implements IAccountService {
+
+    private static final String ACCOUNT_SERVICE_NAME = "account-service";
+
+    private final IAccountUserApi accountApi;
+
+    @Inject
+    public AccountService(IAccountUserApi api) {
+        this.accountApi = api;
+    }
+
+    @Override
+    public String getName() {
+        return ACCOUNT_SERVICE_NAME;
+    }
+
+    @Override
+    public IAccountUserApi getAccountUserApi() {
+        return accountApi;
+    }
+
+    @LyfecycleHandlerType(LyfecycleLevel.INIT_SERVICE)
+    public void initialize() {
+    }
+}
diff --git a/account/src/main/java/com/ning/billing/account/glue/AccountModule.java b/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
index 4f0ec7a..ce44014 100644
--- a/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
+++ b/account/src/main/java/com/ning/billing/account/glue/AccountModule.java
@@ -19,7 +19,9 @@ package com.ning.billing.account.glue;
 import org.skife.config.ConfigurationObjectFactory;
 
 import com.google.inject.AbstractModule;
+import com.ning.billing.account.api.AccountService;
 import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.account.api.IAccountService;
 import com.ning.billing.account.api.IAccountUserApi;
 import com.ning.billing.account.dao.AccountDao;
 import com.ning.billing.account.dao.IAccountDao;
@@ -39,11 +41,16 @@ public class AccountModule extends AbstractModule {
         bind(IAccountUserApi.class).to(AccountUserApi.class).asEagerSingleton();
     }
 
+    protected void installAcountService() {
+        bind(IAccountService.class).to(AccountService.class).asEagerSingleton();
+    }
+
     @Override
     protected void configure() {
         installConfig();
         installAccountDao();
         installAccountUserApi();
+        installAcountService();
     }
 
 }
diff --git a/analytics/pom.xml b/analytics/pom.xml
index 32f9291..8765302 100644
--- a/analytics/pom.xml
+++ b/analytics/pom.xml
@@ -14,7 +14,7 @@
     <parent>
         <groupId>com.ning.billing</groupId>
         <artifactId>killbill</artifactId>
-        <version>0.0.6-SNAPSHOT</version>
+        <version>0.0.10-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-analytics</artifactId>

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

diff --git a/api/pom.xml b/api/pom.xml
index 2fdce61..e9d887f 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.6-SNAPSHOT</version>
+        <version>0.0.10-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-api</artifactId>
diff --git a/api/src/main/java/com/ning/billing/account/api/IAccountService.java b/api/src/main/java/com/ning/billing/account/api/IAccountService.java
new file mode 100644
index 0000000..fa5a9fe
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/account/api/IAccountService.java
@@ -0,0 +1,24 @@
+/*
+ * 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.account.api;
+
+import com.ning.billing.lifecycle.IService;
+
+public interface IAccountService extends IService {
+
+    public IAccountUserApi getAccountUserApi();
+}
diff --git a/api/src/main/java/com/ning/billing/catalog/api/ActionPolicy.java b/api/src/main/java/com/ning/billing/catalog/api/ActionPolicy.java
index 86b8619..4719d4d 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/ActionPolicy.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/ActionPolicy.java
@@ -17,6 +17,7 @@
 package com.ning.billing.catalog.api;
 
 public enum ActionPolicy {
-	END_OF_TERM,
-	IMMEDIATE
+	END_OF_TERM, // transition occurs at end of term
+	IMMEDIATE,   // transition occurs immediately
+	ILLEGAL      // transition is not allowed
 }
diff --git a/api/src/main/java/com/ning/billing/catalog/api/ICatalog.java b/api/src/main/java/com/ning/billing/catalog/api/ICatalog.java
index f583753..403adec 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/ICatalog.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/ICatalog.java
@@ -23,7 +23,7 @@ public interface ICatalog {
 
 	public abstract IProduct[] getProducts();
 
-	public abstract IPriceList[] getPriceLists();
+	public abstract IPriceListSet getPriceLists();
 
 	public abstract IPriceList getPriceListFromName(String priceListName);
 
diff --git a/api/src/main/java/com/ning/billing/catalog/api/IPriceList.java b/api/src/main/java/com/ning/billing/catalog/api/IPriceList.java
index f6a528a..44d515d 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/IPriceList.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/IPriceList.java
@@ -26,5 +26,6 @@ public interface IPriceList {
 	public abstract IPlan findPlanByProductName(String productName);
 
 	public abstract boolean isDefault();
+	
 
 }
\ No newline at end of file
diff --git a/api/src/main/java/com/ning/billing/catalog/api/IPriceListSet.java b/api/src/main/java/com/ning/billing/catalog/api/IPriceListSet.java
new file mode 100644
index 0000000..f973b9e
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/catalog/api/IPriceListSet.java
@@ -0,0 +1,29 @@
+/*
+ * 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.catalog.api;
+
+public interface IPriceListSet {
+	
+	public static final String DEFAULT_PRICELIST_NAME = "DEFAULT";
+
+	public abstract IPriceList getDefaultPricelist();
+
+	public abstract IPriceList[] getChildPriceLists();
+
+	public abstract IPriceList getPriceListFromName(String priceListName);
+
+}
\ No newline at end of file
diff --git a/api/src/main/java/com/ning/billing/catalog/api/ProductCategory.java b/api/src/main/java/com/ning/billing/catalog/api/ProductCategory.java
index dca1f8d..22eb658 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/ProductCategory.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/ProductCategory.java
@@ -18,5 +18,6 @@ package com.ning.billing.catalog.api;
 
 public enum ProductCategory {
 	BASE,
-	ADD_ON
+	ADD_ON,
+	STANDALONE
 }
diff --git a/api/src/main/java/com/ning/billing/config/ICatalogConfig.java b/api/src/main/java/com/ning/billing/config/ICatalogConfig.java
new file mode 100644
index 0000000..29699fe
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/config/ICatalogConfig.java
@@ -0,0 +1,28 @@
+/*
+ * 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.config;
+
+import org.skife.config.Config;
+import org.skife.config.Default;
+
+public interface ICatalogConfig {
+
+    @Config("killbill.catalog.uri")
+    @Default("jar:///com/ning/billing/irs/catalog/NingCatalog.xml")
+    String getCatalogURI();
+
+}
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/IEntitlementService.java b/api/src/main/java/com/ning/billing/entitlement/api/IEntitlementService.java
new file mode 100644
index 0000000..41cd37d
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/entitlement/api/IEntitlementService.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
+import com.ning.billing.entitlement.api.user.IApiListener;
+import com.ning.billing.entitlement.api.user.IEntitlementUserApi;
+import com.ning.billing.lifecycle.IService;
+
+public interface IEntitlementService extends IService {
+
+
+    @Override
+    public String getName();
+
+    public IEntitlementUserApi getUserApi(List<IApiListener> listeners);
+
+    public IEntitlementBillingApi getBillingApi();
+
+}
diff --git a/api/src/main/java/com/ning/billing/lifecycle/IService.java b/api/src/main/java/com/ning/billing/lifecycle/IService.java
new file mode 100644
index 0000000..4e4d6d1
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/lifecycle/IService.java
@@ -0,0 +1,49 @@
+/*
+ * 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.lifecycle;
+
+public interface IService {
+
+    public static class ServiceException extends Exception  {
+
+        private static final long serialVersionUID = 176191207L;
+
+        public ServiceException() {
+            super();
+        }
+
+        public ServiceException(String msg, Throwable e) {
+            super(msg, e);
+        }
+
+        public ServiceException(String msg) {
+            super(msg);
+        }
+
+        public ServiceException(Throwable msg) {
+            super(msg);
+        }
+    }
+
+    /**
+     *
+     * @return the name of the service
+     */
+    public String getName();
+
+
+}
diff --git a/api/src/main/java/com/ning/billing/lifecycle/Lifecycled.java b/api/src/main/java/com/ning/billing/lifecycle/Lifecycled.java
new file mode 100644
index 0000000..df1fb82
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/lifecycle/Lifecycled.java
@@ -0,0 +1,27 @@
+/*
+ * 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.lifecycle;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Lifecycled {
+}
diff --git a/api/src/main/java/com/ning/billing/lifecycle/LyfecycleHandlerType.java b/api/src/main/java/com/ning/billing/lifecycle/LyfecycleHandlerType.java
new file mode 100644
index 0000000..520fca4
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/lifecycle/LyfecycleHandlerType.java
@@ -0,0 +1,91 @@
+/*
+ * 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.lifecycle;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface LyfecycleHandlerType {
+
+
+    //
+    // The level themselves are still work in progress depending on what we really need
+    //
+    public enum LyfecycleLevel {
+
+        /**
+         * Load and validate catalog (only for catalog subsytem)
+         */
+        LOAD_CATALOG(Sequence.STARTUP),
+        /**
+         * Initialize event bus (only for the event bus)
+         */
+        INIT_BUS(Sequence.STARTUP),
+        /**
+         * Service specific initalization
+         */
+        INIT_SERVICE(Sequence.STARTUP),
+        /**
+         * Service register their interest in events
+         */
+        REGISTER_EVENTS(Sequence.STARTUP),
+        /**
+         * Service start
+         * - API call should not work
+         * - Events might be triggered
+         * - Batch processing jobs started
+         */
+        START_SERVICE(Sequence.STARTUP),
+        /**
+         * Stop service
+         */
+        STOP_SERVICE(Sequence.SHUTOWN),
+        /**
+         * Unregister interest in events
+         */
+        UNREGISTER_EVENTS(Sequence.SHUTOWN),
+        /**
+         * Stop bus
+         */
+        STOP_BUS(Sequence.SHUTOWN),
+        /**
+         * Any service specific shutdown action before the end
+         */
+        SHUTDOWN(Sequence.SHUTOWN);
+
+        public enum Sequence {
+            STARTUP,
+            SHUTOWN
+        };
+
+        private Sequence seq;
+
+        LyfecycleLevel(Sequence seq) {
+            this.seq = seq;
+        }
+
+        public Sequence getSequence() {
+            return seq;
+        }
+    }
+
+    public LyfecycleLevel value();
+}

beatrix/pom.xml 97(+97 -0)

diff --git a/beatrix/pom.xml b/beatrix/pom.xml
new file mode 100644
index 0000000..04a0938
--- /dev/null
+++ b/beatrix/pom.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ~ 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. -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.ning.billing</groupId>
+        <artifactId>killbill</artifactId>
+        <version>0.0.10-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>killbill-beatrix</artifactId>
+    <name>killbill-beatrix</name>
+    <packaging>jar</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-entitlement</artifactId>
+        </dependency>
+       <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-catalog</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.jolbox</groupId>
+            <artifactId>bonecp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <version>3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.skife.config</groupId>
+            <artifactId>config-magic</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.jdbi</groupId>
+            <artifactId>jdbi-metrics</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jdbi</groupId>
+            <artifactId>jdbi</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.mysql</groupId>
+            <artifactId>management</artifactId>
+            <version>5.0.11</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/beatrix/src/main/java/com/ning/billing/beatrix/glue/BeatrixModule.java b/beatrix/src/main/java/com/ning/billing/beatrix/glue/BeatrixModule.java
new file mode 100644
index 0000000..7a672c1
--- /dev/null
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/glue/BeatrixModule.java
@@ -0,0 +1,29 @@
+/*
+ * 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.beatrix.glue;
+
+import com.google.inject.AbstractModule;
+import com.ning.billing.beatrix.lifecycle.Lifecycle;
+
+public class BeatrixModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        bind(Lifecycle.class).asEagerSingleton();
+    }
+
+}
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
new file mode 100644
index 0000000..6abdb75
--- /dev/null
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/Lifecycle.java
@@ -0,0 +1,164 @@
+/*
+ * 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.beatrix.lifecycle;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+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;
+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;
+
+
+public class Lifecycle {
+
+    private final static Logger log = LoggerFactory.getLogger(Lifecycle.class);
+    private final SetMultimap<LyfecycleLevel, LifecycleHandler<? extends IService>> handlersByLevel;
+
+    private final ServiceFinder serviceFinder;
+
+    private final Injector injector;
+
+    @Inject
+    public Lifecycle(Injector injector) {
+
+        this.serviceFinder = new ServiceFinder(Lifecycle.class.getClassLoader());
+        this.handlersByLevel = Multimaps.newSetMultimap(new ConcurrentHashMap<LyfecycleLevel, Collection<LifecycleHandler<? extends IService>>>(),
+
+                new Supplier<Set<LifecycleHandler<? extends IService>>>() {
+            @Override
+            public Set<LifecycleHandler<? extends IService>> get() {
+                return new CopyOnWriteArraySet<LifecycleHandler<? extends IService>>();
+            }
+        });
+        this.injector = injector;
+
+        init();
+    }
+
+    public void init() {
+        Set<? extends IService> services = findServices();
+        Iterator<? extends IService> it = services.iterator();
+        while (it.hasNext()) {
+            handlersByLevel.putAll(findAllHandlers(it.next()));
+        }
+    }
+
+    public void fireStartupSequence() {
+        for (LyfecycleLevel level : LyfecycleLevel.values()) {
+            if (level.getSequence() == Sequence.SHUTOWN) {
+                break;
+            }
+            doFireStage(level);
+        }
+    }
+
+    public void fireShutdownSequence() {
+        for (LyfecycleLevel level : LyfecycleLevel.values()) {
+            if (level.getSequence() == Sequence.STARTUP) {
+                continue;
+            }
+            doFireStage(level);
+        }
+    }
+
+    private void doFireStage(LyfecycleLevel level) {
+        log.info("Killbill lifecycle firing stage {}", level);
+        Set<LifecycleHandler<? extends IService>> handlers = handlersByLevel.get(level);
+        for (LifecycleHandler<? extends IService> cur : handlers) {
+
+            try {
+                Method method = cur.getMethod();
+                IService target = cur.getTarget();
+                log.info("Killbill lifecycle calling handler {} for service {}", cur.getMethod().getName(), target.getName());
+                method.invoke(target);
+            } catch (Exception e) {
+                log.warn("Killbill lifecycle failed to invoke lifecycle handler", e);
+            }
+        }
+
+    }
+
+    private Set<? extends IService> findServices() {
+
+        Set<IService> result = new HashSet<IService>();
+        Set<Class<? extends IService>> services =  serviceFinder.getServices();
+        for (Class<? extends IService> cur : services) {
+            log.debug("Found service {}", cur.getName());
+            try {
+                IService instance = injector.getInstance(cur);
+                log.debug("got instance {}", instance.getName());
+                result.add(instance);
+            } catch (Exception e) {
+                log.warn("Failed to inject " + cur.getName(), e);
+            }
+
+        }
+        return result;
+    }
+
+
+    public Multimap<LyfecycleLevel, LifecycleHandler<? extends IService>> findAllHandlers(IService service) {
+        Multimap<LyfecycleLevel, LifecycleHandler<? extends IService>> methodsInService =
+            HashMultimap.create();
+        Class<? extends IService> clazz = service.getClass();
+        for (Method method : clazz.getMethods()) {
+            LyfecycleHandlerType annotation = method.getAnnotation(LyfecycleHandlerType.class);
+            if (annotation != null) {
+                LyfecycleLevel level = annotation.value();
+                LifecycleHandler<? extends IService> handler = new  LifecycleHandler<IService>(service, method);
+                methodsInService.put(level, handler);
+            }
+        }
+        return methodsInService;
+    }
+
+
+    private final class LifecycleHandler<T> {
+        private final T target;
+        private final Method method;
+
+        public LifecycleHandler(T target, Method method) {
+            this.target = target;
+            this.method = method;
+        }
+
+        public T getTarget() {
+            return target;
+        }
+
+        public Method getMethod() {
+            return method;
+        }
+    }
+}
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
new file mode 100644
index 0000000..fe3f0c5
--- /dev/null
+++ b/beatrix/src/main/java/com/ning/billing/beatrix/lifecycle/ServiceFinder.java
@@ -0,0 +1,212 @@
+/*
+ * 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.beatrix.lifecycle;
+
+
+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.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;
+
+	public ServiceFinder(ClassLoader loader) {
+		this.loader = loader;
+		this.servicesTypes = initialize();
+		Iterator<Class<? extends IService>> it = servicesTypes.iterator();
+		while (it.hasNext()) {
+		    Class<? extends IService> svc = it.next();
+			log.debug("Found IService classes {}", svc.getName());
+		}
+	}
+
+	public Set<Class<? extends IService>> getServices() {
+	    return servicesTypes;
+	}
+
+	private Set<Class<? extends IService>> 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);
+		} catch (ClassNotFoundException nfe) {
+			throw new RuntimeException("Failed to initialize ClassFinder", nfe);
+		}
+	}
+
+    /*
+     *  Code originally from Kris Dover <krisdover@hotmail.com> and adapted for my purpose.
+     *
+     */
+	private static Set<Class<? extends IService>> findClasses(ClassLoader classLoader,
+	        String interfaceFilter,
+	        String jarFilter,
+	        Set<String> packageFilter)
+	        throws ClassNotFoundException {
+
+	    final Set<Class<? extends IService>> result = new HashSet<Class<? extends IService>>();
+
+	    Object[] classPaths;
+	    try {
+	        classPaths = ((java.net.URLClassLoader) classLoader).getURLs();
+	    } catch(ClassCastException cce){
+	        classPaths = System.getProperty("java.class.path", "").split(File.pathSeparator);
+	    }
+
+	    for (int h = 0; h < classPaths.length; h++) {
+
+
+	        Enumeration<?> files = null;
+	        JarFile module = null;
+	        File classPath = new File( (URL.class).isInstance(classPaths[h]) ?
+	                ((URL)classPaths[h]).getFile() : classPaths[h].toString());
+	        if (classPath.isDirectory()) {
+	            List<String> dirListing = new ArrayList<String>();
+	            recursivelyListDir(dirListing, classPath, new StringBuffer() );
+	            files = Collections.enumeration( dirListing );
+	        } else if (classPath.getName().endsWith(".jar")) {
+	            String [] jarParts = classPath.getName().split("/");
+	            String jarName = jarParts[jarParts.length - 1];
+	            if (jarFilter != null && jarName != null && ! jarName.startsWith(jarFilter)) {
+	                continue;
+	            }
+	            boolean failed = true;
+	            try {
+	                module = new JarFile(classPath);
+	                failed = false;
+	            } catch (MalformedURLException mue){
+	                throw new ClassNotFoundException("Bad classpath. Error: " + mue.getMessage());
+	            } catch (IOException io){
+	                throw new ClassNotFoundException("jar file '" + classPath.getName() +
+	                        "' could not be instantiate from file path. Error: " + io.getMessage());
+	            }
+	            if (! failed) {
+	                files = module.entries();
+	            }
+	        }
+
+	        while( files != null && files.hasMoreElements() ){
+	            String fileName = files.nextElement().toString();
+
+	            if( fileName.endsWith(".class") ){
+	                String className = fileName.replaceAll("/", ".").substring(0, fileName.length() - 6);
+	                if (packageFilter != null) {
+	                    boolean skip = true;
+	                    Iterator<String> it = packageFilter.iterator();
+	                    while (it.hasNext()) {
+	                        String filter = it.next() + ".";
+	                        if (className.startsWith(filter)) {
+	                            skip = false;
+	                            break;
+	                        }
+	                    }
+	                    if (skip) {
+	                        continue;
+	                    }
+	                }
+	                Class<?> theClass = null;
+	                try {
+	                    theClass = Class.forName(className, false, classLoader);
+	                } catch(NoClassDefFoundError e) {
+	                    continue;
+	                }
+	                if ( theClass.isInterface() ) {
+	                    continue;
+	                }
+	                Class<?> [] classInterfaces = getAllInterfaces(theClass);
+	                String interfaceName = null;
+	                for (int i = 0; i < classInterfaces.length; i++) {
+
+	                    interfaceName = classInterfaces[i].getName();
+	                    if (!interfaceFilter.equals(interfaceName) ) {
+	                        continue;
+	                    }
+	                    result.add((Class<? extends IService>) theClass);
+	                    break;
+	                }
+
+	            }
+	        }
+	        if (module != null) {
+	            try {
+	                module.close();
+	            } catch(IOException ioe) {
+	                throw new ClassNotFoundException("The module jar file '" + classPath.getName() +
+	                        "' could not be closed. Error: " + ioe.getMessage());
+	            }
+	        }
+	    }
+	    return result;
+	}
+
+	private static Class<?> [] getAllInterfaces(Class<?> theClass) {
+	    Set<Class<?>> superInterfaces = new HashSet<Class<?>>();
+	    Class<?> [] classInterfaces = theClass.getInterfaces();
+	    for (Class<?> cur : classInterfaces) {
+	        getSuperInterfaces(superInterfaces, cur);
+	    }
+	    return superInterfaces.toArray(new Class<?>[superInterfaces.size()]);
+	}
+
+	private static void getSuperInterfaces(Set<Class<?>> superInterfaces, Class<?> theInterface) {
+
+	    superInterfaces.add(theInterface);
+	    Class<?> [] classInterfaces = theInterface.getInterfaces();
+	    for (Class<?> cur : classInterfaces) {
+	        getSuperInterfaces(superInterfaces, cur);
+	    }
+	}
+
+	private static void recursivelyListDir(List<String> dirListing, File dir, StringBuffer relativePath){
+	    int prevLen;
+	    if (dir.isDirectory()) {
+	        File[] files = dir.listFiles();
+	        for(int i = 0; i < files.length; i++){
+	            prevLen = relativePath.length();
+	            recursivelyListDir(dirListing, files[i],
+	                    relativePath.append(prevLen == 0 ? "" : "/" ).append( files[i].getName()));
+	            relativePath.delete(prevLen, relativePath.length());
+	        }
+	    } else {
+	        dirListing.add(relativePath.toString());
+	    }
+	}
+}
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
new file mode 100644
index 0000000..f85232f
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/lifecycle/TestLifecycle.java
@@ -0,0 +1,103 @@
+/*
+ * 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.beatrix.lifecycle;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+import com.ning.billing.lifecycle.IService;
+import com.ning.billing.lifecycle.Lifecycled;
+import com.ning.billing.lifecycle.LyfecycleHandlerType;
+import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
+
+
+public class TestLifecycle {
+
+    private final static Logger log = LoggerFactory.getLogger(TestLifecycle.class);
+
+    private Service1 s1;
+    private Service2 s2;
+
+    private Lifecycle lifecycle;
+
+    public static class Service1 implements IService {
+
+        @LyfecycleHandlerType(LyfecycleLevel.INIT_BUS)
+        public void initBus() {
+            log.info("Service1 : got INIT_BUS");
+        }
+
+        @LyfecycleHandlerType(LyfecycleLevel.START_SERVICE)
+        public void startService() {
+            log.info("Service1 : got START_SERVICE");
+        }
+
+        @Override
+        public String getName() {
+            return null;
+        }
+    }
+
+    @Lifecycled
+    public static class Service2 implements IService {
+
+        @LyfecycleHandlerType(LyfecycleLevel.LOAD_CATALOG)
+        public void loadCatalog() {
+            log.info("Service1 : got LOAD_CATALOG");
+        }
+
+        @Override
+        public String getName() {
+            return null;
+        }
+
+    }
+
+
+
+    @BeforeClass(groups={"fast"})
+    public void setup() {
+        final Injector g = Guice.createInjector(Stage.DEVELOPMENT, new TestLifecycleModule());
+        s1 = g.getInstance(Service1.class);
+        s2 = g.getInstance(Service2.class);
+        lifecycle = g.getInstance(Lifecycle.class);
+    }
+
+    @Test
+    public void testLifecycle() {
+        lifecycle.fireStartupSequence();
+    }
+
+
+    public static class TestLifecycleModule extends AbstractModule {
+
+        @Override
+        protected void configure() {
+            bind(Lifecycle.class).asEagerSingleton();
+            bind(Service1.class).asEagerSingleton();
+            bind(Service2.class).asEagerSingleton();
+        }
+
+    }
+}
+
diff --git a/beatrix/src/test/resources/log4j.xml b/beatrix/src/test/resources/log4j.xml
new file mode 100644
index 0000000..75abc76
--- /dev/null
+++ b/beatrix/src/test/resources/log4j.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
+        <param name="Target" value="System.out"/>
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%p	%d{ISO8601}	%X{trace}	%t	%c	%m%n"/>
+        </layout>
+    </appender>
+
+
+    <logger name="com.ning.billing.entitlement">
+        <level value="info"/>
+    </logger>
+
+    <root>
+        <priority value="info"/>
+        <appender-ref ref="stdout"/>
+    </root>
+</log4j:configuration>

catalog/pom.xml 34(+10 -24)

diff --git a/catalog/pom.xml b/catalog/pom.xml
index bc477d7..d61f61f 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.6-SNAPSHOT</version>
+        <version>0.0.10-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-catalog</artifactId>
@@ -29,32 +29,18 @@
             <artifactId>killbill-api</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-util</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.testng</groupId>
             <artifactId>testng</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>exec-maven-plugin</artifactId>
-                <version>1.1.1</version>
-                <executions>
-                    <execution>
-                        <phase>test</phase>
-                        <goals>
-                            <goal>java</goal>
-                        </goals>
-                        <configuration>
-                            <mainClass>com.ning.billing.catalog.io.XMLSchemaGenerator</mainClass>
-                            <arguments>
-                                <argument>${project.basedir}/src/test/resources</argument>
-                            </arguments>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
 </project>
diff --git a/catalog/src/main/java/com/ning/billing/catalog/Case.java b/catalog/src/main/java/com/ning/billing/catalog/Case.java
index 2d92df0..24b6fff 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/Case.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/Case.java
@@ -22,8 +22,10 @@ import javax.xml.bind.annotation.XmlIDREF;
 import com.ning.billing.catalog.api.BillingPeriod;
 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 {
+public abstract class Case<T> extends ValidatingConfig<Catalog> {
 
 	@XmlElement(required=false)
 	@XmlIDREF
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CaseBillingAlignment.java b/catalog/src/main/java/com/ning/billing/catalog/CaseBillingAlignment.java
index 57dd49c..064bb61 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CaseBillingAlignment.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CaseBillingAlignment.java
@@ -25,13 +25,14 @@ import com.ning.billing.catalog.api.ProductCategory;
 
 public class CaseBillingAlignment extends CasePhase<BillingAlignment> {
 
+
 	@XmlElement(required=true)
 	private BillingAlignment alignment;
 
 	public CaseBillingAlignment() {}
 
 	public CaseBillingAlignment(Product product, ProductCategory productCategory, BillingPeriod billingPeriod,
-			PriceList priceList, PhaseType phaseType, BillingAlignment alignment) {
+			PriceListChild priceList, PhaseType phaseType, BillingAlignment alignment) {
 		super(product, productCategory, billingPeriod, priceList, phaseType, alignment);
 		this.alignment = alignment;
 	}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CaseCancelPolicy.java b/catalog/src/main/java/com/ning/billing/catalog/CaseCancelPolicy.java
index 700d6be..954ec8d 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CaseCancelPolicy.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CaseCancelPolicy.java
@@ -30,7 +30,7 @@ public class CaseCancelPolicy extends CasePhase<ActionPolicy>{
 
 	public CaseCancelPolicy() {}
 
-	public CaseCancelPolicy(Product product, ProductCategory productCategory, BillingPeriod billingPeriod, PriceList priceList,
+	public CaseCancelPolicy(Product product, ProductCategory productCategory, BillingPeriod billingPeriod, PriceListChild priceList,
 			PhaseType phaseType, ActionPolicy policy) {
 		super(product, productCategory, billingPeriod, priceList, phaseType, policy);
 		this.policy = policy;
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CaseChange.java b/catalog/src/main/java/com/ning/billing/catalog/CaseChange.java
index 5eabc70..96b4248 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CaseChange.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CaseChange.java
@@ -22,13 +22,16 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlIDREF;
 
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.IPriceList;
 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 {
+public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
 
 	@XmlElement(required=false)
 	private PhaseType phaseType;
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CaseChangePlanAlignment.java b/catalog/src/main/java/com/ning/billing/catalog/CaseChangePlanAlignment.java
index a00ebb4..7c0e02c 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CaseChangePlanAlignment.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CaseChangePlanAlignment.java
@@ -34,7 +34,7 @@ public class CaseChangePlanAlignment extends CaseChange<PlanAlignmentChange> {
 			Product from, Product to, 
 			ProductCategory fromProductCategory, ProductCategory toProductCategory, 
 			BillingPeriod fromBP,BillingPeriod toBP, 
-			PriceList fromPriceList, PriceList toPriceList,
+			PriceListChild fromPriceList, PriceListChild toPriceList,
 			PhaseType fromType, 
 			PlanAlignmentChange result) {
 		super(from, to, 
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CaseChangePlanPolicy.java b/catalog/src/main/java/com/ning/billing/catalog/CaseChangePlanPolicy.java
index 258b9cd..050668e 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CaseChangePlanPolicy.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CaseChangePlanPolicy.java
@@ -36,7 +36,7 @@ public class CaseChangePlanPolicy extends CaseChange<ActionPolicy> {
 			Product from, Product to, 
 			ProductCategory fromProductCategory, ProductCategory toProductCategory, 
 			BillingPeriod fromBP,BillingPeriod toBP, 
-			PriceList fromPriceList, PriceList toPriceList,
+			PriceListChild fromPriceList, PriceListChild toPriceList,
 			PhaseType fromType,
 			ActionPolicy result) {
 		super(from, to, 
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CaseCreateAlignment.java b/catalog/src/main/java/com/ning/billing/catalog/CaseCreateAlignment.java
index 69a64ca..f1dcbbc 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CaseCreateAlignment.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CaseCreateAlignment.java
@@ -19,6 +19,7 @@ package com.ning.billing.catalog;
 import javax.xml.bind.annotation.XmlElement;
 
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.IPriceList;
 import com.ning.billing.catalog.api.PlanAlignmentCreate;
 import com.ning.billing.catalog.api.ProductCategory;
 
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CasePhase.java b/catalog/src/main/java/com/ning/billing/catalog/CasePhase.java
index 36cafc3..5941802 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CasePhase.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CasePhase.java
@@ -23,6 +23,7 @@ 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;
 
 public abstract class CasePhase<T> extends Case<T> {
 
diff --git a/catalog/src/main/java/com/ning/billing/catalog/Catalog.java b/catalog/src/main/java/com/ning/billing/catalog/Catalog.java
index d96aee8..f588821 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/Catalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/Catalog.java
@@ -16,7 +16,8 @@
 
 package com.ning.billing.catalog;
 
-import java.net.URL;
+import java.net.URI;
+import java.util.Collection;
 import java.util.Date;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -30,30 +31,27 @@ import com.ning.billing.catalog.api.BillingAlignment;
 import com.ning.billing.catalog.api.BillingPeriod;
 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.IPriceList;
 import com.ning.billing.catalog.api.IProduct;
 import com.ning.billing.catalog.api.PlanAlignmentChange;
 import com.ning.billing.catalog.api.PlanAlignmentCreate;
 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.ValidationError;
+import com.ning.billing.util.config.ValidationErrors;
 
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
-public class Catalog extends ValidatingConfig implements ICatalog {
-	public PlanRules getPlanRules() {
-		return planRules;
-	}
-
-	public void setPlanRules(PlanRules planRules) {
-		this.planRules = planRules;
-	}
-
+public class Catalog extends ValidatingConfig<Catalog> implements ICatalog {
 	@XmlElement(required=true)
 	private Date effectiveDate;
 
 	@XmlElement(required=true)
 	private String catalogName;
 
-	private String catalogURL;
+	private URI catalogURI;
 
 	@XmlElementWrapper(name="currencies", required=true)
 	@XmlElement(name="currency", required=true)
@@ -70,9 +68,8 @@ public class Catalog extends ValidatingConfig implements ICatalog {
 	@XmlElement(name="plan", required=true)
 	private Plan[] plans;
 
-	@XmlElementWrapper(name="priceLists", required=true)
-	@XmlElement(name="priceList", required=true)
-	private PriceList[] priceLists;
+	@XmlElement(name="priceLists", required=true)
+	private PriceListSet priceLists;
 
 	public Catalog() {}
 
@@ -81,19 +78,17 @@ public class Catalog extends ValidatingConfig implements ICatalog {
 	}
 
 	@Override
-	public void initialize(Catalog catalog) {
-		super.initialize(catalog);
-		planRules.initialize(catalog);
+	public void initialize(Catalog catalog, URI sourceURI) {
+		catalogURI = sourceURI;
+		super.initialize(catalog, sourceURI);
+		planRules.initialize(catalog, sourceURI);
+		priceLists.initialize(catalog, sourceURI);
 		for(Product p : products) {
-			p.initialize(catalog);
+			p.initialize(catalog, sourceURI);
 		}
 		for(Plan p : plans) {
-			p.initialize(catalog);
-		}
-		for(PriceList p : priceLists) {
-			p.initialize(catalog);
+			p.initialize(catalog, sourceURI);
 		}
-
 	}
 
     /* (non-Javadoc)
@@ -120,25 +115,16 @@ public class Catalog extends ValidatingConfig implements ICatalog {
 	 * @see com.ning.billing.catalog.ICatalog#getPlanSets()
 	 */
 	@Override
-	public PriceList[] getPriceLists() {
+	public PriceListSet getPriceLists() {
 		return priceLists;
 	}
  
-	public void setPlanSets(PriceList[] planSets) {
-		this.priceLists = planSets;
-	}
-
 	/* (non-Javadoc)
 	 * @see com.ning.billing.catalog.ICatalog#getPriceListFromName(java.lang.String)
 	 */
 	@Override
 	public PriceList getPriceListFromName(String priceListName) {
-		for(PriceList set : priceLists) {
-			if(set.getName().equals(priceListName)) {
-				return set;
-			}
-		}
-        return null;
+		return priceLists.getPriceListFromName(priceListName);
     }
 
     /* (non-Javadoc)
@@ -147,7 +133,7 @@ public class Catalog extends ValidatingConfig implements ICatalog {
     @Override
 	public Plan getPlan(String productName, BillingPeriod term, String planSetName) {
 
-        PriceList planSet = getPriceListFromName(planSetName);
+    	PriceList planSet = getPriceListFromName(planSetName);
         if (planSet == null) {
             return null;
         }
@@ -185,14 +171,22 @@ public class Catalog extends ValidatingConfig implements ICatalog {
 
 	@Override
 	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
-		errors.addAll(validate(catalog,errors, products));
-		errors.addAll(validate(catalog,errors, priceLists));
-		errors.addAll(validate(catalog,errors, plans));
-		errors.addAll(planRules.validate(catalog, errors));
+		validate(catalog,errors, products);
+		validate(catalog,errors, plans);
+		priceLists.validate(catalog,errors);
+		planRules.validate(catalog, errors);
 		return errors;
 	}
 
-    @Override
+    private Collection<? extends ValidationError> validate(Catalog catalog,
+			ValidationErrors errors, ValidatingConfig<Catalog>[] configs) {
+		for(ValidatingConfig<Catalog> config: configs) {
+			
+		}
+		return null;
+	}
+
+	@Override
     public ActionPolicy getPlanChangePolicy(PlanPhaseSpecifier from, PlanSpecifier to) {
         return planRules.getPlanChangePolicy(from, to, this);
     }
@@ -274,12 +268,16 @@ public class Catalog extends ValidatingConfig implements ICatalog {
 		this.effectiveDate = effectiveDate;
 	}
 
-	public String getCatalogURL() {
-		return catalogURL;
+	public URI getCatalogURI() {
+		return catalogURI;
+	}
+	
+	public PlanRules getPlanRules() { 
+		return planRules;
 	}
 
-	public void setCatalogURL(String catalogURL) {
-		this.catalogURL = catalogURL;
+	public void setPlanRules(PlanRules planRules) {
+		this.planRules = planRules;
 	}
 
 	@Override
@@ -290,7 +288,7 @@ public class Catalog extends ValidatingConfig implements ICatalog {
     	return null;
     }
 
-	public void setPriceLists(PriceList[] priceLists) {
+	public void setPriceLists(PriceListSet priceLists) {
 		this.priceLists = priceLists;
 	}
 
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java b/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java
new file mode 100644
index 0000000..f1d01c8
--- /dev/null
+++ b/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java
@@ -0,0 +1,81 @@
+/*
+ * 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.catalog;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.ning.billing.catalog.api.ICatalog;
+import com.ning.billing.catalog.api.ICatalogService;
+import com.ning.billing.config.ICatalogConfig;
+import com.ning.billing.lifecycle.IService;
+import com.ning.billing.lifecycle.LyfecycleHandlerType;
+import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
+import com.ning.billing.util.config.XMLLoader;
+
+public class CatalogService implements IService, Provider<ICatalog>, ICatalogService {
+
+    private static final String CATALOG_SERVICE_NAME = "catalog-service";
+
+    private static ICatalog catalog;
+
+    private final ICatalogConfig config;
+    private boolean isInitialized;
+
+
+    @Inject
+    public CatalogService(ICatalogConfig config) {
+        this.config = config;
+        System.out.println(config.getCatalogURI());
+        this.isInitialized = false;
+    }
+
+    @LyfecycleHandlerType(LyfecycleLevel.LOAD_CATALOG)
+    public synchronized void loadCatalog() throws ServiceException {
+        if (!isInitialized) {
+            try {
+                catalog = XMLLoader.getObjectFromProperty(config.getCatalogURI(), Catalog.class);
+                isInitialized = true;
+            } catch (Exception e) {
+                throw new ServiceException(e);
+            }
+        }
+    }
+
+
+    @Override
+    public String getName() {
+        return CATALOG_SERVICE_NAME;
+    }
+
+
+
+    /* (non-Javadoc)
+     * @see com.ning.billing.catalog.ICatlogService#getCatalog()
+     */
+    @Override
+    public ICatalog getCatalog() {
+        return catalog;
+    }
+
+
+    // Should be able to use bind(ICatalog.class).toProvider(CatalogService.class);
+    @Override
+    public ICatalog get() {
+        return catalog;
+    }
+
+}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CatalogUserApi.java b/catalog/src/main/java/com/ning/billing/catalog/CatalogUserApi.java
index 744bf5a..b42d12b 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CatalogUserApi.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CatalogUserApi.java
@@ -20,15 +20,15 @@ import java.io.File;
 
 import com.ning.billing.catalog.api.ICatalog;
 import com.ning.billing.catalog.api.ICatalogUserApi;
-import com.ning.billing.catalog.io.XMLReader;
+import com.ning.billing.util.config.XMLLoader;
 
 public class CatalogUserApi implements ICatalogUserApi {
 
     @Override
     public ICatalog getCatalog(final String catalogName) {
-    	String name = catalogName; 
+    	String name = catalogName;
         try {
-            return XMLReader.getCatalogFromName(new File(name).toURI().toURL());
+            return XMLLoader.getObjectFromURI(new File(name).toURI(), Catalog.class);
         } catch (Exception e) {
             e.printStackTrace();
             return null;
diff --git a/catalog/src/main/java/com/ning/billing/catalog/Duration.java b/catalog/src/main/java/com/ning/billing/catalog/Duration.java
index 5e7909a..ac34cf6 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/Duration.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/Duration.java
@@ -22,9 +22,11 @@ import javax.xml.bind.annotation.XmlElement;
 
 import com.ning.billing.catalog.api.IDuration;
 import com.ning.billing.catalog.api.TimeUnit;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class Duration extends ValidatingConfig implements IDuration {
+public class Duration extends ValidatingConfig<Catalog> implements IDuration {
 	@XmlElement(required=true)
     private TimeUnit unit;
 
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
new file mode 100644
index 0000000..deb2305
--- /dev/null
+++ b/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java
@@ -0,0 +1,46 @@
+/*
+ * 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.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;
+
+public class CatalogModule extends AbstractModule {
+
+    protected void installConfig() {
+        final ICatalogConfig config = new ConfigurationObjectFactory(System.getProperties()).build(ICatalogConfig.class);
+        bind(ICatalogConfig.class).toInstance(config);
+    }
+
+    protected void installCatalog() {
+        bind(ICatalogUserApi.class).to(CatalogUserApi.class).asEagerSingleton();
+        bind(ICatalogService.class).to(CatalogService.class).asEagerSingleton();
+    }
+
+    @Override
+    protected void configure() {
+        installConfig();
+        installCatalog();
+    }
+
+}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/InternationalPrice.java b/catalog/src/main/java/com/ning/billing/catalog/InternationalPrice.java
index 48d9782..c81c9b7 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/InternationalPrice.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/InternationalPrice.java
@@ -26,9 +26,11 @@ import javax.xml.bind.annotation.XmlElement;
 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.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class InternationalPrice extends ValidatingConfig implements IInternationalPrice {
+public class InternationalPrice extends ValidatingConfig<Catalog> implements IInternationalPrice {
 
 	//TODO MDW Validation - effectiveDateForExistingSubscriptons > catalog effectiveDate 
 	@XmlElement(required=false)
@@ -72,7 +74,7 @@ public class InternationalPrice extends ValidatingConfig implements IInternation
 		for (IPrice p : prices) {
 			Currency currency = p.getCurrency();
 			if(!currencyIsSupported(currency, supportedCurrencies)) {
-				errors.add("Unsupported currency: " + currency, catalog.getCatalogURL(), this.getClass(), "");
+				errors.add("Unsupported currency: " + currency, catalog.getCatalogURI(), this.getClass(), "");
 			}
 		}
 		return errors;
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 fcda9d7..9bc2314 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
@@ -19,6 +19,7 @@ package com.ning.billing.catalog.io;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.ArrayList;
@@ -33,23 +34,23 @@ 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 implements ICatalogLoader {
+public class VersionedCatalogLoader  {
 	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 = "\"";
-		
+			
 	/* (non-Javadoc)
 	 * @see com.ning.billing.catalog.io.ICatalogLoader#load(java.net.URL)
 	 */
-	@Override
-	public  VersionedCatalog load(URL url) throws IOException, SAXException, InvalidConfigException, JAXBException, TransformerException {
+	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 = XMLReader.getCatalogFromName(u);
+			Catalog catalog = XMLLoader.getObjectFromURL(u, Catalog.class);
 			result.add(catalog);
 		}
 		return result;
diff --git a/catalog/src/main/java/com/ning/billing/catalog/IPriceListDefault.java b/catalog/src/main/java/com/ning/billing/catalog/IPriceListDefault.java
new file mode 100644
index 0000000..e2185e6
--- /dev/null
+++ b/catalog/src/main/java/com/ning/billing/catalog/IPriceListDefault.java
@@ -0,0 +1,25 @@
+/*
+ * 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.catalog;
+
+public interface IPriceListDefault {
+
+	public abstract Plan[] getPlans();
+
+	public abstract Plan findPlanByProductName(String productName);
+
+}
\ No newline at end of file
diff --git a/catalog/src/main/java/com/ning/billing/catalog/Plan.java b/catalog/src/main/java/com/ning/billing/catalog/Plan.java
index bfdd093..1ae6199 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/Plan.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/Plan.java
@@ -16,6 +16,7 @@
 
 package com.ning.billing.catalog;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Iterator;
 
@@ -31,9 +32,11 @@ 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.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class Plan extends ValidatingConfig implements IPlan {
+public class Plan extends ValidatingConfig<Catalog> implements IPlan {
 
 
 	@XmlAttribute(required=true)
@@ -67,8 +70,8 @@ public class Plan extends ValidatingConfig implements IPlan {
 	}
 
 	@Override
-	public void initialize(Catalog catalog) {
-		super.initialize(catalog);
+	public void initialize(Catalog catalog, URI sourceURI) {
+		super.initialize(catalog, sourceURI);
 		if(finalPhase != null) {
 			finalPhase.setPlan(this);
 		}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/PlanPhase.java b/catalog/src/main/java/com/ning/billing/catalog/PlanPhase.java
index b1367c0..36250b4 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/PlanPhase.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/PlanPhase.java
@@ -27,9 +27,11 @@ import com.ning.billing.catalog.api.IInternationalPrice;
 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.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class PlanPhase extends ValidatingConfig implements IPlanPhase {
+public class PlanPhase extends ValidatingConfig<Catalog> implements IPlanPhase {
 
 	@XmlAttribute (required=true)
 	private PhaseType type;
diff --git a/catalog/src/main/java/com/ning/billing/catalog/PlanPolicyChangeRule.java b/catalog/src/main/java/com/ning/billing/catalog/PlanPolicyChangeRule.java
index 816c1f6..8b8079b 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/PlanPolicyChangeRule.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/PlanPolicyChangeRule.java
@@ -22,9 +22,11 @@ import javax.xml.bind.annotation.XmlElement;
 
 import com.ning.billing.catalog.api.ActionPolicy;
 import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class PlanPolicyChangeRule extends ValidatingConfig {
+public class PlanPolicyChangeRule extends ValidatingConfig<Catalog> {
 	public enum Qualifier {
 		DEFAULT,
 		PRODUCT_FROM_LOW_TO_HIGH,
diff --git a/catalog/src/main/java/com/ning/billing/catalog/PlanRules.java b/catalog/src/main/java/com/ning/billing/catalog/PlanRules.java
index fa36049..e2ff36d 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/PlanRules.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/PlanRules.java
@@ -29,9 +29,11 @@ import com.ning.billing.catalog.api.PlanAlignmentChange;
 import com.ning.billing.catalog.api.PlanAlignmentCreate;
 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;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class PlanRules extends ValidatingConfig  {
+public class PlanRules extends ValidatingConfig<Catalog>  {
 
 	@XmlElementWrapper(name="tiers", required=true)
 	@XmlElement(name="tier", required=false) // may not have tiers in some catalogs
diff --git a/catalog/src/main/java/com/ning/billing/catalog/Price.java b/catalog/src/main/java/com/ning/billing/catalog/Price.java
index 9dcbcba..885191e 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/Price.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/Price.java
@@ -24,9 +24,11 @@ import javax.xml.bind.annotation.XmlElement;
 
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.IPrice;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class Price extends ValidatingConfig implements IPrice {
+public class Price extends ValidatingConfig<Catalog> implements IPrice {
 	@XmlElement(required=true)
 	private Currency currency;
 
diff --git a/catalog/src/main/java/com/ning/billing/catalog/PriceList.java b/catalog/src/main/java/com/ning/billing/catalog/PriceList.java
index 76e55bb..de76149 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/PriceList.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/PriceList.java
@@ -18,82 +18,21 @@ package com.ning.billing.catalog;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlID;
-import javax.xml.bind.annotation.XmlIDREF;
 
+import com.ning.billing.catalog.api.IPlan;
 import com.ning.billing.catalog.api.IPriceList;
+import com.ning.billing.util.config.ValidatingConfig;
 
 @XmlAccessorType(XmlAccessType.NONE)
-public class PriceList extends ValidatingConfig implements IPriceList {
+public abstract class PriceList extends ValidatingConfig<Catalog> implements IPriceList {
 
-	@XmlAttribute(required=true)
 	@XmlID
-	private String name;
+	public abstract String getName();
 
-	@XmlElement(required=false) 
-	private Boolean isDefault = false;
+	public abstract Plan[] getPlans();
 
-	@XmlElementWrapper(name="plans", required=true)
-	@XmlElement(name="plan", required=true)
-	@XmlIDREF
-    private Plan[] plans;
-
-    /* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanSet#getName()
-	 */
-    @Override
-	public String getName() {
-        return name;
-    }
-
-    /* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanSet#getPlans()
-	 */
-    @Override
-	public Plan[] getPlans() {
-        return plans;
-    }
-
-    /* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanSet#findPlanByProductName(java.lang.String)
-	 */
-    @Override
-	public Plan findPlanByProductName(String productName) {
-        for (Plan cur : plans) {
-            if (cur.getProduct().getName().equals(productName)) {
-                return cur;
-            }
-        }
-        return null;
-    }
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public void setPlans(Plan[] plans) {
-		this.plans = plans;
-	}
-
-	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.IPlanSet#getProductType()
-	 */
-	@Override
-	public boolean isDefault() {
-		return isDefault;
-	}
-
-	public void setProductType(boolean isDefault) {
-		this.isDefault = isDefault;
-	}
-
-	@Override
-	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
-		return errors;
-
-	}
+	public abstract IPlan findPlanByProductName(String productName);
 
+	public abstract boolean isDefault();
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/PriceListChild.java b/catalog/src/main/java/com/ning/billing/catalog/PriceListChild.java
new file mode 100644
index 0000000..3e9c101
--- /dev/null
+++ b/catalog/src/main/java/com/ning/billing/catalog/PriceListChild.java
@@ -0,0 +1,94 @@
+/*
+ * 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.catalog;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlID;
+import javax.xml.bind.annotation.XmlIDREF;
+
+import com.ning.billing.catalog.api.IPriceList;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
+
+@XmlAccessorType(XmlAccessType.NONE)
+public class PriceListChild extends PriceList implements IPriceList {
+
+	@XmlAttribute(required=true)
+	@XmlID
+	private String name;
+
+	@XmlElementWrapper(name="plans", required=true)
+	@XmlElement(name="plan", required=true)
+	@XmlIDREF
+    private Plan[] plans;
+
+    /* (non-Javadoc)
+	 * @see com.ning.billing.catalog.IPlanSet#getName()
+	 */
+    @Override
+	public String getName() {
+        return name;
+    }
+
+    /* (non-Javadoc)
+	 * @see com.ning.billing.catalog.IPlanSet#getPlans()
+	 */
+    @Override
+	public Plan[] getPlans() {
+        return plans;
+    }
+
+    /* (non-Javadoc)
+	 * @see com.ning.billing.catalog.IPlanSet#findPlanByProductName(java.lang.String)
+	 */
+    @Override
+	public Plan findPlanByProductName(String productName) {
+        for (Plan cur : plans) {
+            if (cur.getProduct().getName().equals(productName)) {
+                return cur;
+            }
+        }
+        return null;
+    }
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public void setPlans(Plan[] plans) {
+		this.plans = plans;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ning.billing.catalog.IPlanSet#getProductType()
+	 */
+	@Override
+	public boolean isDefault() {
+		return false;
+	}
+
+	@Override
+	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
+		return errors;
+
+	}
+
+}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java b/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java
new file mode 100644
index 0000000..770f391
--- /dev/null
+++ b/catalog/src/main/java/com/ning/billing/catalog/PriceListDefault.java
@@ -0,0 +1,79 @@
+/*
+ * 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.catalog;
+
+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 javax.xml.bind.annotation.XmlIDREF;
+
+import com.ning.billing.catalog.api.IPriceList;
+import com.ning.billing.catalog.api.IPriceListSet;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationErrors;
+
+@XmlAccessorType(XmlAccessType.NONE)
+public class PriceListDefault extends PriceList implements IPriceList {
+
+	@XmlElementWrapper(name="plans", required=true)
+	@XmlElement(name="plan", required=true)
+	@XmlIDREF
+    private Plan[] plans;
+  
+	/* (non-Javadoc)
+	 * @see com.ning.billing.catalog.IPriceListDefault#getPlans()
+	 */
+	@Override
+	public Plan[] getPlans() {
+        return plans;
+    }
+
+	/* (non-Javadoc)
+	 * @see com.ning.billing.catalog.IPriceListDefault#findPlanByProductName(java.lang.String)
+	 */
+	@Override
+	public Plan findPlanByProductName(String productName) {
+        for (Plan cur : plans) {
+            if (cur.getProduct().getName().equals(productName)) {
+                return cur;
+            }
+        }
+        return null;
+    }
+
+	public void setPlans(Plan[] plans) {
+		this.plans = plans;
+	}
+
+	@Override
+	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
+		return errors;
+
+	}
+
+	@Override
+	public String getName() {
+		return IPriceListSet.DEFAULT_PRICELIST_NAME;
+	}
+
+	@Override
+	public boolean isDefault() {
+		return true;
+	}
+
+}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/PriceListSet.java b/catalog/src/main/java/com/ning/billing/catalog/PriceListSet.java
new file mode 100644
index 0000000..08c2cf9
--- /dev/null
+++ b/catalog/src/main/java/com/ning/billing/catalog/PriceListSet.java
@@ -0,0 +1,95 @@
+/*
+ * 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.catalog;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+import com.ning.billing.catalog.api.IPriceList;
+import com.ning.billing.catalog.api.IPriceListSet;
+import com.ning.billing.util.config.ValidatingConfig;
+import com.ning.billing.util.config.ValidationError;
+import com.ning.billing.util.config.ValidationErrors;
+
+@XmlAccessorType(XmlAccessType.NONE)
+public class PriceListSet extends ValidatingConfig<Catalog> implements IPriceListSet {
+	@XmlElement(required=true, name="defaultPriceList")
+	private PriceListDefault defaultPricelist;
+	
+	@XmlElement(required=false, name="childPriceList")
+	private PriceListChild[] childPriceLists;
+	
+	public PriceListSet() {
+		if(childPriceLists == null) {
+			childPriceLists = new PriceListChild[0];
+		}
+	}
+	/* (non-Javadoc)
+	 * @see com.ning.billing.catalog.IPriceListSet#getDefaultPricelist()
+	 */
+	@Override
+	public PriceListDefault getDefaultPricelist() {
+		return defaultPricelist;
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.ning.billing.catalog.IPriceListSet#getChildPriceLists()
+	 */
+	@Override
+	public PriceListChild[] getChildPriceLists() {
+		return childPriceLists;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.ning.billing.catalog.IPriceListSet#getPriceListFromName(String priceListName)
+	 */
+	@Override
+	public PriceList getPriceListFromName(String priceListName) {
+		if(priceListName.equals(DEFAULT_PRICELIST_NAME)) {
+			return getDefaultPricelist();
+		}
+		for(PriceListChild set : childPriceLists) {
+			if(set.getName().equals(priceListName)) {
+				return set;
+			}
+		}
+        return null;
+	}
+	
+	
+
+	public void setDefaultPricelist(PriceListDefault defaultPricelist) {
+		this.defaultPricelist = defaultPricelist;
+	}
+
+	public void setChildPriceLists(PriceListChild[] childPriceLists) {
+		this.childPriceLists = childPriceLists;
+	}
+
+	@Override
+	public ValidationErrors validate(Catalog root, ValidationErrors errors) {
+		//Check that the default pricelist name is not in use in the children
+		for(PriceListChild pl : childPriceLists) {
+			if(pl.getName().equals(DEFAULT_PRICELIST_NAME)){
+				errors.add(new ValidationError("Pricelists cannot use the reserved name '" + DEFAULT_PRICELIST_NAME + "'", root.getCatalogURI(), PriceListSet.class, pl.getName()));
+			}
+		}
+		return errors;
+	}
+	
+}
diff --git a/catalog/src/main/java/com/ning/billing/catalog/Product.java b/catalog/src/main/java/com/ning/billing/catalog/Product.java
index 310837c..176b8d4 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/Product.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/Product.java
@@ -16,6 +16,8 @@
 
 package com.ning.billing.catalog;
 
+import java.net.URI;
+
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
@@ -26,9 +28,11 @@ import javax.xml.bind.annotation.XmlIDREF;
 
 import com.ning.billing.catalog.api.IProduct;
 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 Product extends ValidatingConfig implements IProduct {
+public class Product extends ValidatingConfig<Catalog> implements IProduct {
 	
 	@XmlAttribute (required=true)
 	@XmlID
@@ -114,7 +118,7 @@ public class Product extends ValidatingConfig implements IProduct {
 	}
 	
 	@Override
-	public void initialize(Catalog catalog) {
+	public void initialize(Catalog catalog, URI sourceURI) {
 		catalogName = catalog.getCalalogName();
 	}
 
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 055ccd7..676123b 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
@@ -15,6 +15,7 @@
  */
 package com.ning.billing.catalog;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -27,14 +28,18 @@ import com.ning.billing.catalog.api.BillingAlignment;
 import com.ning.billing.catalog.api.BillingPeriod;
 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.IPriceList;
 import com.ning.billing.catalog.api.IProduct;
 import com.ning.billing.catalog.api.PlanAlignmentChange;
 import com.ning.billing.catalog.api.PlanAlignmentCreate;
 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 implements ICatalog {
+public class VersionedCatalog extends ValidatingConfig<Catalog> implements ICatalog {
 	
 	private Catalog currentCatalog;
 	
@@ -89,17 +94,17 @@ public class VersionedCatalog extends ValidatingConfig implements ICatalog {
 	}
 
 	@Override
-	public PriceList[] getPriceLists() {
+	public PriceListSet getPriceLists() {
 		return currentCatalog.getPriceLists();
 	}
 
 	@Override
-	public PriceList getPriceListFromName(String planSetName) {
+	public IPriceList getPriceListFromName(String planSetName) {
 		return currentCatalog.getPriceListFromName(planSetName);
 	}
 
 	@Override
-	public Plan getPlan(String productName, BillingPeriod term,
+	public IPlan getPlan(String productName, BillingPeriod term,
 			String planSetName) {
 		return currentCatalog.getPlan(productName, term, planSetName);
 	}
@@ -131,16 +136,16 @@ public class VersionedCatalog extends ValidatingConfig implements ICatalog {
 	}
 
 	@Override
-	public void initialize(Catalog catalog) {
+	public void initialize(Catalog catalog, URI sourceURI) {
 		for(Catalog c : versions) {
-			c.initialize(catalog);
+			c.initialize(catalog, sourceURI);
 		}
 	}
 
 	@Override
 	public ValidationErrors validate(Catalog catalog, ValidationErrors errors) {
 		for(Catalog c : versions) {
-			errors.addAll(c.validate());
+			errors.addAll(c.validate(c, errors));
 		}
 		return errors;
 	}
diff --git a/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java b/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java
new file mode 100644
index 0000000..39b10f7
--- /dev/null
+++ b/catalog/src/test/java/com/ning/billing/catalog/CreateCatalogSchema.java
@@ -0,0 +1,42 @@
+/*
+ * 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.catalog;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+
+import com.ning.billing.util.config.XMLSchemaGenerator;
+
+public class CreateCatalogSchema {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) throws Exception {
+		if(args.length != 1) {
+			System.err.println("Usage: <filepath>");
+		}
+		
+		File f = new File(args[0]);
+		Writer w = new FileWriter(f);
+		w.write(XMLSchemaGenerator.xmlSchemaAsString(Catalog.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 e858b82..0035bc8 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
@@ -20,6 +20,7 @@ import static org.testng.AssertJUnit.assertTrue;
 
 import java.io.IOException;
 import java.net.MalformedURLException;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Iterator;
 import java.util.List;
@@ -126,7 +127,7 @@ public class TestVersionedCatalogLoader {
 	}
 	
 	@Test(enabled=true)
-	public void testLoad() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException {
+	public void testLoad() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
 		VersionedCatalog c = loader.load(Resources.getResource("versionedCatalog"));
 		assertEquals(4, c.size());
 		Iterator<Catalog> it = c.iterator();
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 1d08c31..a75cb06 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
@@ -17,6 +17,7 @@
 package com.ning.billing.catalog.io;
 
 import java.io.IOException;
+import java.net.URISyntaxException;
 
 import javax.xml.bind.JAXBException;
 import javax.xml.transform.TransformerException;
@@ -25,14 +26,16 @@ import org.testng.annotations.Test;
 import org.xml.sax.SAXException;
 
 import com.google.common.io.Resources;
-import com.ning.billing.catalog.api.InvalidConfigException;
+import com.ning.billing.catalog.Catalog;
+import com.ning.billing.catalog.api.InvalidConfigException; 
+import com.ning.billing.util.config.XMLLoader;
 
 public class TestXMLReader {
 
 	@Test(enabled=true)
-	public void testCatalogLoad() throws IOException, TransformerException, JAXBException, SAXException, InvalidConfigException {
-		XMLReader.getCatalogFromName(Resources.getResource("WeaponsHire.xml"));
-		XMLReader.getCatalogFromName(Resources.getResource("WeaponsHireSmall.xml"));
+	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);
 	}
 	
 }
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 07a9b79..0122a62 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
@@ -72,13 +72,19 @@ public class MockCatalog extends Catalog {
 
 	public void populatePriceLists() {
 		Plan[] plans = getPlans();
-		PriceList[] priceList = new PriceList[plans.length];
-		for(int i = 0; i < plans.length; i++) {
-			priceList[i] = new PriceList();
-			priceList[i].setName(plans[i].getName()+ "-pl");
-			priceList[i].setPlans(new Plan[]{plans[i]});
+		PriceListSet set = new PriceListSet();
+		
+		set.setDefaultPricelist(new PriceListDefault());
+		set.getDefaultPricelist().setPlans(new Plan[]{plans[0]});
+		
+		PriceListChild[] priceList = new PriceListChild[plans.length - 1];
+		for(int i = 1; i < plans.length; i++) {
+			priceList[i-1] = new PriceListChild();
+			priceList[i-1].setName(plans[i].getName()+ "-pl");
+			priceList[i-1].setPlans(new Plan[]{plans[i]});
 		}
-		setPriceLists(priceList);
+		set.setChildPriceLists(priceList);
+		setPriceLists(set);
 	}
 	
 	public String[] getProductNames() {
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestCase.java b/catalog/src/test/java/com/ning/billing/catalog/TestCase.java
index 5848c57..5db84d1 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestCase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestCase.java
@@ -53,7 +53,7 @@ public class TestCase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -75,7 +75,7 @@ public class TestCase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -98,7 +98,7 @@ public class TestCase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -121,7 +121,7 @@ public class TestCase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -144,7 +144,7 @@ public class TestCase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestCaseChange.java b/catalog/src/test/java/com/ning/billing/catalog/TestCaseChange.java
index ed48ccf..cc92fad 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestCaseChange.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestCaseChange.java
@@ -64,10 +64,10 @@ public class TestCaseChange {
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceLists()[0];
+		PriceList priceList1 = cat.getPriceLists().getDefaultPricelist();
 
 		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists()[2];
+		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -154,10 +154,10 @@ public class TestCaseChange {
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceLists()[0];
+		PriceList priceList1 = cat.getPriceLists().getDefaultPricelist();
 
 		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists()[2];
+		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -237,10 +237,10 @@ public class TestCaseChange {
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceLists()[0];
+		PriceList priceList1 = cat.getPriceLists().getDefaultPricelist();
 
 		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists()[2];
+		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -327,10 +327,10 @@ public class TestCaseChange {
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceLists()[0];
+		PriceList priceList1 = cat.getPriceLists().getDefaultPricelist();
 
 		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists()[2];
+		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -417,10 +417,10 @@ public class TestCaseChange {
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceLists()[0];
+		PriceList priceList1 = cat.getPriceLists().getDefaultPricelist();
 
 		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists()[2];
+		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -507,10 +507,10 @@ public class TestCaseChange {
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceLists()[0];
+		PriceList priceList1 = cat.getPriceLists().getDefaultPricelist();
 
 		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists()[2];
+		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -598,10 +598,10 @@ public class TestCaseChange {
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceLists()[0];
+		PriceList priceList1 = cat.getPriceLists().getDefaultPricelist();
 
 		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists()[2];
+		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -688,10 +688,10 @@ public class TestCaseChange {
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceLists()[0];
+		PriceList priceList1 = cat.getPriceLists().getDefaultPricelist();
 
 		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists()[2];
+		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -778,10 +778,10 @@ public class TestCaseChange {
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceLists()[0];
+		PriceList priceList1 = cat.getPriceLists().getDefaultPricelist();
 
 		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists()[2];
+		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
@@ -868,10 +868,10 @@ public class TestCaseChange {
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
-		PriceList priceList1 = cat.getPriceLists()[0];
+		PriceList priceList1 = cat.getPriceLists().getDefaultPricelist();
 
 		Product product2 = cat.getProducts()[2];
-		PriceList priceList2 = cat.getPriceLists()[2];
+		PriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
 
 		CaseChangeResult cr = new CaseChangeResult(
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestCasePhase.java b/catalog/src/test/java/com/ning/billing/catalog/TestCasePhase.java
index 9d3f7cc..ea8e916 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestCasePhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestCasePhase.java
@@ -54,7 +54,7 @@ public class TestCasePhase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -78,7 +78,7 @@ public class TestCasePhase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -102,7 +102,7 @@ public class TestCasePhase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -126,7 +126,7 @@ public class TestCasePhase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -150,7 +150,7 @@ public class TestCasePhase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
@@ -174,7 +174,7 @@ public class TestCasePhase {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
-		PriceList priceList = cat.getPriceLists()[0];
+		PriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
 
 		CaseResult cr = new CaseResult(
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestPlanRules.java b/catalog/src/test/java/com/ning/billing/catalog/TestPlanRules.java
index 6121a85..4b44163 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestPlanRules.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestPlanRules.java
@@ -66,8 +66,8 @@ public class TestPlanRules {
 	}
 	
 
-	protected PriceList createPriceList(String name) {
-		PriceList result = new PriceList();
+	protected PriceListChild createPriceList(String name) {
+		PriceListChild result = new PriceListChild();
 		result.setName(name);
 		return result;
 	}
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 ee4d094..4515af1 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
@@ -19,6 +19,7 @@ import static org.testng.AssertJUnit.assertEquals;
 
 import java.io.IOException;
 import java.net.MalformedURLException;
+import java.net.URISyntaxException;
 import java.util.Date;
 
 import javax.xml.bind.JAXBException;
@@ -30,21 +31,20 @@ import org.xml.sax.SAXException;
 
 import com.google.common.io.Resources;
 import com.ning.billing.catalog.api.InvalidConfigException;
-import com.ning.billing.catalog.io.ICatalogLoader;
 import com.ning.billing.catalog.io.VersionedCatalogLoader;
 
 public class TestVersionedCatalog {
-	private final ICatalogLoader loader = new VersionedCatalogLoader();
+	private final VersionedCatalogLoader loader = new VersionedCatalogLoader();
 
 	@Test(enabled=true)
-	public void testAddCatalog() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException {
+	public void testAddCatalog() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
 		VersionedCatalog vc = loader.load(Resources.getResource("versionedCatalog"));
 		vc.add(new Catalog(new Date()));
 		assertEquals(5, vc.size());
 	}
 	
 	@Test(enabled=true)
-	public void testApplyEffectiveDate() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException {
+	public void testApplyEffectiveDate() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
 		VersionedCatalog vc = loader.load(Resources.getResource("versionedCatalog"));
 		Date d = new Date(1L);
 		vc.configureEffectiveDate(d);
diff --git a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-1.xml b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-1.xml
index 51e68dc..ccba4c0 100644
--- a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-1.xml
+++ b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-1.xml
@@ -16,7 +16,7 @@
   -->
 
 <catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:noNamespaceSchemaLocation="../../../main/resources/CatalogSchema.xsd ">
+	xsi:noNamespaceSchemaLocation="../CatalogSchema.xsd ">
 
 	<effectiveDate>2011-01-01T00:00:00+00:00</effectiveDate>
 	<catalogName>WeaponsHireSmall</catalogName>
@@ -153,13 +153,12 @@
 		</plan>
 	</plans>
 	<priceLists>
-		<priceList name="standardBase"> 
-			<isDefault>true</isDefault>			
+		<defaultPriceList>			
 				<plans>	
 				<plan>pistol-monthly</plan>
 				<plan>shotgun-monthly</plan>
 				<plan>shotgun-annual</plan>
 			</plans>
-		</priceList>
+		</defaultPriceList>
 	</priceLists>
 </catalog>
diff --git a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-2.xml b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-2.xml
index 3ad25f3..e97d5ba 100644
--- a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-2.xml
+++ b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-2.xml
@@ -153,13 +153,12 @@
 		</plan>
 	</plans>
 	<priceLists>
-		<priceList name="standardBase"> 
-			<isDefault>true</isDefault>			
+		<defaultPriceList>			
 				<plans>	
 				<plan>pistol-monthly</plan>
 				<plan>shotgun-monthly</plan>
 				<plan>shotgun-annual</plan>
 			</plans>
-		</priceList>
+		</defaultPriceList>
 	</priceLists>
 </catalog>
diff --git a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-3.xml b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-3.xml
index 20ca041..568ec5e 100644
--- a/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-3.xml
+++ b/catalog/src/test/resources/versionedCatalog/WeaponsHireSmall-3.xml
@@ -153,13 +153,12 @@
 		</plan>
 	</plans>
 	<priceLists>
-		<priceList name="standardBase"> 
-			<isDefault>true</isDefault>			
+		<defaultPriceList>			
 				<plans>	
 				<plan>pistol-monthly</plan>
 				<plan>shotgun-monthly</plan>
 				<plan>shotgun-annual</plan>
 			</plans>
-		</priceList>
+		</defaultPriceList>
 	</priceLists>
 </catalog>
diff --git a/catalog/src/test/resources/WeaponsHire.xml b/catalog/src/test/resources/WeaponsHire.xml
index a3f4e0b..e9c041b 100644
--- a/catalog/src/test/resources/WeaponsHire.xml
+++ b/catalog/src/test/resources/WeaponsHire.xml
@@ -37,7 +37,7 @@ Use Cases to do:
 
  -->
 <catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:noNamespaceSchemaLocation="../../main/resources/CatalogSchema.xsd ">
+	xsi:noNamespaceSchemaLocation="CatalogSchema.xsd ">
 
 	<effectiveDate>2011-10-08T00:00:00+00:00</effectiveDate>
 	<catalogName>Firearms</catalogName>
@@ -549,8 +549,7 @@ Use Cases to do:
 		</plan>
 	</plans>
 	<priceLists>
-		<priceList name="standard">
-			<isDefault>true</isDefault>
+		<defaultPriceList> 
 			<plans>
 				<plan>pistol-monthly</plan>
 				<plan>shotgun-monthly</plan>
@@ -564,8 +563,8 @@ Use Cases to do:
 				<plan>holster-monthly-regular</plan>
 				<plan>refurbish-maintenance</plan>
 			</plans>
-		</priceList>
-		<priceList name="gunclubDiscount">
+		</defaultPriceList>
+		<childPriceList name="gunclubDiscount">
 			<plans>
 				<plan>pistol-monthly</plan>
 				<plan>shotgun-monthly</plan>
@@ -575,12 +574,12 @@ Use Cases to do:
 				<plan>assault-rifle-annual-gunclub-discount</plan>
 				<plan>holster-monthly-special</plan>
 			</plans>
-		</priceList>
-		<priceList name="rescue">
+		</childPriceList>
+		<childPriceList name="rescue">
 			<plans>
 				<plan>assault-rifle-annual-rescue</plan>
 			</plans>
-		</priceList>
+		</childPriceList>
 	</priceLists>
 
 </catalog>
diff --git a/catalog/src/test/resources/WeaponsHireSmall.xml b/catalog/src/test/resources/WeaponsHireSmall.xml
index a40f4c7..c6b25da 100644
--- a/catalog/src/test/resources/WeaponsHireSmall.xml
+++ b/catalog/src/test/resources/WeaponsHireSmall.xml
@@ -16,7 +16,7 @@
   -->
 
 <catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:noNamespaceSchemaLocation="../../main/resources/CatalogSchema.xsd ">
+	xsi:noNamespaceSchemaLocation="CatalogSchema.xsd ">
 
 	<effectiveDate>2011-10-08T00:00:00+00:00</effectiveDate>
 	<catalogName>WeaponsHireSmall</catalogName>
@@ -153,13 +153,12 @@
 		</plan>
 	</plans>
 	<priceLists>
-		<priceList name="standardBase"> 
-			<isDefault>true</isDefault>			
+		<defaultPriceList>
 				<plans>	
-				<plan>pistol-monthly</plan>
-				<plan>shotgun-monthly</plan>
+					<plan>pistol-monthly</plan>
+					<plan>shotgun-monthly</plan>
 				<plan>shotgun-annual</plan>
 			</plans>
-		</priceList>
+		</defaultPriceList>
 	</priceLists>
 </catalog>
diff --git a/entitlement/pom.xml b/entitlement/pom.xml
index 563eeb9..d4e6ed5 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.6-SNAPSHOT</version>
+        <version>0.0.10-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-entitlement</artifactId>
@@ -48,6 +48,7 @@
         <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-catalog</artifactId>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>com.ning.billing</groupId>
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 7856dab..0d9ac8d 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
@@ -21,7 +21,9 @@ import java.util.List;
 
 import org.joda.time.DateTime;
 
+import com.google.inject.Inject;
 import com.ning.billing.catalog.api.ICatalog;
+import com.ning.billing.catalog.api.ICatalogService;
 import com.ning.billing.catalog.api.IDuration;
 import com.ning.billing.catalog.api.IPlan;
 import com.ning.billing.catalog.api.IPlanPhase;
@@ -35,16 +37,13 @@ import com.ning.billing.util.clock.Clock;
 
 public class PlanAligner implements IPlanAligner {
 
-    // STEPH this is a bit broken right now until we figure out to retrieve ICatalog
-    private /*final*/ ICatalog catalog;
+    private final ICatalogService catalogService;
 
-    public PlanAligner() {
-        //this.catalog = Engine.getInstance().getCatalog();
+    @Inject
+    public PlanAligner(ICatalogService catalogService) {
+        this.catalogService = catalogService;
     }
 
-    public void init(ICatalog catalog) {
-        this.catalog = catalog;
-    }
 
     private enum WhichPhase {
         CURRENT,
@@ -87,6 +86,8 @@ public class PlanAligner implements IPlanAligner {
     private TimedPhase getTimedPhaseOnCreate(Subscription subscription,
             IPlan plan, String priceList, DateTime effectiveDate, WhichPhase which) {
 
+        ICatalog catalog = catalogService.getCatalog();
+
             PlanSpecifier planSpecifier = new PlanSpecifier(plan.getProduct().getName(),
                     plan.getProduct().getCategory(),
                     plan.getBillingPeriod(),
@@ -111,6 +112,8 @@ public class PlanAligner implements IPlanAligner {
     private TimedPhase getTimedPhaseOnChange(Subscription subscription,
             IPlan plan, String priceList, DateTime effectiveDate, WhichPhase which) {
 
+        ICatalog catalog = catalogService.getCatalog();
+
         IPlanPhase currentPhase = subscription.getCurrentPhase();
         IPlan currentPlan = subscription.getCurrentPlan();
         String currentPriceList = subscription.getCurrentPriceList();
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/BillingApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/BillingApi.java
index 5777cba..a1528ce 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/BillingApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/billing/BillingApi.java
@@ -38,7 +38,6 @@ public class BillingApi implements IEntitlementBillingApi {
     private final IClock clock;
     private final IEntitlementDao dao;
 
-    @Inject
     public BillingApi(Engine engine, IClock clock, IEntitlementDao dao) {
         super();
         this.engine = engine;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
index e664566..8561ce0 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/EntitlementUserApi.java
@@ -22,7 +22,6 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.IAccount;
 import com.ning.billing.catalog.api.BillingPeriod;
@@ -42,6 +41,7 @@ import com.ning.billing.entitlement.events.phase.IPhaseEvent;
 import com.ning.billing.entitlement.events.phase.PhaseEvent;
 import com.ning.billing.entitlement.events.user.ApiEventCreate;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.entitlement.glue.InjectorMagic;
 import com.ning.billing.util.clock.IClock;
 
 public class EntitlementUserApi implements IEntitlementUserApi {
@@ -51,21 +51,27 @@ public class EntitlementUserApi implements IEntitlementUserApi {
     private final IEntitlementDao dao;
     private final IPlanAligner planAligner;
 
+    private boolean initialized;
+
     private ICatalog catalog;
-    @Inject
+
     public EntitlementUserApi(Engine engine, IClock clock, IPlanAligner planAligner, IEntitlementDao dao) {
         super();
         this.engine = engine;
         this.clock = clock;
         this.dao = dao;
         this.planAligner = planAligner;
+        this.initialized = false;
 
     }
 
     @Override
-    public void initialize(List<IApiListener> listeners) {
-        this.catalog = engine.getCatalog();
-        engine.registerApiObservers(listeners);
+    public synchronized void initialize(List<IApiListener> listeners) {
+        if (!initialized) {
+            this.catalog = InjectorMagic.getCatlog();
+            engine.registerApiObservers(listeners);
+            initialized = true;
+        }
     }
 
     @Override
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
index 6e07f7c..a5cd11e 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/Subscription.java
@@ -49,6 +49,7 @@ import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.ApiEventUncancel;
 import com.ning.billing.entitlement.events.user.IUserEvent;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
+import com.ning.billing.entitlement.glue.InjectorMagic;
 import com.ning.billing.util.clock.IClock;
 
 public class Subscription extends PrivateFields  implements ISubscription {
@@ -146,12 +147,10 @@ public class Subscription extends PrivateFields  implements ISubscription {
     public Subscription(UUID id, UUID bundleId, ProductCategory category, DateTime bundleStartDate, DateTime startDate, DateTime ctd, DateTime ptd, long activeVersion) {
 
         super();
-
-        Engine engine = Engine.getInstance();
-        this.clock = engine.getClock();
-        this.dao = engine.getDao();
-        this.catalog = engine.getCatalog();
-        this.planAligner = engine.getPlanAligner();
+        this.clock = InjectorMagic.getClock();
+        this.dao = InjectorMagic.getEntitlementDao();
+        this.catalog = InjectorMagic.getCatlog();
+        this.planAligner = InjectorMagic.getPlanAligner();
         this.id = id;
         this.bundleId = bundleId;
         this.startDate = startDate;
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessor.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessor.java
index 437f21c..9389969 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessor.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/ApiEventProcessor.java
@@ -19,9 +19,9 @@ package com.ning.billing.entitlement.engine.core;
 import java.util.List;
 
 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.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
 public class ApiEventProcessor extends ApiEventProcessorBase {
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 b83b0be..cf20530 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
@@ -29,9 +29,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 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.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
 public abstract class ApiEventProcessorBase implements IApiEventProcessor {
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 d0e1b02..dd33ae5 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,7 +17,6 @@
 package com.ning.billing.entitlement.engine.core;
 
 import java.util.List;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
@@ -25,73 +24,89 @@ import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
 import com.ning.billing.catalog.api.ICatalog;
-import com.ning.billing.catalog.api.ICatalogUserApi;
-import com.ning.billing.catalog.api.IPlan;
+import com.ning.billing.catalog.api.ICatalogService;
+import com.ning.billing.config.IEntitlementConfig;
 
-import com.ning.billing.entitlement.IEntitlementSystem;
 import com.ning.billing.entitlement.alignment.IPlanAligner;
 import com.ning.billing.entitlement.alignment.IPlanAligner.TimedPhase;
 import com.ning.billing.entitlement.alignment.PlanAligner;
+import com.ning.billing.entitlement.api.IEntitlementService;
+import com.ning.billing.entitlement.api.billing.BillingApi;
+import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
+import com.ning.billing.entitlement.api.user.EntitlementUserApi;
 import com.ning.billing.entitlement.api.user.IApiListener;
-import com.ning.billing.entitlement.api.user.ISubscription;
+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.events.phase.PhaseEvent;
-import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.IUserEvent;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
+import com.ning.billing.lifecycle.LyfecycleHandlerType;
+import com.ning.billing.lifecycle.LyfecycleHandlerType.LyfecycleLevel;
 import com.ning.billing.util.clock.IClock;
 
-public class Engine implements IEventListener, IEntitlementSystem {
+public class Engine implements IEventListener, IEntitlementService {
+
+    private static final String ENTITLEMENT_SERVICE_NAME = "entitlement-service";
 
     private final static Logger log = LoggerFactory.getLogger(Engine.class);
-    private static Engine instance = null;
 
     private final IClock clock;
-    private final ICatalog catalog;
     private final IEntitlementDao dao;
     private final IApiEventProcessor apiEventProcessor;
-    private final ICatalogUserApi catalogApi;
     private final IPlanAligner planAligner;
-
+    private final IEntitlementUserApi userApi;
+    private final IEntitlementBillingApi billingApi;
     private List<IApiListener> observers;
 
+
     @Inject
-    public Engine(IClock clock, IEntitlementDao dao, IApiEventProcessor apiEventProcessor, ICatalogUserApi catalogApi,
+    public Engine(IClock clock, IEntitlementDao dao, IApiEventProcessor apiEventProcessor,
             IPlanAligner planAligner, IEntitlementConfig config) {
         super();
         this.clock = clock;
-        this.catalogApi = catalogApi;
         this.dao = dao;
         this.apiEventProcessor = apiEventProcessor;
         this.planAligner = planAligner;
-        this.catalog = readCatalogFromConfig(config.getCatalogConfigFileName());
         this.observers = null;
-        instance = this;
-
-        // STEPH yack
-        ((PlanAligner) planAligner).init(catalog);
+        this.userApi = new EntitlementUserApi(this, clock, planAligner, dao);
+        this.billingApi = new BillingApi(this, clock, dao);
     }
 
     @Override
-    public void initialize() {
-        // TODO Auto-generated method stub
+    public String getName() {
+        return ENTITLEMENT_SERVICE_NAME;
+    }
+
 
+    @LyfecycleHandlerType(LyfecycleLevel.INIT_SERVICE)
+    public void initialize() {
     }
 
-    @Override
+    @LyfecycleHandlerType(LyfecycleLevel.START_SERVICE)
     public void start() {
         apiEventProcessor.startNotifications(this);
     }
 
-    @Override
+    @LyfecycleHandlerType(LyfecycleLevel.STOP_SERVICE)
     public void stop() {
         apiEventProcessor.stopNotifications();
     }
 
+    @Override
+    public IEntitlementUserApi getUserApi(List<IApiListener> listeners) {
+        userApi.initialize(listeners);
+        return userApi;
+    }
+
+    @Override
+    public IEntitlementBillingApi getBillingApi() {
+        return billingApi;
+    }
+
+
     public void registerApiObservers(List<IApiListener> observers) {
         this.observers = observers;
     }
@@ -150,36 +165,4 @@ public class Engine implements IEventListener, IEntitlementSystem {
             dao.createNextPhaseEvent(subscription.getId(), nextPhaseEvent);
         }
     }
-
-
-    private ICatalog readCatalogFromConfig(String configFile) {
-        return catalogApi.getCatalog(configFile);
-    }
-
-    //
-    // STEPH would be nice to have those go away..
-    //
-
-    // For non Guice classes
-    public synchronized static Engine getInstance() {
-        return instance;
-    }
-
-    public IClock getClock() {
-        return clock;
-    }
-
-    public ICatalog getCatalog() {
-        return catalog;
-    }
-
-    public IEntitlementDao getDao() {
-        return dao;
-    }
-
-    public IPlanAligner getPlanAligner() {
-        return planAligner;
-    }
-
-
 }
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 8dfc34a..db4e375 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
@@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
 import com.google.common.collect.Lists;
 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.ISubscription;
 import com.ning.billing.entitlement.api.user.ISubscriptionBundle;
 import com.ning.billing.entitlement.api.user.Subscription;
@@ -42,7 +43,6 @@ import com.ning.billing.entitlement.events.IEvent.EventType;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.IUserEvent;
 import com.ning.billing.entitlement.exceptions.EntitlementError;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.Hostname;
 import com.ning.billing.util.clock.IClock;
 
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 fd27374..d303b30 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
@@ -19,15 +19,12 @@ package com.ning.billing.entitlement.glue;
 import org.skife.config.ConfigurationObjectFactory;
 
 import com.google.inject.AbstractModule;
-import com.ning.billing.catalog.CatalogUserApi;
-import com.ning.billing.catalog.api.ICatalogUserApi;
-import com.ning.billing.entitlement.IEntitlementSystem;
+import com.ning.billing.config.IEntitlementConfig;
 import com.ning.billing.entitlement.alignment.IPlanAligner;
 import com.ning.billing.entitlement.alignment.PlanAligner;
-import com.ning.billing.entitlement.api.billing.BillingApi;
-import com.ning.billing.entitlement.api.billing.IEntitlementBillingApi;
-import com.ning.billing.entitlement.api.user.IEntitlementUserApi;
+import com.ning.billing.entitlement.api.IEntitlementService;
 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.engine.core.Engine;
 import com.ning.billing.entitlement.engine.core.IApiEventProcessor;
@@ -40,13 +37,6 @@ import com.ning.billing.util.clock.IClock;
 
 public class EntitlementModule extends AbstractModule {
 
-    protected void installCatalog() {
-        bind(ICatalogUserApi.class).to(CatalogUserApi.class).asEagerSingleton();
-    }
-
-    protected void installAccount() {
-//        bind(IAccount.class).to(CatalogUserApi.class);
-    }
 
     protected void installClock() {
         bind(IClock.class).to(Clock.class).asEagerSingleton();
@@ -66,29 +56,22 @@ public class EntitlementModule extends AbstractModule {
     }
 
     protected void installEntitlementCore() {
-        bind(IEntitlementSystem.class).to(Engine.class).asEagerSingleton();
+        bind(IEntitlementService.class).to(Engine.class).asEagerSingleton();
         bind(Engine.class).asEagerSingleton();
         bind(IPlanAligner.class).to(PlanAligner.class).asEagerSingleton();
     }
 
-    protected void installUserApi() {
-        bind(IEntitlementUserApi.class).to(EntitlementUserApi.class).asEagerSingleton();
-    }
-
-    protected void installBillingApi() {
-        bind(IEntitlementBillingApi.class).to(BillingApi.class).asEagerSingleton();
+    protected void installInjectorMagic() {
+        bind(InjectorMagic.class).asEagerSingleton();
     }
 
-
     @Override
     protected void configure() {
+        installInjectorMagic();
         installConfig();
         installClock();
-        installCatalog();
         installApiEventProcessor();
         installEntitlementDao();
         installEntitlementCore();
-        installUserApi();
-        installBillingApi();
     }
 }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/glue/InjectorMagic.java b/entitlement/src/main/java/com/ning/billing/entitlement/glue/InjectorMagic.java
new file mode 100644
index 0000000..8e845da
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/glue/InjectorMagic.java
@@ -0,0 +1,76 @@
+/*
+ * 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.glue;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.ning.billing.catalog.api.ICatalog;
+import com.ning.billing.catalog.api.ICatalogService;
+import com.ning.billing.entitlement.alignment.IPlanAligner;
+import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
+import com.ning.billing.util.clock.IClock;
+
+//
+// Allows to return Guice injected singleton in a non guice context
+//
+public class InjectorMagic {
+
+    // public void testng only
+    public static InjectorMagic instance;
+
+    private final Injector injector;
+
+    @Inject
+    public InjectorMagic(Injector injector) {
+        this.injector = injector;
+        synchronized(InjectorMagic.class) {
+            if (instance == null) {
+                instance = this;
+            }
+        }
+    }
+
+
+    public static IClock getClock() {
+        return InjectorMagic.get().getInstance(IClock.class);
+    }
+
+    public static ICatalog getCatlog() {
+        ICatalogService catalogService = InjectorMagic.get().getInstance(ICatalogService.class);
+        return catalogService.getCatalog();
+    }
+
+    public static IEntitlementDao getEntitlementDao() {
+        return InjectorMagic.get().getInstance(IEntitlementDao.class);
+    }
+
+    public static IPlanAligner getPlanAligner() {
+        return InjectorMagic.get().getInstance(IPlanAligner.class);
+    }
+
+
+    public static Injector get() {
+        if (instance == null) {
+            throw new RuntimeException("Trying to retrieve injector too early");
+        }
+        return instance.getInjector();
+    }
+
+    private Injector getInjector() {
+        return injector;
+    }
+}
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 0f9806d..4c2ae2b 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
@@ -36,21 +36,26 @@ import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
+import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.BeforeTest;
 
 import com.google.inject.Injector;
 import com.ning.billing.account.api.IAccount;
+import com.ning.billing.catalog.CatalogService;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.ICatalog;
-import com.ning.billing.catalog.api.ICatalogUserApi;
+import com.ning.billing.catalog.api.ICatalogService;
 import com.ning.billing.catalog.api.IDuration;
 import com.ning.billing.catalog.api.TimeUnit;
-import com.ning.billing.entitlement.IEntitlementSystem;
+import com.ning.billing.config.IEntitlementConfig;
 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.engine.core.Engine;
 import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
@@ -59,7 +64,8 @@ import com.ning.billing.entitlement.events.IEvent;
 import com.ning.billing.entitlement.events.phase.IPhaseEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.IUserEvent;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
+import com.ning.billing.entitlement.glue.InjectorMagic;
+import com.ning.billing.lifecycle.IService.ServiceException;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.clock.IClock;
 
@@ -69,11 +75,10 @@ public abstract class TestUserApiBase {
 
     protected static final long DAY_IN_MS = (24 * 3600 * 1000);
 
-    protected IEntitlementSystem service;
-    protected Engine engine;
+    protected IEntitlementService entitlementService;
     protected IEntitlementUserApi entitlementApi;
     protected IEntitlementBillingApi billingApi;
-    protected ICatalogUserApi catalogApi;
+    protected ICatalogService catalogService;
     protected IEntitlementConfig config;
     protected IEntitlementDao dao;
     protected ClockMock clock;
@@ -83,6 +88,7 @@ public abstract class TestUserApiBase {
     protected ApiTestListener testListener;
     protected ISubscriptionBundle bundle;
 
+    private InjectorMagic injectorMagic;
 
     public static void loadSystemPropertiesFromClasspath( final String resource )
     {
@@ -96,34 +102,34 @@ public abstract class TestUserApiBase {
         }
     }
 
+    @AfterClass(groups={"setup"})
+    public void tearDown() {
+        InjectorMagic.instance = null;
+    }
 
     @BeforeClass(groups={"setup"})
     public void setup() {
 
-        // Does not see to work ...
-        /*
-        TimeZone tz  = TimeZone.getDefault();
-        TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));
-        tz  = TimeZone.getDefault();
-         */
-
         loadSystemPropertiesFromClasspath("/entitlement.properties");
         final Injector g = getInjector();
 
-        service = g.getInstance(IEntitlementSystem.class);
-        engine = g.getInstance(Engine.class);
-        entitlementApi = g.getInstance(IEntitlementUserApi.class);
-        catalogApi = g.getInstance(ICatalogUserApi.class);
-        billingApi = g.getInstance(IEntitlementBillingApi.class);
+        injectorMagic = g.getInstance(InjectorMagic.class);
+
+
+        entitlementService = g.getInstance(IEntitlementService.class);
+        catalogService = g.getInstance(ICatalogService.class);
         config = g.getInstance(IEntitlementConfig.class);
         dao = g.getInstance(IEntitlementDao.class);
         clock = (ClockMock) g.getInstance(IClock.class);
         try {
 
-            service.initialize();
+            ((CatalogService) catalogService).loadCatalog();
+            ((Engine)entitlementService).initialize();
             init();
         } catch (EntitlementUserApiException e) {
             Assert.fail(e.getMessage());
+        } catch (ServiceException e) {
+            Assert.fail(e.getMessage());
         }
     }
 
@@ -133,18 +139,20 @@ public abstract class TestUserApiBase {
         account = getAccount();
         assertNotNull(account);
 
-        catalog = catalogApi.getCatalog(config.getCatalogConfigFileName());
+        catalog = catalogService.getCatalog();
         assertNotNull(catalog);
 
         testListener = new ApiTestListener();
         List<IApiListener> listeners =  new ArrayList<IApiListener>();
         listeners.add(testListener);
-        entitlementApi.initialize(listeners);
+        entitlementApi = entitlementService.getUserApi(listeners);
+        billingApi = entitlementService.getBillingApi();
 
     }
 
     @BeforeMethod(groups={"setup"})
     public void setupTest() {
+
         log.warn("\n");
         log.warn("RESET TEST FRAMEWORK\n\n");
 
@@ -157,12 +165,15 @@ public abstract class TestUserApiBase {
             Assert.fail(e.getMessage());
         }
         assertNotNull(bundle);
-        service.start();
+
+        ((Engine)entitlementService).start();
     }
 
     @AfterMethod(groups={"setup"})
     public void cleanupTest() {
-        service.stop();
+
+
+        ((Engine)entitlementService).stop();
         log.warn("DONE WITH TEST\n");
     }
 
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 38c55f2..24468fe 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
@@ -30,6 +30,7 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+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.IPlan;
@@ -43,7 +44,7 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
     protected void testCancelSubscriptionIMMReal() {
 
-        log.info("Starting testChangeSubscriptionEOTWithNoChargeThroughDate");
+        log.info("Starting testCancelSubscriptionIMM");
 
         try {
 
@@ -51,7 +52,7 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
             String prod = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = "standard";
+            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
             Subscription subscription = createSubscription(prod, term, planSet);
@@ -90,7 +91,7 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
             String prod = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = "standard";
+            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
             Subscription subscription = createSubscription(prod, term, planSet);
@@ -143,7 +144,7 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
             String prod = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = "standard";
+            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
             Subscription subscription = createSubscription(prod, term, planSet);
@@ -187,7 +188,7 @@ public abstract class TestUserApiCancel extends TestUserApiBase {
 
             String prod = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSet = "standard";
+            String planSet = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             // CREATE
             Subscription subscription = createSubscription(prod, term, planSet);
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 05fe153..00c2bab 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,12 +16,12 @@
 
 package com.ning.billing.entitlement.api.user;
 
-import org.testng.annotations.BeforeMethod;
 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;
 
 public class TestUserApiCancelMemory extends TestUserApiCancel {
@@ -29,7 +29,7 @@ public class TestUserApiCancelMemory extends TestUserApiCancel {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock());
+        return Guice.createInjector(Stage.PRODUCTION, new EngineModuleMemoryMock(), new CatalogModuleMock());
     }
 
     @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 84f11e2..58e8891 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
@@ -21,6 +21,7 @@ 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;
 
 public class TestUserApiCancelSql extends TestUserApiCancel {
@@ -30,7 +31,7 @@ public class TestUserApiCancelSql extends TestUserApiCancel {
 
     @Override
     public Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock(), new CatalogModuleMock());
     }
 
     @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 8816503..f187d9f 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
@@ -31,6 +31,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.ning.billing.account.api.IAccount;
+import com.ning.billing.catalog.PriceListSet;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ICatalog;
 import com.ning.billing.catalog.api.IDuration;
@@ -66,14 +67,14 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
 
     protected void testChangePlanBundleAlignEOTWithNoChargeThroughDateReal() {
-        tChangePlanBundleAlignEOTWithNoChargeThroughDate("Shotgun", BillingPeriod.MONTHLY, "standard", "Pistol", BillingPeriod.MONTHLY, "standard");
+        tChangePlanBundleAlignEOTWithNoChargeThroughDate("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, "Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
     }
 
 
     private void tChangePlanBundleAlignEOTWithNoChargeThroughDate(String fromProd, BillingPeriod fromTerm, String fromPlanSet,
         String toProd, BillingPeriod toTerm, String toPlanSet) {
 
-        log.info("Starting testChangeSubscriptionEOTWithNoChargeThroughDate");
+        log.info("Starting testChangePlanBundleAlignEOTWithNoChargeThroughDateReal");
 
         try {
 
@@ -170,7 +171,7 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
 
     protected void testChangePlanBundleAlignIMMReal() {
-        tChangePlanBundleAlignIMM("Shotgun", BillingPeriod.MONTHLY, "standard", "Assault-Rifle", BillingPeriod.MONTHLY, "standard");
+        tChangePlanBundleAlignIMM("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, "Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
     }
 
 
@@ -212,7 +213,7 @@ public abstract class TestUserApiChangePlan extends TestUserApiBase {
 
 
     protected void testChangePlanChangePlanAlignEOTWithChargeThroughDateReal() {
-        tChangePlanChangePlanAlignEOTWithChargeThroughDate("Shotgun", BillingPeriod.ANNUAL, "standard", "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,
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 56c1a74..4455436 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
@@ -21,13 +21,14 @@ 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;
 
 public class TestUserApiChangePlanMemory extends TestUserApiChangePlan {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock());
+        return Guice.createInjector(Stage.PRODUCTION, new EngineModuleMemoryMock(), new CatalogModuleMock());
     }
 
 
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 30ace87..174b85e 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
@@ -21,6 +21,7 @@ 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;
 
 public class TestUserApiChangePlanSql extends TestUserApiChangePlan {
@@ -29,7 +30,7 @@ public class TestUserApiChangePlanSql extends TestUserApiChangePlan {
 
     @Override
     public Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock(), new CatalogModuleMock());
     }
 
     @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 44c126c..c8eac1f 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
@@ -28,6 +28,7 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import com.ning.billing.catalog.PriceListSet;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.IPlan;
 import com.ning.billing.catalog.api.IPlanPhase;
@@ -51,7 +52,7 @@ public abstract class TestUserApiCreate extends TestUserApiBase {
 
             String productName = "Shotgun";
             BillingPeriod term = BillingPeriod.MONTHLY;
-            String planSetName = "standard";
+            String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
@@ -163,7 +164,7 @@ public abstract class TestUserApiCreate extends TestUserApiBase {
 
             String productName = "Shotgun";
             BillingPeriod term = BillingPeriod.ANNUAL;
-            String planSetName = "standard";
+            String planSetName = PriceListSet.DEFAULT_PRICELIST_NAME;
 
             testListener.pushExpectedEvent(NextEvent.CREATE);
 
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 8ec02d7..429652c 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
@@ -21,6 +21,7 @@ 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;
 
 public class TestUserApiCreateMemory extends TestUserApiCreate {
@@ -28,7 +29,7 @@ public class TestUserApiCreateMemory extends TestUserApiCreate {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleMemoryMock());
+        return Guice.createInjector(Stage.PRODUCTION, new EngineModuleMemoryMock(), new CatalogModuleMock());
     }
 
     @Test(enabled=true, groups={"fast"})
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 58fa52b..328976f 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
@@ -21,13 +21,14 @@ 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;
 
 public class TestUserApiCreateSql extends TestUserApiCreate {
 
     @Override
     protected Injector getInjector() {
-        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock());
+        return Guice.createInjector(Stage.DEVELOPMENT, new EngineModuleSqlMock(), new CatalogModuleMock());
     }
 
     @Test(enabled=true, groups={"sql"})
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 8f22f83..1e6f454 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
@@ -17,12 +17,8 @@
 package com.ning.billing.entitlement.api.user;
 
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.assertFalse;
 
-
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -33,6 +29,7 @@ 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;
@@ -61,10 +58,10 @@ public class TestUserApiError extends TestUserApiBase {
     @Test(enabled=true)
     public void testCreateSubscriptionBadCatalog() {
         // WRONG PRODUTCS
-        tCreateSubscriptionInternal(bundle.getId(), null, BillingPeriod.ANNUAL, "standard", ErrorCode.ENT_CREATE_BAD_CATALOG);
-        tCreateSubscriptionInternal(bundle.getId(), "Whatever", BillingPeriod.ANNUAL, "standard", ErrorCode.ENT_CREATE_BAD_CATALOG);
+        tCreateSubscriptionInternal(bundle.getId(), null, BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_BAD_CATALOG);
+        tCreateSubscriptionInternal(bundle.getId(), "Whatever", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_BAD_CATALOG);
         // WRONG BILLING PERIOD
-        tCreateSubscriptionInternal(bundle.getId(), "Shotgun", null, "standard", ErrorCode.ENT_CREATE_BAD_CATALOG);
+        tCreateSubscriptionInternal(bundle.getId(), "Shotgun", null, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_BAD_CATALOG);
         // 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);
@@ -73,19 +70,19 @@ public class TestUserApiError extends TestUserApiBase {
 
     @Test(enabled=true)
     public void testCreateSubscriptionNoBundle() {
-        tCreateSubscriptionInternal(null, "Shotgun", BillingPeriod.ANNUAL, "standard", ErrorCode.ENT_CREATE_NO_BUNDLE);
+        tCreateSubscriptionInternal(null, "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_NO_BUNDLE);
     }
 
     @Test(enabled=false)
     public void testCreateSubscriptionNoBP() {
-        //tCreateSubscriptionInternal(bundle.getId(), "Shotgun", BillingPeriod.ANNUAL, "standard", ErrorCode.ENT_CREATE_NO_BP);
+        //tCreateSubscriptionInternal(bundle.getId(), "Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, ErrorCode.ENT_CREATE_NO_BP);
     }
 
     @Test(enabled=true)
     public void testCreateSubscriptionBPExists() {
         try {
-            createSubscription("Shotgun", BillingPeriod.ANNUAL, "standard");
-            tCreateSubscriptionInternal(bundle.getId(), "Shotgun", BillingPeriod.ANNUAL, "standard", 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);
@@ -111,12 +108,12 @@ public class TestUserApiError extends TestUserApiBase {
     @Test(enabled=true)
     public void testChangeSubscriptionNonActive() {
         try {
-            ISubscription subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, "standard");
+            ISubscription subscription = createSubscription("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME);
 
             testListener.pushExpectedEvent(NextEvent.CANCEL);
             subscription.cancel();
             try {
-                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, "standard");
+                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
             } catch (EntitlementUserApiException e) {
                 assertEquals(e.getCode(), ErrorCode.ENT_CHANGE_NON_ACTIVE.getCode());
                 try {
@@ -135,7 +132,7 @@ public class TestUserApiError extends TestUserApiBase {
     @Test(enabled=true)
     public void testChangeSubscriptionFutureCancelled() {
         try {
-            ISubscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, "standard");
+            ISubscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
             // SET CTD TO CANCEL IN FUTURE
             IPlanPhase trialPhase = subscription.getCurrentPhase();
@@ -147,7 +144,7 @@ public class TestUserApiError extends TestUserApiBase {
 
             subscription.cancel();
             try {
-                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, "standard");
+                subscription.changePlan("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
             } catch (EntitlementUserApiException e) {
                 assertEquals(e.getCode(), ErrorCode.ENT_CHANGE_FUTURE_CANCELLED.getCode());
                 try {
@@ -170,7 +167,7 @@ public class TestUserApiError extends TestUserApiBase {
     @Test(enabled=true)
     public void testUncancelBadState() {
         try {
-            ISubscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, "standard");
+            ISubscription subscription = createSubscription("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME);
 
             try {
                 subscription.uncancel();
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorMemoryMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorMemoryMock.java
index 4089936..38aed83 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorMemoryMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/ApiEventProcessorMemoryMock.java
@@ -19,9 +19,9 @@ package com.ning.billing.entitlement.engine.core;
 import java.util.List;
 
 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.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
 public class ApiEventProcessorMemoryMock extends ApiEventProcessorBase {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java
index 143b069..cc574ee 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoMemoryMock.java
@@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory;
 import com.google.inject.Inject;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.catalog.api.TimeUnit;
+import com.ning.billing.config.IEntitlementConfig;
 import com.ning.billing.entitlement.api.user.ISubscription;
 import com.ning.billing.entitlement.api.user.ISubscriptionBundle;
 import com.ning.billing.entitlement.api.user.Subscription;
@@ -38,11 +39,8 @@ import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.events.IEvent;
 import com.ning.billing.entitlement.events.IEvent.EventType;
 import com.ning.billing.entitlement.events.IEventLyfecycle.IEventLyfecycleState;
-import com.ning.billing.entitlement.events.phase.IPhaseEvent;
-import com.ning.billing.entitlement.events.phase.PhaseEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 import com.ning.billing.entitlement.events.user.IUserEvent;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
 public class EntitlementDaoMemoryMock implements IEntitlementDao, IEntitlementDaoMock {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoSqlMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoSqlMock.java
index 114021e..24d6bff 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoSqlMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/dao/EntitlementDaoSqlMock.java
@@ -24,7 +24,7 @@ import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
 import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
 
 import com.google.inject.Inject;
-import com.ning.billing.entitlement.glue.IEntitlementConfig;
+import com.ning.billing.config.IEntitlementConfig;
 import com.ning.billing.util.clock.IClock;
 
 public class EntitlementDaoSqlMock extends EntitlementDao implements IEntitlementDaoMock {
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMemoryMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMemoryMock.java
index e930cb2..3a701cc 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMemoryMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMemoryMock.java
@@ -17,21 +17,12 @@
 package com.ning.billing.entitlement.glue;
 
 
-import org.skife.config.ConfigurationObjectFactory;
-import org.skife.jdbi.v2.DBI;
-
-import com.ning.billing.dbi.DBIProvider;
-import com.ning.billing.dbi.DbiConfig;
 import com.ning.billing.entitlement.engine.core.ApiEventProcessorMemoryMock;
 import com.ning.billing.entitlement.engine.core.IApiEventProcessor;
 import com.ning.billing.entitlement.engine.dao.EntitlementDaoMemoryMock;
 import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
-import com.ning.billing.entitlement.glue.EntitlementModule;
-import com.ning.billing.util.clock.ClockMock;
-import com.ning.billing.util.clock.IClock;
-
 
-public class EngineModuleMemoryMock extends EntitlementModule {
+public class EngineModuleMemoryMock extends EngineModuleMock {
     @Override
     protected void installApiEventProcessor() {
         bind(IApiEventProcessor.class).to(ApiEventProcessorMemoryMock.class).asEagerSingleton();
@@ -42,20 +33,9 @@ public class EngineModuleMemoryMock extends EntitlementModule {
         bind(IEntitlementDao.class).to(EntitlementDaoMemoryMock.class).asEagerSingleton();
     }
 
-    @Override
-    protected void installClock() {
-        bind(IClock.class).to(ClockMock.class).asEagerSingleton();
-    }
-
-    protected void installDBI() {
-        bind(DBI.class).toProvider(DBIProvider.class).asEagerSingleton();
-        final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
-        bind(DbiConfig.class).toInstance(config);
-    }
 
     @Override
     protected void configure() {
         super.configure();
-        installDBI();
     }
 }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMock.java
new file mode 100644
index 0000000..d70a2f7
--- /dev/null
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleMock.java
@@ -0,0 +1,34 @@
+/*
+ * 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.glue;
+
+import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.clock.IClock;
+
+public class EngineModuleMock extends EntitlementModule {
+
+    @Override
+    protected void installClock() {
+        bind(IClock.class).to(ClockMock.class).asEagerSingleton();
+    }
+
+    @Override
+    protected void configure() {
+        super.configure();
+    }
+
+}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleSqlMock.java b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleSqlMock.java
index 6fdc8e5..9dd1c2d 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleSqlMock.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/glue/EngineModuleSqlMock.java
@@ -26,7 +26,7 @@ import com.ning.billing.entitlement.engine.dao.IEntitlementDao;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.clock.IClock;
 
-public class EngineModuleSqlMock extends EntitlementModule {
+public class EngineModuleSqlMock extends EngineModuleMock {
 
 
     @Override
diff --git a/entitlement/src/test/resources/entitlement.properties b/entitlement/src/test/resources/entitlement.properties
index 372ce23..d149d78 100644
--- a/entitlement/src/test/resources/entitlement.properties
+++ b/entitlement/src/test/resources/entitlement.properties
@@ -1,4 +1,4 @@
-killbill.entitlement.catalog.config.file=src/test/resources/testInput.xml
+killbill.catalog.uri=file:src/test/resources/testInput.xml
 killbill.entitlement.dao.claim.time=60000
 killbill.entitlement.dao.ready.max=1
 killbill.entitlement.engine.notifications.sleep=500
diff --git a/entitlement/src/test/resources/testInput.xml b/entitlement/src/test/resources/testInput.xml
index 59b9093..e9c041b 100644
--- a/entitlement/src/test/resources/testInput.xml
+++ b/entitlement/src/test/resources/testInput.xml
@@ -37,7 +37,7 @@ Use Cases to do:
 
  -->
 <catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:noNamespaceSchemaLocation="../../main/resources/CatalogSchema.xsd ">
+	xsi:noNamespaceSchemaLocation="CatalogSchema.xsd ">
 
 	<effectiveDate>2011-10-08T00:00:00+00:00</effectiveDate>
 	<catalogName>Firearms</catalogName>
@@ -83,12 +83,6 @@ Use Cases to do:
 		<product name="Refurbish-Maintenance">
 			<category>ADD_ON</category>
 		</product>
-		<product name="Bowie-Knife">
-			<category>BASE</category>
-		</product>
-		<product name="Samuri-Sword">
-			<category>BASE</category>
-		</product>
 	</products>
 	 
 	<rules>
@@ -555,8 +549,7 @@ Use Cases to do:
 		</plan>
 	</plans>
 	<priceLists>
-		<priceList name="standard">
-			<isDefault>true</isDefault>
+		<defaultPriceList> 
 			<plans>
 				<plan>pistol-monthly</plan>
 				<plan>shotgun-monthly</plan>
@@ -570,8 +563,8 @@ Use Cases to do:
 				<plan>holster-monthly-regular</plan>
 				<plan>refurbish-maintenance</plan>
 			</plans>
-		</priceList>
-		<priceList name="gunclubDiscount">
+		</defaultPriceList>
+		<childPriceList name="gunclubDiscount">
 			<plans>
 				<plan>pistol-monthly</plan>
 				<plan>shotgun-monthly</plan>
@@ -581,12 +574,12 @@ Use Cases to do:
 				<plan>assault-rifle-annual-gunclub-discount</plan>
 				<plan>holster-monthly-special</plan>
 			</plans>
-		</priceList>
-		<priceList name="rescue">
+		</childPriceList>
+		<childPriceList name="rescue">
 			<plans>
 				<plan>assault-rifle-annual-rescue</plan>
 			</plans>
-		</priceList>
+		</childPriceList>
 	</priceLists>
 
 </catalog>

invoice/pom.xml 7(+5 -2)

diff --git a/invoice/pom.xml b/invoice/pom.xml
index bdbf77b..6840bf4 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.6-SNAPSHOT</version>
+        <version>0.0.10-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-invoice</artifactId>
@@ -23,7 +23,10 @@
         <dependency>
             <groupId>com.ning.billing</groupId>
             <artifactId>killbill-api</artifactId>
-            <version>0.0.6-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-util</artifactId>
         </dependency>
         <dependency>
             <groupId>org.testng</groupId>

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

diff --git a/payment/pom.xml b/payment/pom.xml
index 729c773..84ff329 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.6-SNAPSHOT</version>
+        <version>0.0.10-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-payment</artifactId>

pom.xml 19(+13 -6)

diff --git a/pom.xml b/pom.xml
index 1bc3b7c..83ec479 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,10 +17,10 @@
     <groupId>com.ning.billing</groupId>
     <artifactId>killbill</artifactId>
     <packaging>pom</packaging>
-    <version>0.0.6-SNAPSHOT</version>
+    <version>0.0.10-SNAPSHOT</version>
     <name>killbill</name>
     <description>Library for managing recurring subscriptions and the associated billing</description>
-    <url>http://github.com/sbrossie/killbill</url>
+    <url>http://github.com/ning/killbill</url>
     <licenses>
         <license>
             <name>Apache License 2.0</name>
@@ -30,17 +30,18 @@
     </licenses>
     <scm>
         <connection>scm:git:git://github.com/stephane/killbill.git</connection>
-        <developerConnection>scm:git:git@github.com:sbrossie/killbill.git</developerConnection>
-        <url>http://github.com/sbrossie/killbill/tree/master</url>
+        <developerConnection>scm:git:git@github.com:ning/killbill.git</developerConnection>
+        <url>http://github.com/ning/killbill/tree/master</url>
     </scm>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
     <modules>
+        <module>account</module>
         <module>analytics</module>
         <module>api</module>
+        <module>beatrix</module>
         <module>catalog</module>
-        <module>account</module>
         <module>entitlement</module>
         <module>invoice</module>
         <module>payment</module>
@@ -55,6 +56,11 @@
             </dependency>
             <dependency>
                 <groupId>com.ning.billing</groupId>
+                <artifactId>killbill-entitlement</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.ning.billing</groupId>
                 <artifactId>killbill-catalog</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -315,6 +321,7 @@
                                 <exclude>**/*.properties</exclude>
                                 <exclude>**/*.dont-let-git-remove-this-directory</exclude>
                                 <exclude>**/test-output/**</exclude>
+                                <exclude>**/bin/**</exclude>
                             </excludes>
                         </configuration>
                     </execution>
@@ -471,6 +478,6 @@
     </reporting>
     <issueManagement>
         <system>Github</system>
-        <url>http://github.com/sbrossie/killbill</url>
+        <url>http://github.com/ning/killbill</url>
     </issueManagement>
 </project>

util/pom.xml 7(+6 -1)

diff --git a/util/pom.xml b/util/pom.xml
index 9a6b5f5..2143767 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.6-SNAPSHOT</version>
+        <version>0.0.10-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <artifactId>killbill-util</artifactId>
@@ -66,6 +66,11 @@
             <artifactId>commons-io</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        
     </dependencies>
     <build>
         <plugins>
diff --git a/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java b/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java
new file mode 100644
index 0000000..34c2adc
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/config/ValidatingConfig.java
@@ -0,0 +1,44 @@
+/*
+ * 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.net.URI;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+@XmlAccessorType(XmlAccessType.NONE)
+public abstract class ValidatingConfig<Context> {
+	/**
+	 * All must implement validation
+	 * 
+	 * @param root
+	 * @param errors
+	 * @return
+	 */
+	public abstract ValidationErrors validate(Context root, ValidationErrors errors);
+	
+	
+	/**
+	 * Override  to initialize
+	 * 
+	 * @param root
+	 */
+	public void initialize(Context root, URI uri){}
+
+}
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
new file mode 100644
index 0000000..72cf752
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/config/ValidationErrors.java
@@ -0,0 +1,31 @@
+/*
+ * 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.net.URI;
+import java.util.ArrayList;
+
+public class ValidationErrors extends ArrayList<ValidationError>{
+	private static final long serialVersionUID = 1L;
+
+	public void add(String description, URI catalogURI,
+			Class<?> objectType, String objectName) {
+		add(new ValidationError(description, catalogURI, objectType, objectName));
+		
+	}
+
+}
\ No newline at end of file
diff --git a/util/src/main/java/com/ning/billing/util/config/XMLWriter.java b/util/src/main/java/com/ning/billing/util/config/XMLWriter.java
new file mode 100644
index 0000000..3f16e90
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/config/XMLWriter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.ByteArrayOutputStream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+
+public class XMLWriter<T> {
+	final private static  int MAX_XML_SIZE_IN_BYTES = 100000;
+	
+	public static <T> String writeXML(T object, Class<T> type) throws Exception {
+   	 	JAXBContext context =JAXBContext.newInstance(type);
+        Marshaller marshaller = context.createMarshaller();
+        ByteArrayOutputStream output = new ByteArrayOutputStream(MAX_XML_SIZE_IN_BYTES);
+        
+        marshaller.marshal(object, output);
+        
+        return new String(output.toByteArray());
+   }
+}
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
new file mode 100644
index 0000000..02fbcd2
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/config/TestXMLLoader.java
@@ -0,0 +1,59 @@
+/*
+ * 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 static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+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;
+
+
+public class TestXMLLoader {
+	public static final String TEST_XML = 
+			"<xmlTestClass>" +
+			"	<foo>foo</foo>" +
+			"	<bar>1.0</bar>" +
+			"	<lala>42</lala>" +
+			"</xmlTestClass>";
+	
+	@Test
+	public void test() throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, URISyntaxException {
+		InputStream is = new ByteArrayInputStream(TEST_XML.getBytes());
+		XmlTestClass test = XMLLoader.getObjectFromStream(new URI("internal:/"), is, XmlTestClass.class);
+		assertEquals(test.getFoo(), "foo");
+		assertEquals(test.getBar(),1.0);
+		assertEquals(test.getLala(), 42);
+	}
+	
+	
+	
+	
+	
+}
diff --git a/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java b/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java
new file mode 100644
index 0000000..f863784
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/config/TestXMLSchemaGenerator.java
@@ -0,0 +1,40 @@
+/*
+ * 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.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.transform.TransformerException;
+
+import org.apache.commons.io.IOUtils;
+import org.testng.annotations.Test;
+
+public class TestXMLSchemaGenerator {
+	
+	@Test
+	public void test() throws IOException, TransformerException, JAXBException {
+		InputStream stream = XMLSchemaGenerator.xmlSchema(XmlTestClass.class);
+		StringWriter writer = new StringWriter();
+		IOUtils.copy(stream, writer);
+		String result = writer.toString();
+		
+		System.out.println(result);
+	}
+}
diff --git a/util/src/test/java/com/ning/billing/util/config/TestXMLWriter.java b/util/src/test/java/com/ning/billing/util/config/TestXMLWriter.java
new file mode 100644
index 0000000..f9115a0
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/util/config/TestXMLWriter.java
@@ -0,0 +1,53 @@
+/*
+ * 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 static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.URI;
+
+import org.testng.annotations.Test;
+
+public class TestXMLWriter {
+	public static final String TEST_XML = 
+			"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
+		    "<xmlTestClass>" +
+			"<foo>foo</foo>" +
+			"<bar>1.0</bar>" +
+			"<lala>42</lala>" +
+			"</xmlTestClass>";
+	
+	@Test
+	public void test() throws Exception {
+		InputStream is = new ByteArrayInputStream(TEST_XML.getBytes());
+		XmlTestClass test = XMLLoader.getObjectFromStream(new URI("internal:/"), is, XmlTestClass.class);
+		assertEquals(test.getFoo(), "foo");
+		assertEquals(test.getBar(), 1.0);
+		assertEquals(test.getLala(), 42);
+		
+		String output = XMLWriter.writeXML(test, XmlTestClass.class);
+		
+		System.out.println(output);
+		assertEquals(output, TEST_XML);
+		 
+	}
+
+	
+}