killbill-uncached

Merge branch 'irs-integration' of github.com:ning/killbill

11/30/2011 8:02:58 PM

Changes

Details

diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java
index 691fbe1..5602fe8 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessSubscription.java
@@ -17,6 +17,7 @@
 package com.ning.billing.analytics;
 
 import com.ning.billing.analytics.utils.Rounder;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.IDuration;
 import com.ning.billing.catalog.api.IPlan;
@@ -130,7 +131,14 @@ public class BusinessSubscription
             }
 
             if (currentPhase.getRecurringPrice() != null) {
-                price = currentPhase.getRecurringPrice().getPrice(USD);
+            	//TODO check if this is the right way to handle exception
+            	BigDecimal tmpPrice = null;
+                try {
+                	tmpPrice = currentPhase.getRecurringPrice().getPrice(USD);
+				} catch (CatalogApiException e) {
+					tmpPrice = new BigDecimal(0);
+				}
+                price = tmpPrice;
                 mrr = getMrrFromISubscription(currentPhase.getDuration(), price);
             }
             else {
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 e67c154..c2c0c43 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
@@ -17,46 +17,44 @@
 package com.ning.billing.catalog.api;
 
 import java.util.Date;
-import java.util.List;
 
 public interface ICatalog {
 
 	public abstract IProduct[] getProducts();
 	
-	public abstract IPlan getPlan(String productName, BillingPeriod term, String priceList);
+	public abstract IPlan findPlan(String productName, BillingPeriod term, String priceList) throws CatalogApiException;
 
-	public abstract Currency[] getSupportedCurrencies();
+	public abstract IPlan findPlan(String name) throws CatalogApiException;
 
-	public abstract IPlan[] getPlans();
+    public abstract IProduct findProduct(String name) throws CatalogApiException;
 
-	public abstract ActionPolicy getPlanChangePolicy(PlanPhaseSpecifier from,
-			PlanSpecifier to);
+    public abstract IPlanPhase findPhase(String name) throws CatalogApiException;
 
-	public abstract PlanChangeResult planChange(PlanPhaseSpecifier from,
-			PlanSpecifier to) throws IllegalPlanChange;
 	
-    public abstract IPlan getPlanFromName(String name);
+	public abstract Currency[] getSupportedCurrencies();
 
-    public abstract IPlanPhase getPhaseFromName(String name);
+	public abstract IPlan[] getPlans();
 
-    public abstract Date getEffectiveDate();
+	public abstract ActionPolicy planChangePolicy(PlanPhaseSpecifier from,
+			PlanSpecifier to) throws CatalogApiException;
 
-    public abstract IPlanPhase getPhaseFor(String name, Date date);
+	public abstract PlanChangeResult planChange(PlanPhaseSpecifier from,
+			PlanSpecifier to) throws IllegalPlanChange, CatalogApiException;
 
-    public abstract IProduct getProductFromName(String name);
+    public abstract Date getEffectiveDate();
 
-    public abstract ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase);
+    public abstract ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase) throws CatalogApiException;
 
     public abstract void configureEffectiveDate(Date date);
 
     public abstract String getCalalogName();
 
-    public abstract PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier);
+    public abstract PlanAlignmentCreate planCreateAlignment(PlanSpecifier specifier) throws CatalogApiException;
 
-    public abstract BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase);
+    public abstract BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase) throws CatalogApiException;
 
-    public abstract PlanAlignmentChange getPlanChangeAlignment(PlanPhaseSpecifier from,
-			PlanSpecifier to);
+    public abstract PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from,
+			PlanSpecifier to) throws CatalogApiException;
 
 	
 }
\ No newline at end of file
diff --git a/api/src/main/java/com/ning/billing/catalog/api/IInternationalPrice.java b/api/src/main/java/com/ning/billing/catalog/api/IInternationalPrice.java
index 47b206c..b771c31 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/IInternationalPrice.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/IInternationalPrice.java
@@ -24,7 +24,7 @@ public interface IInternationalPrice {
 
 	public abstract IPrice[] getPrices();
 
-	public abstract BigDecimal getPrice(Currency currency);
+	public abstract BigDecimal getPrice(Currency currency) throws CatalogApiException;
 
 	public abstract Date getEffectiveDateForExistingSubscriptons();
 
diff --git a/api/src/main/java/com/ning/billing/catalog/api/IPrice.java b/api/src/main/java/com/ning/billing/catalog/api/IPrice.java
index dce29cc..52a9c54 100644
--- a/api/src/main/java/com/ning/billing/catalog/api/IPrice.java
+++ b/api/src/main/java/com/ning/billing/catalog/api/IPrice.java
@@ -23,6 +23,6 @@ public interface IPrice {
 
 	public abstract Currency getCurrency();
 
-	public abstract BigDecimal getValue();
+	public abstract BigDecimal getValue() throws CurrencyValueNull;
 
 }
\ No newline at end of file
diff --git a/api/src/main/java/com/ning/billing/ErrorCode.java b/api/src/main/java/com/ning/billing/ErrorCode.java
index 5cca8fa..aef5920 100644
--- a/api/src/main/java/com/ning/billing/ErrorCode.java
+++ b/api/src/main/java/com/ning/billing/ErrorCode.java
@@ -44,9 +44,45 @@ public enum ErrorCode {
     /* Un-cancellation */
     ENT_UNCANCEL_BAD_STATE(1070, "Subscription %s was not in a cancelled state"),
     
+    /*
+    *
+    * Range 2000 : CATALOG
+    *
+    */
+    
+    /*
+    * Rules exceptions 
+    */
+    
+    /* Plan change is disallowed by the catalog */
     CAT_ILLEGAL_CHANGE_REQUEST(2001, "Attempting to change plan from (product: '%s', billing period: '%s', " +
-    		"pricelist '%s') to (product: '%s', billing period: '%s', pricelist '%s'). This transition is not allowed by catalog rules")
+    		"pricelist '%s') to (product: '%s', billing period: '%s', pricelist '%s'). This transition is not allowed by catalog rules"),
+
+	/*
+	 * Price list 
+	 */
+
+	/*Attempt to reference a price that is not present - should only happen if it is a currency not available in the catalog */
+    CAT_NO_PRICE_FOR_CURRENCY(2010, "This price does not have a value for the currency '%s'."),
     
+    /* Price value explicitly set to NULL meaning there is no price available in that currency */
+    CAT_PRICE_VALUE_NULL_FOR_CURRENCY(2011, "The value for the currency '%s' is NULL. This plan cannot be bought in this currnency."),
+    
+    /*
+     * Plans
+     */
+    CAT_PLAN_NOT_FOUND(2020,"Could not find a plan matching: (product: '%s', billing period: '%s', pricelist '%s')"),
+    CAT_NO_SUCH_PLAN(2021,"Could not find any plans named '%s'"),
+    
+    /*
+     * Products
+     */
+    CAT_NO_SUCH_PRODUCT(2030,"Could not find any plans named '%s'"),
+    
+    /*
+     * Phases
+     */
+    CAT_NO_SUCH_PHASE(2040,"Could not find any phases named '%s'")
     ;
 
     private int code;
diff --git a/api/src/main/java/com/ning/billing/invoice/api/BillingEvent.java b/api/src/main/java/com/ning/billing/invoice/api/BillingEvent.java
index d17bc26..f7c7ab9 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/BillingEvent.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/BillingEvent.java
@@ -17,6 +17,7 @@
 package com.ning.billing.invoice.api;
 
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.IInternationalPrice;
 import com.ning.billing.entitlement.api.billing.BillingMode;
@@ -90,9 +91,15 @@ public class BillingEvent implements IBillingEvent {
         return price;
     }
 
+ // TODO handle exception correctly
     @Override
     public BigDecimal getPrice(Currency currency) {
-        return price.getPrice(currency);
+        try {
+			return price.getPrice(currency);
+		} catch (CatalogApiException e)  {		
+			e.printStackTrace();
+			return new BigDecimal(0);
+		}
     }
 
     @Override
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 fa24752..61a4604 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/Catalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/Catalog.java
@@ -26,22 +26,24 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 
+import com.ning.billing.ErrorCode;
 import com.ning.billing.catalog.api.ActionPolicy;
 import com.ning.billing.catalog.api.BillingAlignment;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.ICatalog;
 import com.ning.billing.catalog.api.IProduct;
 import com.ning.billing.catalog.api.IllegalPlanChange;
 import com.ning.billing.catalog.api.PlanAlignmentChange;
 import com.ning.billing.catalog.api.PlanAlignmentCreate;
+import com.ning.billing.catalog.api.PlanChangeResult;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.rules.PlanRules;
 import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationError;
 import com.ning.billing.util.config.ValidationErrors;
-import com.ning.billing.catalog.api.PlanChangeResult;
 
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
@@ -63,7 +65,7 @@ public class Catalog extends ValidatingConfig<Catalog> implements ICatalog {
 	private Product[] products;
 
 	@XmlElement(name="rules", required=true)
-    private PlanRules planRules;
+	private PlanRules planRules;
 
 	@XmlElementWrapper(name="plans", required=true)
 	@XmlElement(name="plan", required=true)
@@ -78,70 +80,149 @@ public class Catalog extends ValidatingConfig<Catalog> implements ICatalog {
 		this.effectiveDate = effectiveDate;
 	}
 
-	@Override
-	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, sourceURI);
-		}
-		for(Plan p : plans) {
-			p.initialize(catalog, sourceURI);
-		}
-	}
-
-    /* (non-Javadoc)
+	/* (non-Javadoc)
 	 * @see com.ning.billing.catalog.ICatalog#getCalalogName()
 	 */
-    @Override
+	@Override
 	public String getCalalogName() {
 		return catalogName;
 	}
 
-    /* (non-Javadoc)
+	@Override
+	public Date getEffectiveDate() {
+		return effectiveDate;
+	}
+
+	/* (non-Javadoc)
 	 * @see com.ning.billing.catalog.ICatalog#getProducts()
 	 */
-    @Override
+	@Override
 	public Product[] getProducts() {
 		return products;
 	}
 
-	public void setProducts(Product[] products) {
-		this.products = products;
+
+	@Override
+	public Currency[] getSupportedCurrencies() {
+		return supportedCurrencies;
+	}
+
+	@Override
+	public Plan[] getPlans() {
+		return plans;
 	}
 
- 
-    /* (non-Javadoc)
+	public URI getCatalogURI() {
+		return catalogURI;
+	}
+
+	public PlanRules getPlanRules() { 
+		return planRules;
+	}
+	
+	public PriceList getPriceListFromName(String priceListName) {
+		return priceLists.findPriceListFrom(priceListName);
+	}
+	
+	public PriceListSet getPriceLists() {
+		return this.priceLists;
+	}
+
+	@Override
+	public void configureEffectiveDate(Date date) {
+		// Nothing to do here this is a method that is only implemented on VersionedCatalog
+	}
+
+
+	/* (non-Javadoc)
 	 * @see com.ning.billing.catalog.ICatalog#getPlan(java.lang.String, java.lang.String)
 	 */
-    @Override
-	public Plan getPlan(String productName, BillingPeriod period, String priceListName) {
-    	IProduct product = getProductFromName(productName);
-    	return priceLists.getPlanListFrom(priceListName, product, period);
-    }
+	@Override
+	public Plan findPlan(String productName, BillingPeriod period, String priceListName) throws CatalogApiException {
+		IProduct product = findProduct(productName);
+		Plan result = priceLists.getPlanListFrom(priceListName, product, period);
+		if ( result == null) {
+			throw new CatalogApiException(ErrorCode.CAT_PLAN_NOT_FOUND, productName, period.toString(), priceListName);
+		}
+		return result;
+	}
+	
+	@Override
+	public Plan findPlan(String name) throws CatalogApiException {
+		if (name == null) {
+			return null;
+		}
+		for(Plan p : plans) {
+			if(p.getName().equals(name)) {
+				return p;
+			}
+		}
+		throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PLAN, name);
+	}
+	
+	@Override
+	public IProduct findProduct(String name) throws CatalogApiException {
+		for(Product p : products) {
+			if (p.getName().equals(name)) {
+				return p;
+			}
+		}
+		throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PRODUCT, name);
+	}
 
 	@Override
-	public Currency[] getSupportedCurrencies() {
-		return supportedCurrencies;
+	public PlanPhase findPhase(String name) throws CatalogApiException {
+		for(Plan p : plans) {
+
+			if(p.getFinalPhase().getName().equals(name)) {
+				return p.getFinalPhase();
+			}
+			if (p.getInitialPhases() != null) {
+				for(PlanPhase pp : p.getInitialPhases()) {
+					if(pp.getName().equals(name)) {
+						return pp;
+					}
+				}
+			}
+		}
+
+		throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PHASE, name);
 	}
 
-	public void setSupportedCurrencies(Currency[] supportedCurrencies) {
-		this.supportedCurrencies = supportedCurrencies;
+	//////////////////////////////////////////////////////////////////////////////
+	//
+	// RULES
+	//
+	//////////////////////////////////////////////////////////////////////////////
+	@Override
+	public ActionPolicy planChangePolicy(PlanPhaseSpecifier from, PlanSpecifier to) throws CatalogApiException {
+		return planRules.getPlanChangePolicy(from, to, this);
 	}
 
-	public void setPlanChangeRules(PlanRules planChangeRules) {
-		this.planRules = planChangeRules;
+	@Override
+	public PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from, PlanSpecifier to) throws CatalogApiException {
+		return planRules.getPlanChangeAlignment(from, to, this);
 	}
 
 	@Override
-	public Plan[] getPlans() {
-		return plans;
+	public ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase) throws CatalogApiException {
+		return planRules.getPlanCancelPolicy(planPhase, this);
 	}
 
-	public void setPlans(Plan[] plans) {
-		this.plans = plans;
+	@Override
+	public PlanAlignmentCreate planCreateAlignment(PlanSpecifier specifier) throws CatalogApiException {
+		return planRules.getPlanCreateAlignment(specifier, this);
+	}
+
+	@Override
+	public BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase) throws CatalogApiException {
+		return planRules.getBillingAlignment(planPhase, this);
+	}
+
+	@Override
+	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to)
+			throws CatalogApiException {
+		return planRules.planChange(from, to, this);
 	}
 
 	@Override
@@ -153,140 +234,64 @@ public class Catalog extends ValidatingConfig<Catalog> implements ICatalog {
 		return errors;
 	}
 
-    private Collection<? extends ValidationError> validate(Catalog catalog,
+	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);
-    }
-    
-    @Override
-    public PlanAlignmentChange getPlanChangeAlignment(PlanPhaseSpecifier from, PlanSpecifier to) {
-        return planRules.getPlanChangeAlignment(from, to, this);
-    }
-
-    @Override
-    public ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase) {
-        return planRules.getPlanCancelPolicy(planPhase, this);
-    }
-    
-    @Override
-    public PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier) {
-        return planRules.getPlanCreateAlignment(specifier, this);
-    }
-    
-    @Override
-    public BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase) {
-        return planRules.getBillingAlignment(planPhase, this);
-    }
-
-
-    @Override
-    public Plan getPlanFromName(String name) {
-        if (name == null) {
-            return null;
-        }
-        for(Plan p : plans) {
-        	if(p.getName().equals(name)) {
-        		return p;
-        	}
-        }
-        return null;
-    }
-    
-    @Override
-    public IProduct getProductFromName(String name) {
-        for(Product p : products) {
-        	if (p.getName().equals(name)) {
-        		return p;
-        	}
-        }
-        return null;
-    }
-
-
-    @Override
-    public PlanPhase getPhaseFromName(String name) {
-
-        if (name == null) {
-            return null;
-        }
-        for(Plan p : plans) {
-
-            if(p.getFinalPhase().getName().equals(name)) {
-                return p.getFinalPhase();
-            }
-            if (p.getInitialPhases() != null) {
-                for(PlanPhase pp : p.getInitialPhases()) {
-                    if(pp.getName().equals(name)) {
-                        return pp;
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-	public Date getEffectiveDate() {
-		return effectiveDate;
+	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, sourceURI);
+		}
+		for(Plan p : plans) {
+			p.initialize(catalog, sourceURI);
+		}
 	}
 
-	public void setEffectiveDate(Date effectiveDate) {
-		this.effectiveDate = effectiveDate;
-	}
 
-	public URI getCatalogURI() {
-		return catalogURI;
+	protected Catalog setProducts(Product[] products) {
+		this.products = products;
+		return this;
 	}
-	
-	public PlanRules getPlanRules() { 
-		return planRules;
+	protected Catalog setSupportedCurrencies(Currency[] supportedCurrencies) {
+		this.supportedCurrencies = supportedCurrencies;
+		return this;
 	}
 
-	public void setPlanRules(PlanRules planRules) {
-		this.planRules = planRules;
+	protected Catalog setPlanChangeRules(PlanRules planChangeRules) {
+		this.planRules = planChangeRules;
+		return this;
 	}
 
-	@Override
-    public PlanPhase getPhaseFor(String name, Date date) {
-    	if(getEffectiveDate().getTime() >= date.getTime()){
-    		return getPhaseFromName(name);
-    	}
-    	return null;
-    }
-
-	public void setPriceLists(PriceListSet priceLists) {
-		this.priceLists = priceLists;
+	protected Catalog setPlans(Plan[] plans) {
+		this.plans = plans;
+		return this;
 	}
 
-	public PriceListSet getPriceLists() {
-		return this.priceLists;
+	protected Catalog setEffectiveDate(Date effectiveDate) {
+		this.effectiveDate = effectiveDate;
+		return this;
 	}
 
-	@Override
-	public void configureEffectiveDate(Date date) {
-		// Nothing to do here this is a method that is only inplemented on VersionedCatalog
-		
+	protected Catalog setPlanRules(PlanRules planRules) {
+		this.planRules = planRules;
+		return this;
 	}
 
-	public PriceList getPriceListFromName(String priceListName) {
-		return priceLists.findPriceListFrom(priceListName);
+	protected Catalog setPriceLists(PriceListSet priceLists) {
+		this.priceLists = priceLists;
+		return this;
 	}
 
-	@Override
-	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to)
-			throws IllegalPlanChange {
-		return planRules.planChange(from, to, this);
-	}
-	
-	//TODO: MDW validation - only allow one default pricelist
+
 
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java b/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java
index b0d099a..fb1d473 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/CatalogService.java
@@ -20,6 +20,7 @@ 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.catalog.io.VersionedCatalogLoader;
 import com.ning.billing.config.ICatalogConfig;
 import com.ning.billing.lifecycle.IService;
 import com.ning.billing.lifecycle.LifecycleHandlerType;
@@ -35,19 +36,26 @@ public class CatalogService implements IService, Provider<ICatalog>, ICatalogSer
     private final ICatalogConfig config;
     private boolean isInitialized;
 
+	private VersionedCatalogLoader loader;
+
 
     @Inject
-    public CatalogService(ICatalogConfig config) {
+    public CatalogService(ICatalogConfig config, VersionedCatalogLoader loader) {
         this.config = config;
         System.out.println(config.getCatalogURI());
         this.isInitialized = false;
+        this.loader = loader;
     }
 
     @LifecycleHandlerType(LifecycleLevel.LOAD_CATALOG)
     public synchronized void loadCatalog() throws ServiceException {
         if (!isInitialized) {
             try {
-                catalog = XMLLoader.getObjectFromProperty(config.getCatalogURI(), Catalog.class);
+            	System.out.println("Really really::" + config.getCatalogURI());
+            	String url = config.getCatalogURI();
+            	catalog = loader.load(url);
+            	
+                //catalog = XMLLoader.getObjectFromProperty(config.getCatalogURI(), Catalog.class);
                 isInitialized = true;
             } catch (Exception e) {
                 throw new ServiceException(e);
diff --git a/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java b/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java
index deb2305..9b09f31 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/glue/CatalogModule.java
@@ -20,9 +20,9 @@ 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.catalog.io.ICatalogLoader;
+import com.ning.billing.catalog.io.VersionedCatalogLoader;
 import com.ning.billing.config.ICatalogConfig;
 
 public class CatalogModule extends AbstractModule {
@@ -33,8 +33,8 @@ public class CatalogModule extends AbstractModule {
     }
 
     protected void installCatalog() {
-        bind(ICatalogUserApi.class).to(CatalogUserApi.class).asEagerSingleton();
         bind(ICatalogService.class).to(CatalogService.class).asEagerSingleton();
+        bind(ICatalogLoader.class).to(VersionedCatalogLoader.class).asEagerSingleton();
     }
 
     @Override
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 f9d35c2..2aceedf 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/InternationalPrice.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/InternationalPrice.java
@@ -24,15 +24,18 @@ import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 
+import com.ning.billing.ErrorCode;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.CurrencyValueNull;
 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.ValidationError;
 import com.ning.billing.util.config.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
 public class InternationalPrice extends ValidatingConfig<Catalog> implements IInternationalPrice {
-	private static Price[] zeroPrice;
 
 	//TODO MDW Validation - effectiveDateForExistingSubscriptons > catalog effectiveDate 
 	@XmlElement(required=false)
@@ -43,6 +46,7 @@ public class InternationalPrice extends ValidatingConfig<Catalog> implements IIn
 	@XmlElement(name="price")
 	private Price[] prices;
 
+
 	/* (non-Javadoc)
 	 * @see com.ning.billing.catalog.IInternationalPrice#getPrices()
 	 */
@@ -62,17 +66,17 @@ public class InternationalPrice extends ValidatingConfig<Catalog> implements IIn
 	/* (non-Javadoc)
 	 * @see com.ning.billing.catalog.IInternationalPrice#getPrice(com.ning.billing.catalog.api.Currency)
 	 */
-	@Override
-	public BigDecimal getPrice(Currency currency) {
-		// Note if there are no prices specified we default to 0 for any currency
+	@Override 
+	public BigDecimal getPrice(Currency currency) throws CatalogApiException {
 		for(IPrice p : prices) {
 			if(p.getCurrency() == currency) {
 				return p.getValue();
 			}
 		}
-		return new BigDecimal(0);
+		throw new CatalogApiException(ErrorCode.CAT_NO_PRICE_FOR_CURRENCY, currency);
 	}
 
+
 	protected void setEffectiveDateForExistingSubscriptons(
 			Date effectiveDateForExistingSubscriptons) {
 		this.effectiveDateForExistingSubscriptons = effectiveDateForExistingSubscriptons;
@@ -86,17 +90,31 @@ public class InternationalPrice extends ValidatingConfig<Catalog> implements IIn
 
 	@Override
 	public ValidationErrors validate(Catalog catalog, ValidationErrors errors)  {
-		if(prices.length == 0) return errors;
 		Currency[] supportedCurrencies = catalog.getSupportedCurrencies();
 		for (IPrice p : prices) {
 			Currency currency = p.getCurrency();
 			if(!currencyIsSupported(currency, supportedCurrencies)) {
 				errors.add("Unsupported currency: " + currency, catalog.getCatalogURI(), this.getClass(), "");
 			}
+			try {
+				if(p.getValue().doubleValue() < 0.0) {
+					errors.add("Negative value for price in currency: " + currency, catalog.getCatalogURI(), this.getClass(), "");
+				}
+			} catch (CurrencyValueNull e) {
+				// No currency => nothing to check, ignore exception
+			}
+		}
+		if(effectiveDateForExistingSubscriptons != null &&
+				catalog.getEffectiveDate().getTime() > effectiveDateForExistingSubscriptons.getTime()) {
+			errors.add(new ValidationError(String.format("Price effective date %s is before catalog effective date '%s'",
+					effectiveDateForExistingSubscriptons,
+					catalog.getEffectiveDate().getTime()), 
+					catalog.getCatalogURI(), InternationalPrice.class, ""));
 		}
+		
 		return errors;
 	}
-
+	
 	private boolean currencyIsSupported(Currency currency, Currency[] supportedCurrencies) {
 		for (Currency c : supportedCurrencies) {
 			if(c == currency) {
@@ -106,6 +124,7 @@ public class InternationalPrice extends ValidatingConfig<Catalog> implements IIn
 		return false;
 	}
 
+
 	@Override
 	public void initialize(Catalog root, URI uri) {
 		if(prices == null) {
@@ -115,15 +134,14 @@ public class InternationalPrice extends ValidatingConfig<Catalog> implements IIn
 	}
 
 	private synchronized Price[] getZeroPrice(Catalog root) {
-		if(zeroPrice == null) {
-			Currency[] currencies = root.getSupportedCurrencies();
-			zeroPrice = new Price[currencies.length];
-			for(int i = 0; i < currencies.length; i++) {
-				zeroPrice[i] = new Price();
-				zeroPrice[i].setCurrency(currencies[i]);
-				zeroPrice[i].setValue(new BigDecimal(0));
-			}
+		Currency[] currencies = root.getSupportedCurrencies();
+		Price[] zeroPrice = new Price[currencies.length];
+		for(int i = 0; i < currencies.length; i++) {
+			zeroPrice[i] = new Price();
+			zeroPrice[i].setCurrency(currencies[i]);
+			zeroPrice[i].setValue(new BigDecimal(0));
 		}
+
 		return zeroPrice;
 	}
 
diff --git a/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java b/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
index 9bc2314..52f92ef 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/io/VersionedCatalogLoader.java
@@ -16,64 +16,81 @@
 
 package com.ning.billing.catalog.io;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.net.URLConnection;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
-import java.util.Scanner;
-
-import javax.xml.bind.JAXBException;
-import javax.xml.transform.TransformerException;
-
-import org.xml.sax.SAXException;
 
+import com.google.inject.Inject;
 import com.ning.billing.catalog.Catalog;
 import com.ning.billing.catalog.VersionedCatalog;
-import com.ning.billing.catalog.api.InvalidConfigException;
+import com.ning.billing.lifecycle.IService.ServiceException;
+import com.ning.billing.util.clock.IClock;
+import com.ning.billing.util.config.UriAccessor;
 import com.ning.billing.util.config.XMLLoader;
 
-public class VersionedCatalogLoader  {
+public class VersionedCatalogLoader implements ICatalogLoader  {
+	private static final Object PROTOCOL_FOR_FILE = "file";
 	private  final String XML_EXTENSION = ".xml";
 	private  final String HREF_LOW_START = "href=\""; 
 	private  final String HREF_CAPS_START = "HREF=\""; 
 	private  final String HREF_SEARCH_END = "\"";
+	private IClock clock;
 			
+	@Inject 
+	public VersionedCatalogLoader(IClock clock) {
+		this.clock = clock;
+	}
+	
 	/* (non-Javadoc)
-	 * @see com.ning.billing.catalog.io.ICatalogLoader#load(java.net.URL)
+	 * @see com.ning.billing.catalog.io.ICatalogLoader#load(java.lang.String)
 	 */
-	public  VersionedCatalog load(URL url) throws IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
-		String directoryContents = pullContentsFrom(url);
-		List<URL> xmlURLs = findXmlReferences(directoryContents, url);
-		VersionedCatalog result = new VersionedCatalog();
-		for(URL u : xmlURLs) {
-			Catalog catalog = XMLLoader.getObjectFromURL(u, Catalog.class);
-			result.add(catalog);
+	@Override
+	public  VersionedCatalog load(String uriString) throws ServiceException{
+		try {
+			List<URI> xmlURIs = null;
+			
+			if(uriString.endsWith(XML_EXTENSION)) { //assume its an xml file
+				xmlURIs = new ArrayList<URI>();
+	        	xmlURIs.add(new URI(uriString));
+			} else { //assume its a directory
+				String directoryContents = UriAccessor.accessUriAsString(uriString);
+				xmlURIs = findXmlReferences(directoryContents, new URL(uriString));
+			}
+			
+			VersionedCatalog result = new VersionedCatalog();
+			for(URI u : xmlURIs) {
+				Catalog catalog = XMLLoader.getObjectFromUri(u, Catalog.class);
+				result.add(catalog);
+			}
+			Date now = clock.getUTCNow().toDate();
+			result.configureEffectiveDate(now);
+			return result;
+		} catch (Exception e) {
+			throw new ServiceException("Problem encountered loading catalog", e);
 		}
-		return result;
 	}
 	
-	protected  List<URL> findXmlReferences(String directoryContents, URL url) throws MalformedURLException {
-		if(url.getProtocol().equals("file")) {
+	protected  List<URI> findXmlReferences(String directoryContents, URL url) throws URISyntaxException {
+		if(url.getProtocol().equals(PROTOCOL_FOR_FILE)) {
 			return findXmlFileReferences(directoryContents, url);
 		} 
 		return findXmlUrlReferences(directoryContents, url);
 	}
 
-	protected  List<URL> findXmlUrlReferences(String directoryContents, URL url) throws MalformedURLException {
-		List<URL> results = new ArrayList<URL>();
+	protected  List<URI> findXmlUrlReferences(String directoryContents, URL url) throws URISyntaxException {
+		List<URI> results = new ArrayList<URI>();
 		List<String> urlFragments = extractHrefs(directoryContents);
 		for(String u : urlFragments) {
 			if(u.endsWith(XML_EXTENSION)) { //points to xml
 				if(u.startsWith("/")) { //absolute path need to add the protocol
-					results.add(new URL(url.getProtocol() + ":" + u));
+					results.add(new URI(url.getProtocol() + ":" + u));
 				} else if (u.startsWith("http:")) { // full url
-					results.add(new URL(u));
+					results.add(new URI(u));
 				} else { // relative url stick the name on the end
-					results.add(appendToURL(url,u));
+					results.add(appendToURI(url,u));
 				}
 			}
 		}
@@ -108,28 +125,24 @@ public class VersionedCatalogLoader  {
 		return results;
 	}
 
-	protected  List<URL> findXmlFileReferences(String directoryContents, URL url) throws MalformedURLException {
-		List<URL> results = new ArrayList<URL>();
+	protected  List<URI> findXmlFileReferences(String directoryContents, URL url) throws URISyntaxException {
+		List<URI> results = new ArrayList<URI>();
 		String[] filenames = directoryContents.split("\\n");
 		for(String filename : filenames) {
 			if(filename.endsWith(XML_EXTENSION)) {
-				results.add(appendToURL(url,filename));
+				results.add(appendToURI(url,filename));
 			}
 		}
 		return results;
 	}
 
-	protected  URL appendToURL(final URL url, final String filename) throws MalformedURLException {
+	protected  URI appendToURI(final URL url, final String filename) throws URISyntaxException {
 		String f = filename;
 		if (!url.toString().endsWith("/")) {
 			f = "/" + filename;
 		}
-		return new URL(url.toString() + f);
+		return new URI(url.toString() + f);
 	}
 
-	protected  String pullContentsFrom(final URL url) throws IOException {
-		URLConnection connection = url.openConnection();
-		InputStream content = connection.getInputStream();
-		return new Scanner(content).useDelimiter("\\A").next();
-	}
+	
 }
diff --git a/catalog/src/main/java/com/ning/billing/catalog/PlanPhase.java b/catalog/src/main/java/com/ning/billing/catalog/PlanPhase.java
index 50ded44..f76f365 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/PlanPhase.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/PlanPhase.java
@@ -122,9 +122,6 @@ public class PlanPhase extends ValidatingConfig<Catalog> implements IPlanPhase {
 					catalog.getCatalogURI(), PlanPhase.class, type.toString()));
 		}
 		
-		
-		
-		
 		//Validation: if there is a recurring price there must be a billing period
 		if(recurringPrice != null && (billingPeriod == null || billingPeriod ==BillingPeriod.NO_BILLING_PERIOD)) {
 			errors.add(new ValidationError(String.format("Phase %s of plan %s has a reccurring price but no billing period", type.toString(), plan.getName()), 
@@ -132,22 +129,27 @@ public class PlanPhase extends ValidatingConfig<Catalog> implements IPlanPhase {
 		}
 		//Validation: if there is no reccuring price there should be no billing period
 		if(recurringPrice == null && billingPeriod != BillingPeriod.NO_BILLING_PERIOD) {
-			errors.add(new ValidationError(String.format("Phase %s of plan %s has no reccurring price but does have a billing period. The billing period shoudl be set to '%s'", 
+			errors.add(new ValidationError(String.format("Phase %s of plan %s has no reccurring price but does have a billing period. The billing period should be set to '%s'", 
 					type.toString(), plan.getName(), BillingPeriod.NO_BILLING_PERIOD), 
 					catalog.getCatalogURI(), PlanPhase.class, type.toString()));
 		}
 		
+		//Validation: there must be at least one of reccuringPrice or fixedPrice
+		if(recurringPrice == null && fixedPrice == null) {
+			errors.add(new ValidationError(String.format("Phase %s of plan %s has neither a reccurring price or a fixed price.", 
+					type.toString(), plan.getName()), 
+					catalog.getCatalogURI(), PlanPhase.class, type.toString()));
+		}
 		return errors;
 
 	}
 	
-
 	@Override
 	public void initialize(Catalog root, URI uri) {
 		if (fixedPrice != null) { fixedPrice.initialize(root, uri);  }	
 		if (recurringPrice != null) { recurringPrice.initialize(root, uri); }
 	}
-
+	
 	protected PlanPhase setFixedPrice(InternationalPrice price) {
 		this.fixedPrice = price;
 		return this;
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 cdbf464..3e81f64 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/Price.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/Price.java
@@ -23,6 +23,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 
 import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.CurrencyValueNull;
 import com.ning.billing.catalog.api.IPrice;
 import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationErrors;
@@ -32,7 +33,7 @@ public class Price extends ValidatingConfig<Catalog> implements IPrice {
 	@XmlElement(required=true)
 	private Currency currency;
 
-	@XmlElement(required=true)
+	@XmlElement(required=true,nillable=true)
 	private BigDecimal value;
 
 	/* (non-Javadoc)
@@ -47,7 +48,10 @@ public class Price extends ValidatingConfig<Catalog> implements IPrice {
 	 * @see com.ning.billing.catalog.IPrice#getValue()
 	 */
 	@Override
-	public BigDecimal getValue() {
+	public BigDecimal getValue() throws CurrencyValueNull {
+		if (value == null) {
+			throw new CurrencyValueNull(currency);
+		}
 		return value;
 	}
 	
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java b/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java
index 67f7bae..39b267d 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/Case.java
@@ -20,6 +20,7 @@ import com.ning.billing.catalog.Catalog;
 import com.ning.billing.catalog.PriceList;
 import com.ning.billing.catalog.Product;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.util.config.ValidatingConfig;
@@ -34,21 +35,21 @@ public abstract class Case<T> extends ValidatingConfig<Catalog> {
 
 	protected abstract T getResult();
 
-	public T getResult(PlanSpecifier planPhase, Catalog c) {
+	public T getResult(PlanSpecifier planPhase, Catalog c) throws CatalogApiException {
 		if (satisfiesCase(planPhase, c)	) {
 			return getResult(); 
 		}
 		return null;
 	}
 	
-	protected boolean satisfiesCase(PlanSpecifier planPhase, Catalog c) {
-		return (product         == null || product.equals(c.getProductFromName(planPhase.getProductName()))) &&
+	protected boolean satisfiesCase(PlanSpecifier planPhase, Catalog c) throws CatalogApiException {
+		return (product         == null || product.equals(c.findProduct(planPhase.getProductName()))) &&
 		(productCategory == null || productCategory.equals(planPhase.getProductCategory())) &&
 		(billingPeriod   == null || billingPeriod.equals(planPhase.getBillingPeriod())) &&
 		(priceList       == null || priceList.equals(c.getPriceListFromName(planPhase.getPriceListName())));
 	}
 
-	public static <K> K getResult(Case<K>[] cases, PlanSpecifier planSpec, Catalog catalog) {
+	public static <K> K getResult(Case<K>[] cases, PlanSpecifier planSpec, Catalog catalog) throws CatalogApiException {
     	if(cases != null) {
     		for(Case<K> c : cases) {
     			K result = c.getResult(planSpec, catalog);
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java
index e0095f8..b5e6f8d 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CaseChange.java
@@ -25,6 +25,7 @@ import com.ning.billing.catalog.Catalog;
 import com.ning.billing.catalog.PriceList;
 import com.ning.billing.catalog.Product;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PlanSpecifier;
@@ -69,13 +70,13 @@ public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
 	protected abstract T getResult();
 	
 	public T getResult(PlanPhaseSpecifier from,
-			PlanSpecifier to, Catalog catalog) {
+			PlanSpecifier to, Catalog catalog) throws CatalogApiException {
 		if(	
 				(phaseType     	     == null || from.getPhaseType() == phaseType) &&
-				(fromProduct 	     == null || fromProduct.equals(catalog.getProductFromName(from.getProductName()))) &&
+				(fromProduct 	     == null || fromProduct.equals(catalog.findProduct(from.getProductName()))) &&
 				(fromProductCategory == null || fromProductCategory.equals(from.getProductCategory())) &&
 				(fromBillingPeriod   == null || fromBillingPeriod.equals(from.getBillingPeriod())) &&
-				(toProduct           == null || toProduct.equals(catalog.getProductFromName(to.getProductName()))) &&
+				(toProduct           == null || toProduct.equals(catalog.findProduct(to.getProductName()))) &&
 				(toProductCategory   == null || toProductCategory.equals(to.getProductCategory())) &&
 				(toBillingPeriod     == null || toBillingPeriod.equals(to.getBillingPeriod())) &&
 				(fromPriceList       == null || fromPriceList.equals(catalog.getPriceListFromName(from.getPriceListName()))) &&
@@ -87,7 +88,7 @@ public abstract class CaseChange<T>  extends ValidatingConfig<Catalog> {
 	}
 	
 	static public <K> K getResult(CaseChange<K>[] cases, PlanPhaseSpecifier from,
-			PlanSpecifier to, Catalog catalog) {
+			PlanSpecifier to, Catalog catalog) throws CatalogApiException {
     	if(cases != null) {
     		for(CaseChange<K> cc : cases) {
     			K result = cc.getResult(from, to, catalog);
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java b/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java
index afd6d4b..a098a77 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/CasePhase.java
@@ -22,6 +22,7 @@ import com.ning.billing.catalog.Catalog;
 import com.ning.billing.catalog.PriceList;
 import com.ning.billing.catalog.Product;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PlanSpecifier;
@@ -33,7 +34,7 @@ public abstract class CasePhase<T> extends CaseStandardNaming<T> {
 	@XmlElement(required=false)
 	private PhaseType phaseType;	
 	
-	public T getResult(PlanPhaseSpecifier specifier, Catalog c) {
+	public T getResult(PlanPhaseSpecifier specifier, Catalog c) throws CatalogApiException {
 		if (	
 				(phaseType       == null || specifier.getPhaseType() == null || specifier.getPhaseType() == phaseType) &&
 				satisfiesCase(new PlanSpecifier(specifier), c)
@@ -43,7 +44,7 @@ public abstract class CasePhase<T> extends CaseStandardNaming<T> {
 		return null;
 	}
 	
-	public static <K> K getResult(CasePhase<K>[] cases, PlanPhaseSpecifier planSpec, Catalog catalog) {
+	public static <K> K getResult(CasePhase<K>[] cases, PlanPhaseSpecifier planSpec, Catalog catalog) throws CatalogApiException {
     	if(cases != null) {
     		for(CasePhase<K> cp : cases) {
     			K result = cp.getResult(planSpec, catalog);
diff --git a/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java b/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java
index 787dbaf..d688815 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/rules/PlanRules.java
@@ -25,13 +25,13 @@ import com.ning.billing.catalog.Catalog;
 import com.ning.billing.catalog.PriceList;
 import com.ning.billing.catalog.api.ActionPolicy;
 import com.ning.billing.catalog.api.BillingAlignment;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.IllegalPlanChange;
 import com.ning.billing.catalog.api.PlanAlignmentChange;
 import com.ning.billing.catalog.api.PlanAlignmentCreate;
 import com.ning.billing.catalog.api.PlanChangeResult;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PlanSpecifier;
-import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.util.config.ValidatingConfig;
 import com.ning.billing.util.config.ValidationErrors;
 
@@ -62,19 +62,19 @@ public class PlanRules extends ValidatingConfig<Catalog>  {
 	@XmlElement(name="priceListCase", required=false)
 	private CasePriceList[] priceListCase;
 
-	public PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier, Catalog catalog) {
+	public PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier, Catalog catalog) throws CatalogApiException {
 		return Case.getResult(createAlignmentCase, specifier, catalog);      
     }
 	
-	public ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase, Catalog catalog) {
+	public ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase, Catalog catalog) throws CatalogApiException {
 		return CasePhase.getResult(cancelCase, planPhase, catalog);      
 	}
 
-	public BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase, Catalog catalog) {
+	public BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase, Catalog catalog) throws CatalogApiException {
 		return CasePhase.getResult(billingAlignmentCase, planPhase, catalog);      
 	}
 
-	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to, Catalog catalog) throws IllegalPlanChange {
+	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to, Catalog catalog) throws CatalogApiException {
 		PriceList priceList = catalog.getPriceListFromName(to.getPriceListName());
 		if( priceList== null ) {
 			priceList = findPriceList(from.toPlanSpecifier(), catalog);
@@ -92,12 +92,12 @@ public class PlanRules extends ValidatingConfig<Catalog>  {
 	}
 	
 	public PlanAlignmentChange getPlanChangeAlignment(PlanPhaseSpecifier from,
-			PlanSpecifier to, Catalog catalog) {
+			PlanSpecifier to, Catalog catalog) throws CatalogApiException {
 		return CaseChange.getResult(changeAlignmentCase, from, to, catalog);      
     }
 
 	public ActionPolicy getPlanChangePolicy(PlanPhaseSpecifier from,
-			PlanSpecifier to, Catalog catalog) {
+			PlanSpecifier to, Catalog catalog) throws CatalogApiException {
 		if(from.getProductName().equals(to.getProductName()) &&
 				from.getBillingPeriod() == to.getBillingPeriod() &&
 				from.getPriceListName().equals(to.getPriceListName())) {
@@ -107,7 +107,7 @@ public class PlanRules extends ValidatingConfig<Catalog>  {
 		return CaseChange.getResult(changeCase, from, to, catalog); 
 	}
 	
-	private PriceList findPriceList(PlanSpecifier specifier, Catalog catalog) {
+	private PriceList findPriceList(PlanSpecifier specifier, Catalog catalog) throws CatalogApiException {
 		PriceList result = Case.getResult(priceListCase, specifier, catalog);
 		if (result == null) {
 			result = catalog.getPriceListFromName(specifier.getPriceListName());
diff --git a/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java b/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
index cb447ea..7bf76f5 100644
--- a/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
+++ b/catalog/src/main/java/com/ning/billing/catalog/VersionedCatalog.java
@@ -23,15 +23,16 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 
+import com.google.inject.Inject;
 import com.ning.billing.catalog.api.ActionPolicy;
 import com.ning.billing.catalog.api.BillingAlignment;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.ICatalog;
 import com.ning.billing.catalog.api.IPlan;
 import com.ning.billing.catalog.api.IPlanPhase;
 import com.ning.billing.catalog.api.IProduct;
-import com.ning.billing.catalog.api.IllegalPlanChange;
 import com.ning.billing.catalog.api.PlanAlignmentChange;
 import com.ning.billing.catalog.api.PlanAlignmentCreate;
 import com.ning.billing.catalog.api.PlanChangeResult;
@@ -46,10 +47,11 @@ public class VersionedCatalog extends ValidatingConfig<Catalog> implements ICata
 	
 	private final List<Catalog> versions = new ArrayList<Catalog>();
 	
+	@Inject
 	public VersionedCatalog() {
 		Catalog baseline = new Catalog(new Date(0)); // init with an empty catalog may need to 
 													 // populate some empty pieces here to make validation work
-		add(baseline);
+		add(baseline); 
 	}
 	
 	private Catalog versionForDate(Date date) {
@@ -95,12 +97,6 @@ public class VersionedCatalog extends ValidatingConfig<Catalog> implements ICata
 	}
 
 	@Override
-	public IPlan getPlan(String productName, BillingPeriod term,
-			String planSetName) {
-		return currentCatalog.getPlan(productName, term, planSetName);
-	}
-
-	@Override
 	public Currency[] getSupportedCurrencies() {
 		return currentCatalog.getSupportedCurrencies();
 	}
@@ -111,19 +107,29 @@ public class VersionedCatalog extends ValidatingConfig<Catalog> implements ICata
 	}
 
 	@Override
-	public Plan getPlanFromName(String name) {
-		return currentCatalog.getPlanFromName(name);
+	public Date getEffectiveDate() {
+		return currentCatalog.getEffectiveDate();
 	}
 
+	@Override
+	public IPlan findPlan(String productName, BillingPeriod term,
+			String planSetName) throws CatalogApiException {
+		return currentCatalog.findPlan(productName, term, planSetName);
+	}
 
 	@Override
-	public IPlanPhase getPhaseFromName(String name) {
-		return currentCatalog.getPhaseFromName(name);
+	public Plan findPlan(String name) throws CatalogApiException {
+		return currentCatalog.findPlan(name);
 	}
 
 	@Override
-	public Date getEffectiveDate() {
-		return currentCatalog.getEffectiveDate();
+	public IPlanPhase findPhase(String name) throws CatalogApiException {
+		return currentCatalog.findPhase(name);
+	}
+
+	@Override
+	public IProduct findProduct(String name) throws CatalogApiException {
+		return currentCatalog.findProduct(name);
 	}
 
 	@Override
@@ -142,36 +148,25 @@ public class VersionedCatalog extends ValidatingConfig<Catalog> implements ICata
 	}
 	
 	@Override
-    public PlanPhase getPhaseFor(String name, Date date) {
-    	Catalog c = versionForDate(date);
-    	return c.getPhaseFromName(name);
-    }
-
-	@Override
-	public ActionPolicy getPlanChangePolicy(PlanPhaseSpecifier from,
-			PlanSpecifier to) {
-		return currentCatalog.getPlanChangePolicy(from, to);
-	}
-
-	@Override
-	public IProduct getProductFromName(String name) {
-		return currentCatalog.getProductFromName(name);
+	public ActionPolicy planChangePolicy(PlanPhaseSpecifier from,
+			PlanSpecifier to) throws CatalogApiException {
+		return currentCatalog.planChangePolicy(from, to);
 	}
 
 	@Override
-	public ActionPolicy getPlanCancelPolicy(PlanPhaseSpecifier planPhase) {
-		return currentCatalog.getPlanCancelPolicy(planPhase);
+	public ActionPolicy planCancelPolicy(PlanPhaseSpecifier planPhase) throws CatalogApiException {
+		return currentCatalog.planCancelPolicy(planPhase);
 	}
 
 	@Override
-	public PlanAlignmentChange getPlanChangeAlignment(PlanPhaseSpecifier from,
-			PlanSpecifier to) {
-		return currentCatalog.getPlanChangeAlignment(from, to);
+	public PlanAlignmentChange planChangeAlignment(PlanPhaseSpecifier from,
+			PlanSpecifier to) throws CatalogApiException {
+		return currentCatalog.planChangeAlignment(from, to);
 	}
 
 	@Override
-	public PlanAlignmentCreate getPlanCreateAlignment(PlanSpecifier specifier) {
-		return currentCatalog.getPlanCreateAlignment(specifier);
+	public PlanAlignmentCreate planCreateAlignment(PlanSpecifier specifier) throws CatalogApiException {
+		return currentCatalog.planCreateAlignment(specifier);
 	}
 
 	@Override
@@ -180,13 +175,13 @@ public class VersionedCatalog extends ValidatingConfig<Catalog> implements ICata
 	}
 
 	@Override
-	public BillingAlignment getBillingAlignment(PlanPhaseSpecifier planPhase) {
-		return currentCatalog.getBillingAlignment(planPhase);
+	public BillingAlignment billingAlignment(PlanPhaseSpecifier planPhase) throws CatalogApiException {
+		return currentCatalog.billingAlignment(planPhase);
 	}
 
 	@Override
 	public PlanChangeResult planChange(PlanPhaseSpecifier from, PlanSpecifier to)
-			throws IllegalPlanChange {
+			throws CatalogApiException {
 		return currentCatalog.planChange(from, to);
 	}
 	
diff --git a/catalog/src/test/java/com/ning/billing/catalog/io/TestVersionedCatalogLoader.java b/catalog/src/test/java/com/ning/billing/catalog/io/TestVersionedCatalogLoader.java
index 0035bc8..1b4703c 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
@@ -16,10 +16,10 @@
 package com.ning.billing.catalog.io;
 
 import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertTrue;
 
 import java.io.IOException;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Iterator;
@@ -36,26 +36,20 @@ import com.google.common.io.Resources;
 import com.ning.billing.catalog.Catalog;
 import com.ning.billing.catalog.VersionedCatalog;
 import com.ning.billing.catalog.api.InvalidConfigException;
+import com.ning.billing.lifecycle.IService.ServiceException;
+import com.ning.billing.util.clock.Clock;
 
 public class TestVersionedCatalogLoader {
-	private final VersionedCatalogLoader loader = new VersionedCatalogLoader();
+	private final VersionedCatalogLoader loader = new VersionedCatalogLoader(new Clock());
 
-
-	@Test(enabled=true)
-	public void testPullContentsFrom() throws MalformedURLException, IOException {
-		String contents = loader.pullContentsFrom(Resources.getResource("WeaponsHireSmall.xml"));
-
-		assertTrue(contents.length() > 0);
-		
-	}
 	
 	@Test(enabled=true)
-	public void testAppendToURL() throws MalformedURLException, IOException {
+	public void testAppendToURI() throws MalformedURLException, IOException, URISyntaxException {
 		URL u1 = new URL("http://www.ning.com/foo");
-		assertEquals("http://www.ning.com/foo/bar",loader.appendToURL(u1, "bar").toString());
+		assertEquals("http://www.ning.com/foo/bar",loader.appendToURI(u1, "bar").toString());
 
 		URL u2 = new URL("http://www.ning.com/foo/");
-		assertEquals("http://www.ning.com/foo/bar",loader.appendToURL(u2, "bar").toString());
+		assertEquals("http://www.ning.com/foo/bar",loader.appendToURI(u2, "bar").toString());
 		
 	}
 	
@@ -63,12 +57,12 @@ public class TestVersionedCatalogLoader {
 
 	
 	@Test(enabled=true)
-	public void testFindXmlFileReferences() throws MalformedURLException {
+	public void testFindXmlFileReferences() throws MalformedURLException, URISyntaxException {
 		String page = "dg.xml\n" + 
 				"replica.foo\n" + 
 				"snv1/\n" + 
 				"viking.xml\n" ;
-		List<URL> urls = loader.findXmlFileReferences(page, new URL("http://ning.com/"));
+		List<URI> urls = loader.findXmlFileReferences(page, new URL("http://ning.com/"));
 		assertEquals(2, urls.size());
 		assertEquals("http://ning.com/dg.xml", urls.get(0).toString());
 		assertEquals("http://ning.com/viking.xml", urls.get(1).toString());
@@ -101,7 +95,7 @@ public class TestVersionedCatalogLoader {
 	}
 	
 	@Test(enabled=true)
-	public void testFindXmlUrlReferences() throws MalformedURLException {
+	public void testFindXmlUrlReferences() throws MalformedURLException, URISyntaxException {
 		String page = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">" + 
 				"<html>" + 
 				" <head>" + 
@@ -119,16 +113,16 @@ public class TestVersionedCatalogLoader {
 				"</ul>" + 
 				"<address>Apache/2.2.3 (CentOS) Server at <a href=\"mailto:kate@ning.com\">gepo.ningops.net</a> Port 80</address>" + 
 				"</body></html>" ;
-		List<URL> urls = loader.findXmlUrlReferences(page, new URL("http://ning.com/"));
-		assertEquals(2, urls.size());
-		assertEquals("http://ning.com/dg.xml", urls.get(0).toString());
-		assertEquals("http://ning.com/viking.xml", urls.get(1).toString());
+		List<URI> uris = loader.findXmlUrlReferences(page, new URL("http://ning.com/"));
+		assertEquals(2, uris.size());
+		assertEquals("http://ning.com/dg.xml", uris.get(0).toString());
+		assertEquals("http://ning.com/viking.xml", uris.get(1).toString());
 		
 	}
 	
 	@Test(enabled=true)
-	public void testLoad() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
-		VersionedCatalog c = loader.load(Resources.getResource("versionedCatalog"));
+	public void testLoad() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException {
+		VersionedCatalog c = loader.load(Resources.getResource("versionedCatalog").toString());
 		assertEquals(4, c.size());
 		Iterator<Catalog> it = c.iterator();
 		it.next(); //discard the baseline
diff --git a/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java b/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java
index a75cb06..01b436e 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/io/TestXMLReader.java
@@ -16,26 +16,18 @@
 
 package com.ning.billing.catalog.io;
 
-import java.io.IOException;
-import java.net.URISyntaxException;
-
-import javax.xml.bind.JAXBException;
-import javax.xml.transform.TransformerException;
-
 import org.testng.annotations.Test;
-import org.xml.sax.SAXException;
 
 import com.google.common.io.Resources;
 import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.api.InvalidConfigException; 
 import com.ning.billing.util.config.XMLLoader;
 
 public class TestXMLReader {
 
 	@Test(enabled=true)
-	public void testCatalogLoad() throws IOException, TransformerException, JAXBException, SAXException, InvalidConfigException, URISyntaxException {
-		XMLLoader.getObjectFromURL(Resources.getResource("WeaponsHire.xml"), Catalog.class);
-		XMLLoader.getObjectFromURL(Resources.getResource("WeaponsHireSmall.xml"), Catalog.class);
+	public void testCatalogLoad() throws Exception {
+		XMLLoader.getObjectFromString(Resources.getResource("WeaponsHire.xml").toExternalForm(), Catalog.class);
+		XMLLoader.getObjectFromString(Resources.getResource("WeaponsHireSmall.xml").toExternalForm(), 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 c561457..31d9e51 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/MockCatalog.java
@@ -16,6 +16,10 @@
 
 package com.ning.billing.catalog;
 
+import java.util.Date;
+
+import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.catalog.rules.CaseCancelPolicy;
 import com.ning.billing.catalog.rules.CaseChangePlanAlignment;
@@ -27,6 +31,7 @@ public class MockCatalog extends Catalog {
 	private static final String[] PRODUCT_NAMES = new String[]{ "TestProduct1", "TestProduct2", "TestProduct3"};
 	
 	public MockCatalog() {
+		setEffectiveDate(new Date());
 		populateProducts();
 		populateRules();
 		populatePlans();
@@ -59,7 +64,8 @@ public class MockCatalog extends Catalog {
 		Product[] products = getProducts();
 		Plan[] plans = new Plan[products.length];
 		for(int i = 0; i < products.length; i++) {
-			plans[i] = new MockPlan().setName(products[i].getName().toLowerCase() + "-plan").setProduct(products[i]);
+			PlanPhase phase = new PlanPhase().setPhaseType(PhaseType.EVERGREEN).setBillingPeriod(BillingPeriod.MONTHLY).setReccuringPrice(new InternationalPrice());
+			plans[i] = new MockPlan().setName(products[i].getName().toLowerCase() + "-plan").setProduct(products[i]).setFinalPhase(phase);
 		}
 		setPlans(plans);
 	}
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java
index 3cd031b..03ae3a3 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCase.java
@@ -28,6 +28,7 @@ import com.ning.billing.catalog.MockCatalog;
 import com.ning.billing.catalog.PriceList;
 import com.ning.billing.catalog.Product;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.IPriceListSet;
 import com.ning.billing.catalog.api.PlanSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
@@ -56,7 +57,7 @@ public class TestCase {
 	}
 
 	@Test(enabled=true)
-	public void testBasic(){
+	public void testBasic() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
@@ -71,14 +72,14 @@ public class TestCase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-		assertionNull(cr, "lala", ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+		assertionNull(cr, cat.getProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
 	}
 
 	@Test(enabled=true)
-	public void testWildCardProduct(){
+	public void testWildCardProduct() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
@@ -94,14 +95,14 @@ public class TestCase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
-		assertion(Result.FOO, cr,"lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
+		assertion(Result.FOO, cr, cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
 	}
 	
 	@Test(enabled=true)
-	public void testWildCardProductCategory(){
+	public void testWildCardProductCategory() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
@@ -117,14 +118,14 @@ public class TestCase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-		assertionNull(cr, "lala", ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
 	}
 	
 	@Test(enabled=true)
-	public void testWildCardBillingPeriod(){
+	public void testWildCardBillingPeriod() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
@@ -140,14 +141,14 @@ public class TestCase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-		assertionNull(cr, "lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertion(Result.FOO,cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
 	}
 
 	@Test(enabled=true)
-	public void testWildCardPriceList(){
+	public void testWildCardPriceList() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
@@ -163,14 +164,14 @@ public class TestCase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
-		assertionNull(cr, "lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), cat);
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", cat);
 	}
 	
 	@Test
-	public void testCaseOrder() {
+	public void testCaseOrder() throws CatalogApiException {
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
@@ -217,11 +218,11 @@ public class TestCase {
 	
 
 
-	protected void assertionNull(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, Catalog cat){
+	protected void assertionNull(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, Catalog cat) throws CatalogApiException{
 		assertNull(cr.getResult(new PlanSpecifier(productName, productCategory, bp, priceListName), cat));
 	}
 
-	protected void assertion(Result result, CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName,Catalog cat){
+	protected void assertion(Result result, CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName,Catalog cat) throws CatalogApiException{
 		assertEquals(result, cr.getResult(new PlanSpecifier(productName, productCategory, bp, priceListName), cat));
 	}
 
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java
index 34f055d..152480d 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCaseChange.java
@@ -21,6 +21,7 @@ import static org.testng.AssertJUnit.assertNull;
 
 import javax.xml.bind.annotation.XmlElement;
 
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.Catalog;
@@ -28,6 +29,7 @@ import com.ning.billing.catalog.MockCatalog;
 import com.ning.billing.catalog.PriceList;
 import com.ning.billing.catalog.Product;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.IPriceListSet;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
@@ -91,14 +93,14 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -136,14 +138,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -181,7 +183,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertion(Result.FOO,cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -202,7 +204,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.ANNUAL, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -219,14 +221,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -264,7 +266,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -285,7 +287,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertion(Result.FOO, cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -309,14 +311,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -354,14 +356,14 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -399,14 +401,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -444,14 +446,14 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -489,14 +491,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -534,7 +536,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -555,7 +557,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -579,14 +581,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -625,7 +627,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -646,7 +648,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -670,14 +672,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -715,7 +717,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -736,7 +738,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -760,14 +762,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -805,7 +807,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -826,7 +828,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -850,14 +852,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertion(Result.FOO,cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
@@ -895,7 +897,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				"wrong", product2.getName(), 
+				 cat.getProducts()[1].getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -916,7 +918,7 @@ public class TestCaseChange {
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
-				product1.getName(), "wrong", 
+				product1.getName(),  cat.getProducts()[1].getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
 				priceList1.getName(), priceList2.getName(), 
@@ -940,14 +942,14 @@ public class TestCaseChange {
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				"wrong", priceList2.getName(), 
+				 cat.getProducts()[1].getName(), priceList2.getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertionNull(cr, 
 				product1.getName(), product2.getName(), 
 				ProductCategory.BASE, ProductCategory.BASE,
 				BillingPeriod.MONTHLY, BillingPeriod.MONTHLY, 
-				priceList1.getName(), "wrong", 
+				priceList1.getName(),  cat.getProducts()[1].getName(), 
 				PhaseType.EVERGREEN, cat);
 		
 		assertion(Result.FOO,cr, 
@@ -960,7 +962,7 @@ public class TestCaseChange {
 	
 	
 	@Test(enabled=true)
-	public void testOrder(){
+	public void testOrder() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
 		Product product1 = cat.getProducts()[0];
@@ -1031,8 +1033,12 @@ public class TestCaseChange {
 			BillingPeriod fromBp, BillingPeriod toBp,
 			String fromPriceListName, String toPriceListName,
 			PhaseType phaseType, Catalog cat){
-		assertNull(cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory, fromBp, fromPriceListName, phaseType), 
-								new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat));
+		try {
+			assertNull(cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory, fromBp, fromPriceListName, phaseType), 
+									new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat));
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
+		}
 	}
 
 	protected void assertion(Result result, CaseChangeResult cr, 
@@ -1041,8 +1047,12 @@ public class TestCaseChange {
 			BillingPeriod fromBp, BillingPeriod toBp,
 			String fromPriceListName, String toPriceListName,
 			PhaseType phaseType, Catalog cat){
-		assertEquals(result, cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory,fromBp, fromPriceListName, phaseType), 
-								new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat));
+		try {
+			assertEquals(result, cr.getResult(new PlanPhaseSpecifier(fromProductName, fromProductCategory,fromBp, fromPriceListName, phaseType), 
+					new PlanSpecifier(toProductName, toProductCategory, toBp, toPriceListName),cat));
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
+		}
 	}
 
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java
index 32c8354..96893c8 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestCasePhase.java
@@ -16,11 +16,9 @@
 
 package com.ning.billing.catalog.rules;
 
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNull;
-
 import javax.xml.bind.annotation.XmlElement;
 
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.Catalog;
@@ -28,6 +26,7 @@ import com.ning.billing.catalog.MockCatalog;
 import com.ning.billing.catalog.PriceList;
 import com.ning.billing.catalog.Product;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.ProductCategory;
@@ -73,7 +72,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, "lala", ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -97,7 +96,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertion(Result.FOO, cr,"lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertion(Result.FOO, cr, cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -121,7 +120,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, "lala", ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -145,7 +144,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, "lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertion(Result.FOO,cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -169,7 +168,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, "lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -193,7 +192,7 @@ public class TestCasePhase {
 				Result.FOO);
 
 		assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-		assertionNull(cr, "lala", ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+		assertionNull(cr,  cat.getProducts()[1].getName(), ProductCategory.BASE,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.ADD_ON,BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE,BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
 		assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -201,7 +200,7 @@ public class TestCasePhase {
 	}
 	
 	@Test(enabled=true)
-	public void testOrder(){
+	public void testOrder() throws CatalogApiException{
 		MockCatalog cat = new MockCatalog();
 
 		Product product = cat.getProducts()[0];
@@ -251,22 +250,30 @@ public class TestCasePhase {
 		Result r1 = CasePhase.getResult(new CaseResult[]{cr0, cr1, cr2,cr3,cr4}, 
 				new PlanPhaseSpecifier(product.getName(), product.getCategory(), BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN), cat);
 		
-		assertEquals(Result.FOO, r1);
+		Assert.assertEquals(Result.FOO, r1);
 
 		Result r2 = CasePhase.getResult(new CaseResult[]{cr0, cr1, cr2,cr3,cr4}, 
 				new PlanPhaseSpecifier(product.getName(), product.getCategory(), BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN), cat);
 		
-		assertEquals(Result.DIPSY, r2);
+		Assert.assertEquals(Result.DIPSY, r2);
 
 	}
 
 
 	protected void assertionNull(CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, PhaseType phaseType, Catalog cat){
-		assertNull(cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+		try {
+			Assert.assertNull(cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
+		}
 	}
 
 	protected void assertion(Result result, CaseResult cr, String productName, ProductCategory productCategory, BillingPeriod bp, String priceListName, PhaseType phaseType, Catalog cat){
-		assertEquals(result, cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+		try {
+			Assert.assertEquals(result, cr.getResult(new PlanPhaseSpecifier(productName, productCategory, bp, priceListName, phaseType), cat));
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
+		}
 	}
 
 
diff --git a/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java b/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java
index fac41a2..38f0f60 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/rules/TestPlanRules.java
@@ -16,10 +16,9 @@
 
 package com.ning.billing.catalog.rules;
 
-import junit.framework.Assert;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testng.Assert;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
@@ -28,6 +27,7 @@ import com.ning.billing.catalog.PriceList;
 import com.ning.billing.catalog.Product;
 import com.ning.billing.catalog.api.ActionPolicy;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.IPriceListSet;
 import com.ning.billing.catalog.api.IllegalPlanChange;
 import com.ning.billing.catalog.api.PhaseType;
@@ -70,6 +70,8 @@ public class TestPlanRules {
 			Assert.fail("We did not see an exception when  trying to change plan to the same plan");
 		} catch (IllegalPlanChange e) {
 			log.info("Correct - cannot change to the same plan:", e);
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
 		}
 
 	}
@@ -88,6 +90,8 @@ public class TestPlanRules {
 		} catch (IllegalPlanChange e) {
 			log.info("Correct - cannot change to the same plan:", e);
 			Assert.fail("We should not have triggered this error");
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
 		}
 		
 		Assert.assertEquals(result.getPolicy(), ActionPolicy.END_OF_TERM);
@@ -113,6 +117,8 @@ public class TestPlanRules {
 		} catch (IllegalPlanChange e) {
 			log.info("Correct - cannot change to the same plan:", e);
 			Assert.fail("We should not have triggered this error");
+		} catch (CatalogApiException e) {
+			Assert.fail("", e);
 		}
 		
 		Assert.assertEquals(result.getPolicy(), ActionPolicy.END_OF_TERM);
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestCatlogService.java b/catalog/src/test/java/com/ning/billing/catalog/TestCatlogService.java
new file mode 100644
index 0000000..fa42ea3
--- /dev/null
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestCatlogService.java
@@ -0,0 +1,57 @@
+/*
+ * 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 org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.catalog.api.ICatalog;
+import com.ning.billing.catalog.io.VersionedCatalogLoader;
+import com.ning.billing.config.ICatalogConfig;
+import com.ning.billing.lifecycle.IService.ServiceException;
+import com.ning.billing.util.clock.Clock;
+
+public class TestCatlogService {
+
+	@Test
+	public void testCatalogServiceDirectory() throws ServiceException {
+		CatalogService service = new CatalogService(new ICatalogConfig() {
+			@Override
+			public String getCatalogURI() {
+				return "file:src/test/resources/versionedCatalog";
+			}
+			
+		}, new VersionedCatalogLoader(new Clock()));
+		service.loadCatalog();
+		Assert.assertNotNull(service.getCatalog());
+		Assert.assertEquals(service.getCatalog().getCalalogName(), "WeaponsHireSmall");
+	}
+	
+	@Test
+	public void testCatalogServiceFile() throws ServiceException {
+		CatalogService service = new CatalogService(new ICatalogConfig() {
+			@Override
+			public String getCatalogURI() {
+				return "file:src/test/resources/WeaponsHire.xml";
+			}
+			
+		}, new VersionedCatalogLoader(new Clock()));
+		service.loadCatalog();
+		Assert.assertNotNull(service.getCatalog());
+		Assert.assertEquals(service.getCatalog().getCalalogName(), "Firearms");
+	}
+}
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java b/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
index a02541d..535da6f 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestInternationalPrice.java
@@ -18,15 +18,22 @@ package com.ning.billing.catalog;
 import java.math.BigDecimal;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.util.Date;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.util.config.ValidationErrors;
 
 public class TestInternationalPrice {
+	private static final Logger log = LoggerFactory.getLogger(TestInternationalPrice.class);
+	
   @Test
-  public void testZeroValue() throws URISyntaxException {
+  public void testZeroValue() throws URISyntaxException, CatalogApiException {
 	  Catalog c = new MockCatalog();
 	  c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
 	  InternationalPrice p0 =  new MockInternationalPrice();
@@ -55,4 +62,44 @@ public class TestInternationalPrice {
 	  Assert.assertEquals(p1.getPrice(Currency.MXN), new BigDecimal(1));
 	  
   }
+  
+  @Test
+  public void testPriceInitialization() throws URISyntaxException, CatalogApiException  {
+	  Catalog c = new MockCatalog();
+	  c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+	  c.initialize(c, new URI("foo://bar"));
+	  Assert.assertEquals(c.getPlans()[0].getFinalPhase().getRecurringPrice().getPrice(Currency.GBP), new BigDecimal(0));
+  }
+  
+  @Test
+  public void testNegativeValuePrices(){
+	  Catalog c = new MockCatalog();
+	  c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+	
+	  InternationalPrice p1 =  new MockInternationalPrice();
+	  p1.setPrices(new Price[] {
+			  new Price().setCurrency(Currency.GBP).setValue(new BigDecimal(-1)),
+			  new Price().setCurrency(Currency.EUR).setValue(new BigDecimal(-1)),
+			  new Price().setCurrency(Currency.USD).setValue(new BigDecimal(-1)),
+			  new Price().setCurrency(Currency.BRL).setValue(new BigDecimal(1)),
+			  new Price().setCurrency(Currency.MXN).setValue(new BigDecimal(1)),		  
+	  });
+	  
+	 ValidationErrors errors = p1.validate(c, new ValidationErrors());
+	 errors.log(log);
+	 Assert.assertEquals(errors.size(), 3);
+  }
+  @Test
+  public void testDateValidation(){
+	 Catalog c = new MockCatalog();
+	 c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
+	 InternationalPrice p1 =  new MockInternationalPrice();
+	 p1.setEffectiveDateForExistingSubscriptons(new Date((new Date().getTime()) - (1000 * 60 * 60 * 24)));
+	 ValidationErrors errors = p1.validate(c, new ValidationErrors());
+	 Assert.assertEquals(errors.size(), 1);
+	 errors.log(log);
+  }
+  
+  
+  
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java b/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
index b38a823..beb3cb7 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestPlanPhase.java
@@ -31,7 +31,7 @@ public class TestPlanPhase {
 	public void testValidation() {
 		log.info("Testing Plan Phase Validation");
 		
-		PlanPhase pp = new MockPlanPhase().setBillCycleDuration(BillingPeriod.MONTHLY).setReccuringPrice(null);
+		PlanPhase pp = new MockPlanPhase().setBillCycleDuration(BillingPeriod.MONTHLY).setReccuringPrice(null).setFixedPrice(new InternationalPrice());
 		ValidationErrors errors = pp.validate(new MockCatalog(), new ValidationErrors());
 		errors.log(log);
 		Assert.assertEquals(errors.size(), 1);
@@ -40,5 +40,10 @@ public class TestPlanPhase {
 		errors = pp.validate(new MockCatalog(), new ValidationErrors());
 		errors.log(log);
 		Assert.assertEquals(errors.size(), 1);
-	}
+
+		pp = new MockPlanPhase().setReccuringPrice(null).setFixedPrice(null).setBillCycleDuration(BillingPeriod.NO_BILLING_PERIOD);
+		errors = pp.validate(new MockCatalog(), new ValidationErrors());
+		errors.log(log);
+		Assert.assertEquals(errors.size(), 1);
+}
 }
diff --git a/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java b/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
index fc456ac..c6da79d 100644
--- a/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
+++ b/catalog/src/test/java/com/ning/billing/catalog/TestVersionedCatalog.java
@@ -30,24 +30,24 @@ import org.testng.annotations.Test;
 import org.xml.sax.SAXException;
 
 import com.google.common.io.Resources;
-import com.ning.billing.catalog.Catalog;
-import com.ning.billing.catalog.VersionedCatalog;
 import com.ning.billing.catalog.api.InvalidConfigException;
 import com.ning.billing.catalog.io.VersionedCatalogLoader;
+import com.ning.billing.lifecycle.IService.ServiceException;
+import com.ning.billing.util.clock.Clock;
 
 public class TestVersionedCatalog {
-	private final VersionedCatalogLoader loader = new VersionedCatalogLoader();
+	private final VersionedCatalogLoader loader = new VersionedCatalogLoader(new Clock());
 
 	@Test(enabled=true)
-	public void testAddCatalog() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
-		VersionedCatalog vc = loader.load(Resources.getResource("versionedCatalog"));
+	public void testAddCatalog() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException {
+		VersionedCatalog vc = loader.load(Resources.getResource("versionedCatalog").toString());
 		vc.add(new Catalog(new Date()));
 		assertEquals(5, vc.size());
 	}
 	
 	@Test(enabled=true)
-	public void testApplyEffectiveDate() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException {
-		VersionedCatalog vc = loader.load(Resources.getResource("versionedCatalog"));
+	public void testApplyEffectiveDate() throws MalformedURLException, IOException, SAXException, InvalidConfigException, JAXBException, TransformerException, URISyntaxException, ServiceException {
+		VersionedCatalog vc = loader.load(Resources.getResource("versionedCatalog").toString());
 		Date d = new Date(1L);
 		vc.configureEffectiveDate(d);
 		assertEquals(new Date(0), vc.getEffectiveDate()); // Start at the begining of time
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/PlanAligner.java
index 5a4305f..5ba7076 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
@@ -23,6 +23,7 @@ import java.util.List;
 import org.joda.time.DateTime;
 
 import com.google.inject.Inject;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.ICatalog;
 import com.ning.billing.catalog.api.ICatalogService;
 import com.ning.billing.catalog.api.IDuration;
@@ -95,7 +96,16 @@ public class PlanAligner implements IPlanAligner {
                     priceList);
 
             DateTime planStartDate = null;
-            PlanAlignmentCreate alignement =  catalog.getPlanCreateAlignment(planSpecifier);
+            
+            //TODO fix exception handling
+            PlanAlignmentCreate alignement = null;
+			try {
+				alignement = catalog.planCreateAlignment(planSpecifier);
+			} catch (CatalogApiException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			
             switch(alignement) {
             case START_OF_SUBSCRIPTION:
                 planStartDate = subscription.getStartDate();
@@ -131,7 +141,15 @@ public class PlanAligner implements IPlanAligner {
                 priceList);
 
         DateTime planStartDate = null;
-        PlanAlignmentChange alignment = catalog.getPlanChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier);
+        
+        //TODO Correctly handle exception
+        PlanAlignmentChange alignment = null;
+		try {
+			alignment = catalog.planChangeAlignment(fromPlanPhaseSpecifier, toPlanSpecifier);
+		} catch (CatalogApiException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
         switch(alignment) {
         case START_OF_SUBSCRIPTION:
             planStartDate = subscription.getStartDate();
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 83339a8..d9d2ec9 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
@@ -26,6 +26,7 @@ import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.IAccount;
 import com.ning.billing.catalog.api.BillingPeriod;
+import com.ning.billing.catalog.api.CatalogApiException;
 import com.ning.billing.catalog.api.ICatalogService;
 import com.ning.billing.catalog.api.IPlan;
 import com.ning.billing.catalog.api.IPlanPhase;
@@ -107,7 +108,17 @@ public class EntitlementUserApi implements IEntitlementUserApi {
             throw new EntitlementUserApiException(ErrorCode.ENT_INVALID_REQUESTED_DATE, requestedDate.toString());
         }
 
-        IPlan plan = catalogService.getCatalog().getPlan(productName, term, realPriceList);
+        requestedDate = (requestedDate == null) ? now : requestedDate;
+
+        //TODO: Correctly handle exception
+        IPlan plan = null;
+		try {
+			plan = catalogService.getCatalog().findPlan(productName, term, realPriceList);
+		} catch (CatalogApiException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
         if (plan == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_BAD_CATALOG, productName, term, realPriceList);
         }
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 7348894..7aa359b 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
@@ -180,7 +180,15 @@ public class Subscription extends PrivateFields  implements ISubscription {
         		getCurrentPriceList(),
         		getCurrentPhase().getPhaseType());
 
-        ActionPolicy policy = catalog.getPlanCancelPolicy(planPhase);
+        //TODO: Correctly handle exception
+        ActionPolicy policy = null;
+		try {
+			policy = catalog.planCancelPolicy(planPhase);
+		} catch (CatalogApiException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
         DateTime effectiveDate = getPlanChangeEffectiveDate(policy, now);
 
         IEntitlementEvent cancelEvent = new ApiEventCancel(new ApiEventBuilder()
@@ -240,7 +248,7 @@ public class Subscription extends PrivateFields  implements ISubscription {
         PlanChangeResult planChangeResult = null;
         try {
 
-            IProduct destProduct = catalog.getProductFromName(productName);
+            IProduct destProduct = catalog.findProduct(productName);
             // STEPH really catalog exception
             if (destProduct == null) {
                 throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_BAD_CATALOG,
@@ -265,8 +273,16 @@ public class Subscription extends PrivateFields  implements ISubscription {
         ActionPolicy policy = planChangeResult.getPolicy();
         IPriceList newPriceList = planChangeResult.getNewPriceList();
 
-        IPlan newPlan = catalog.getPlan(productName, term, newPriceList.getName());
-        if (newPlan == null) {
+        //TODO: Correctly handle exception
+        IPlan newPlan = null;
+		try {
+			newPlan = catalog.findPlan(productName, term, newPriceList.getName());
+		} catch (CatalogApiException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		if (newPlan == null) {
             throw new EntitlementUserApiException(ErrorCode.ENT_CREATE_BAD_CATALOG,
                     productName, term.toString(), newPriceList.getName());
         }
@@ -522,12 +538,33 @@ public class Subscription extends PrivateFields  implements ISubscription {
                 throw new EntitlementError(String.format("Unexpected Event type = %s",
                         cur.getType()));
             }
-
-            IPlan previousPlan = catalog.getPlanFromName(previousPlanName);
-            IPlanPhase previousPhase = catalog.getPhaseFromName(previousPhaseName);
-            IPlan nextPlan = catalog.getPlanFromName(nextPlanName);
-            IPlanPhase nextPhase = catalog.getPhaseFromName(nextPhaseName);
-
+            
+            //TODO: Correctly handle exceptions
+            IPlan previousPlan = null;
+            IPlanPhase previousPhase = null;
+            IPlan nextPlan = null;
+            IPlanPhase nextPhase = null;
+            try {
+            	previousPlan = catalog.findPlan(previousPlanName);
+            } catch (CatalogApiException e) {
+            	// TODO: handle exception
+            }
+            try {
+            	previousPhase = catalog.findPhase(previousPhaseName);
+            } catch (CatalogApiException e) {
+                // TODO: handle exception
+			}
+            try {
+            	nextPlan = catalog.findPlan(nextPlanName);
+            } catch (CatalogApiException e) {
+            	// TODO: handle exception
+            }
+            try {
+            	nextPhase = catalog.findPhase(nextPhaseName);
+            } catch (CatalogApiException e) {
+            	// TODO: handle exception
+            }
+ 
             SubscriptionTransition transition =
                 new SubscriptionTransition(cur.getId(), id, bundleId, cur.getType(), apiEventType,
                         cur.getRequestedDate(), cur.getEffectiveDate(),
diff --git a/util/src/main/java/com/ning/billing/util/config/UriAccessor.java b/util/src/main/java/com/ning/billing/util/config/UriAccessor.java
new file mode 100644
index 0000000..e931837
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/config/UriAccessor.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.config;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Scanner;
+
+public class UriAccessor {
+	private static final String URI_SCHEME_FOR_CLASSPATH = "jar";
+	private static final String URI_SCHEME_FOR_FILE = "file";
+
+	public static InputStream accessUri(String uri)  throws IOException, URISyntaxException {
+		return accessUri(new URI(uri));
+	}
+	
+	public static InputStream accessUri(URI uri) throws IOException {
+		String scheme = uri.getScheme();
+        URL url = null;
+        if (scheme.equals(URI_SCHEME_FOR_CLASSPATH)) {
+        	return UriAccessor.class.getResourceAsStream(uri.getPath());
+        } else if (scheme.equals(URI_SCHEME_FOR_FILE) &&
+        	!uri.getSchemeSpecificPart().startsWith("/")) { // interpret URIs of this form as relative path uris
+        	url = new File(uri.getSchemeSpecificPart()).toURI().toURL();
+        }
+        url = uri.toURL();
+    	return url.openConnection().getInputStream();
+	}
+	
+	public static String accessUriAsString(String uri)  throws IOException, URISyntaxException {
+		return accessUriAsString(new URI(uri));
+	}
+	
+	public static String accessUriAsString(URI uri) throws IOException {
+		InputStream stream = accessUri(uri);
+		return new Scanner(stream).useDelimiter("\\A").next();
+	}
+}
diff --git a/util/src/main/java/com/ning/billing/util/config/XMLLoader.java b/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
index 8aaaf14..481447c 100644
--- a/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
+++ b/util/src/main/java/com/ning/billing/util/config/XMLLoader.java
@@ -16,12 +16,9 @@
 
 package com.ning.billing.util.config;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
 
 import javax.xml.XMLConstants;
 import javax.xml.bind.JAXBContext;
@@ -39,46 +36,27 @@ import org.xml.sax.SAXException;
 import com.ning.billing.catalog.api.InvalidConfigException;
 
 public class XMLLoader {
-	private static final String URI_SCHEME_FOR_CLASSPATH = "jar";
-	private static final String URI_SCHEME_FOR_FILE = "file";
 	public static Logger log = LoggerFactory.getLogger(XMLLoader.class);
 
-	public static <T extends ValidatingConfig<T>> T getObjectFromProperty(String property, Class<T> objectType) throws Exception {
-		if (property == null) {
+	public static <T extends ValidatingConfig<T>> T getObjectFromString(String uri, Class<T> objectType) throws Exception {
+		if (uri == null) {
 			return null;
 		}
-		log.info("Initializing an object of class " + objectType.getName() + " from xml file at: " + property);
+		log.info("Initializing an object of class " + objectType.getName() + " from xml file at: " + uri);
 					
-		return getObjectFromURI(new URI(property), objectType);
+		return getObjectFromStream(new URI(uri), UriAccessor.accessUri(uri), objectType);
 	}
 	
-	public static <T extends ValidatingConfig<T>> T getObjectFromURI(final URI uri, final Class<T> objectType) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, URISyntaxException {
-        String scheme = uri.getScheme();
-        URI uriToCall = uri;
-        if (scheme.equals(URI_SCHEME_FOR_CLASSPATH)) {
-        	InputStream resourceStream = XMLLoader.class.getResourceAsStream(uri.getPath());
-        	return getObjectFromStream(uri, resourceStream, objectType);
-        } else if (scheme.equals(URI_SCHEME_FOR_FILE) &&
-        	!uri.getSchemeSpecificPart().startsWith("/")) { // interpret URIs of this form as relative path uris
-        	uriToCall = new File(uri.getSchemeSpecificPart()).toURI();
-        }
-        return getObjectFromURL(uriToCall.toURL(), objectType);
-    }
-
-	public static <T extends ValidatingConfig<T>> T getObjectFromURL(URL url, Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException, URISyntaxException {
-        Object o = unmarshaller(clazz).unmarshal(url);
-    
-        if (clazz.isInstance(o)) {
-            @SuppressWarnings("unchecked")
-			T castObject = (T)o;
-            validate(url.toURI(),castObject);
-            return castObject;
-        } else {
-            return null;
-        }
-    }
-
-	public static <T extends ValidatingConfig<T>> T getObjectFromStream(URI uri,InputStream stream, Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException {
+	public static <T extends ValidatingConfig<T>> T getObjectFromUri(URI uri, Class<T> objectType) throws Exception {
+		if (uri == null) {
+			return null;
+		}
+		log.info("Initializing an object of class " + objectType.getName() + " from xml file at: " + uri);
+					
+		return getObjectFromStream(uri, UriAccessor.accessUri(uri), objectType);
+	}
+	
+	public static <T extends ValidatingConfig<T>> T getObjectFromStream(URI uri, InputStream stream, Class<T> clazz) throws SAXException, InvalidConfigException, JAXBException, IOException, TransformerException {
         Object o = unmarshaller(clazz).unmarshal(stream);
         if (clazz.isInstance(o)) {
         	@SuppressWarnings("unchecked")
@@ -88,9 +66,7 @@ public class XMLLoader {
         } else {
             return null;
         }
-    }
-
-    
+    } 
 
 	public static <T extends ValidatingConfig<T>> void validate(URI uri, T c) {
             c.initialize(c, uri);