killbill-memoizeit

Changes

pom.xml 2(+1 -1)

Details

diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
index 4635782..c314ac2 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationWithCatalogUpdate.java
@@ -101,7 +101,7 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
         final SimplePlanDescriptor desc1 = new DefaultSimplePlanDescriptor("foo-monthly", "Foo", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.MONTHLY, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of());
         catalogUserApi.addSimplePlan(desc1, init, testCallContext);
         StaticCatalog catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
-        assertEquals(catalog.getCurrentPlans().length, 1);
+        assertEquals(catalog.getCurrentPlans().size(), 1);
 
         final Entitlement baseEntitlement = createEntitlement("foo-monthly", true);
 
@@ -111,7 +111,7 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
         final SimplePlanDescriptor desc2 = new DefaultSimplePlanDescriptor("superfoo-monthly", "SuperFoo", ProductCategory.BASE, account.getCurrency(), new BigDecimal("20.00"), BillingPeriod.MONTHLY, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of());
         catalogUserApi.addSimplePlan(desc2, init, testCallContext);
         catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
-        assertEquals(catalog.getCurrentPlans().length, 2);
+        assertEquals(catalog.getCurrentPlans().size(), 2);
 
         // Change Plan to the newly added Plan and verify correct default rules behavior (IMMEDIATE change)
         busHandler.pushExpectedEvents(NextEvent.CHANGE, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT, NextEvent.PAYMENT);
@@ -131,8 +131,8 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
         final SimplePlanDescriptor desc1 = new DefaultSimplePlanDescriptor("xxx-monthly", "XXX", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.MONTHLY, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of());
         catalogUserApi.addSimplePlan(desc1, init, testCallContext);
         StaticCatalog catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
-        assertEquals(catalog.getCurrentProducts().length, 1);
-        assertEquals(catalog.getCurrentPlans().length, 1);
+        assertEquals(catalog.getCurrentProducts().size(), 1);
+        assertEquals(catalog.getCurrentPlans().size(), 1);
 
         final Entitlement baseEntitlement1 = createEntitlement("xxx-monthly", true);
 
@@ -140,8 +140,8 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
         final SimplePlanDescriptor desc2 = new DefaultSimplePlanDescriptor("xxx-14-monthly", "XXX", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.MONTHLY, 14, TimeUnit.DAYS, ImmutableList.<String>of());
         catalogUserApi.addSimplePlan(desc2, init, testCallContext);
         catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
-        assertEquals(catalog.getCurrentProducts().length, 1);
-        assertEquals(catalog.getCurrentPlans().length, 2);
+        assertEquals(catalog.getCurrentProducts().size(), 1);
+        assertEquals(catalog.getCurrentPlans().size(), 2);
 
         final Entitlement baseEntitlement2 = createEntitlement("xxx-14-monthly", false);
 
@@ -149,8 +149,8 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
         final SimplePlanDescriptor desc3 = new DefaultSimplePlanDescriptor("xxx-30-monthly", "XXX", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.MONTHLY, 30, TimeUnit.DAYS, ImmutableList.<String>of());
         catalogUserApi.addSimplePlan(desc3, init, testCallContext);
         catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
-        assertEquals(catalog.getCurrentProducts().length, 1);
-        assertEquals(catalog.getCurrentPlans().length, 3);
+        assertEquals(catalog.getCurrentProducts().size(), 1);
+        assertEquals(catalog.getCurrentPlans().size(), 3);
 
         final Entitlement baseEntitlement3 = createEntitlement("xxx-30-monthly", false);
 
@@ -172,12 +172,12 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
         final SimplePlanDescriptor desc1 = new DefaultSimplePlanDescriptor("zoe-monthly", "Zoe", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.MONTHLY, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of());
         catalogUserApi.addSimplePlan(desc1, init, testCallContext);
         StaticCatalog catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
-        assertEquals(catalog.getCurrentPlans().length, 1);
+        assertEquals(catalog.getCurrentPlans().size(), 1);
 
         final SimplePlanDescriptor desc2 = new DefaultSimplePlanDescriptor("zoe-14-monthly", "Zoe", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.MONTHLY, 14, TimeUnit.DAYS, ImmutableList.<String>of());
         catalogUserApi.addSimplePlan(desc2, init, testCallContext);
         catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
-        assertEquals(catalog.getCurrentPlans().length, 2);
+        assertEquals(catalog.getCurrentPlans().size(), 2);
 
         try {
             final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Zoe", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
@@ -195,9 +195,9 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
         final SimplePlanDescriptor desc1 = new DefaultSimplePlanDescriptor("bar-monthly", "Bar", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.MONTHLY, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of());
         catalogUserApi.addSimplePlan(desc1, init, testCallContext);
         StaticCatalog catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
-        assertEquals(catalog.getCurrentPlans().length, 1);
+        assertEquals(catalog.getCurrentPlans().size(), 1);
 
-        final Plan plan = catalog.getCurrentPlans()[0];
+        final Plan plan = catalog.getCurrentPlans().iterator().next();
         final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("bar-monthly", null);
 
         final List<PlanPhasePriceOverride> overrides = new ArrayList<PlanPhasePriceOverride>();
@@ -236,7 +236,7 @@ public class TestIntegrationWithCatalogUpdate extends TestIntegrationBase {
         final SimplePlanDescriptor desc1 = new DefaultSimplePlanDescriptor("thirty-monthly", "Thirty", ProductCategory.BASE, account.getCurrency(), BigDecimal.TEN, BillingPeriod.THIRTY_DAYS, 0, TimeUnit.UNLIMITED, ImmutableList.<String>of());
         catalogUserApi.addSimplePlan(desc1, init, testCallContext);
         StaticCatalog catalog = catalogUserApi.getCurrentCatalog("dummy", testCallContext);
-        assertEquals(catalog.getCurrentPlans().length, 1);
+        assertEquals(catalog.getCurrentPlans().size(), 1);
 
 
         final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("thirty-monthly", null);
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/CatalogEntityCollection.java b/catalog/src/main/java/org/killbill/billing/catalog/CatalogEntityCollection.java
new file mode 100644
index 0000000..b9bad42
--- /dev/null
+++ b/catalog/src/main/java/org/killbill/billing/catalog/CatalogEntityCollection.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2014-2016 Groupon, Inc
+ * Copyright 2014-2016 The Billing Project, LLC
+ *
+ * The Billing Project 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 org.killbill.billing.catalog;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.killbill.billing.catalog.api.CatalogEntity;
+
+import com.google.common.collect.Ordering;
+
+public class CatalogEntityCollection<T extends CatalogEntity> implements Collection<T> {
+
+    private final Map<String, T> data;
+
+    public CatalogEntityCollection() {
+        this.data = new TreeMap<String, T>(Ordering.<String>natural());
+    }
+
+    public CatalogEntityCollection(final T[] entities) {
+        this.data = new TreeMap<String, T>(Ordering.<String>natural());
+        for (final T cur : entities) {
+            addEntry(cur);
+        }
+    }
+
+
+    public CatalogEntityCollection(final Collection<T> entities) {
+        this.data = new TreeMap<String, T>(Ordering.<String>natural());
+        for (final T cur : entities) {
+            addEntry(cur);
+        }
+    }
+
+    //
+    // Returning such entries will be log(N)
+    //
+    public T findByName(final String entryName) {
+        return data.get(entryName);
+    }
+
+    public Collection<T> getEntries() {
+        return data.values();
+    }
+
+    @Override
+    public int size() {
+        return data.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return data.isEmpty();
+    }
+
+    @Override
+    public boolean contains(final Object o) {
+        return data.containsKey(((CatalogEntity) o).getName());
+    }
+
+    @Override
+    public Iterator iterator() {
+
+        // Build an iterator that will return ordered using natural ordering with regard to CatalogEntity#name
+        final Iterator<String> keyIterator = data.keySet().iterator();
+        final Iterator it = new Iterator() {
+            private String prevKey = null;
+            @Override
+            public boolean hasNext() {
+                return keyIterator.hasNext();
+            }
+            @Override
+            public Object next() {
+                prevKey = keyIterator.next();
+                return data.get(prevKey);
+            }
+            @Override
+            public void remove() {
+                if (prevKey != null) {
+                    keyIterator.remove();
+                    data.remove(prevKey);
+                }
+            }
+        };
+        return it;
+    }
+
+    @Override
+    public boolean add(final T t) {
+        addEntry(t);
+        return true;
+    }
+
+    @Override
+    public boolean remove(final Object o) {
+        return removeEntry((T) o);
+    }
+
+    @Override
+    public boolean addAll(final Collection c) {
+        final Iterator iterator = c.iterator();
+        while (iterator.hasNext()) {
+            final T cur = (T) iterator.next();
+            addEntry(cur);
+        }
+        return true;
+    }
+
+    @Override
+    public void clear() {
+        data.clear();
+    }
+
+    @Override
+    public boolean retainAll(final Collection c) {
+        throw new IllegalStateException("Not implemented");
+    }
+
+    @Override
+    public boolean removeAll(final Collection c) {
+        final Iterator iterator = c.iterator();
+        while (iterator.hasNext()) {
+            final CatalogEntity cur = (CatalogEntity) iterator.next();
+            data.remove(cur.getName());
+        }
+        return true;
+    }
+
+    @Override
+    public boolean containsAll(final Collection c) {
+        final Iterator iterator = c.iterator();
+        while (iterator.hasNext()) {
+            final CatalogEntity cur = (CatalogEntity) iterator.next();
+            if (!data.containsKey(cur.getName())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Object[] toArray(final Object[] a) {
+        return data.values().toArray(a);
+    }
+
+    @Override
+    public Object[] toArray() {
+        return data.values().toArray(new Object[data.size()]);
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof CatalogEntityCollection)) {
+            return false;
+        }
+
+        final CatalogEntityCollection<?> that = (CatalogEntityCollection<?>) o;
+        return data != null ? data.equals(that.data) : that.data == null;
+    }
+
+    @Override
+    public int hashCode() {
+        return data != null ? data.hashCode() : 0;
+    }
+
+    private void addEntry(final T entry) {
+        data.put(entry.getName(), entry);
+    }
+
+    private boolean removeEntry(final T entry) {
+        return data.remove(entry.getName()) != null;
+    }
+
+}
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/CatalogUpdater.java b/catalog/src/main/java/org/killbill/billing/catalog/CatalogUpdater.java
index fcfe43c..f8b61b6 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/CatalogUpdater.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/CatalogUpdater.java
@@ -29,9 +29,11 @@ import org.killbill.billing.catalog.api.BillingMode;
 import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.PhaseType;
+import org.killbill.billing.catalog.api.Plan;
 import org.killbill.billing.catalog.api.PlanAlignmentChange;
 import org.killbill.billing.catalog.api.PlanAlignmentCreate;
 import org.killbill.billing.catalog.api.PriceListSet;
+import org.killbill.billing.catalog.api.Product;
 import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.catalog.api.SimplePlanDescriptor;
 import org.killbill.billing.catalog.api.TimeUnit;
@@ -44,6 +46,8 @@ import org.killbill.billing.catalog.rules.DefaultCasePriceList;
 import org.killbill.billing.catalog.rules.DefaultPlanRules;
 import org.killbill.xmlloader.XMLWriter;
 
+import com.google.common.collect.ImmutableList;
+
 public class CatalogUpdater {
 
     private static URI DUMMY_URI;
@@ -53,7 +57,9 @@ public class CatalogUpdater {
             DUMMY_URI = new URI("dummy");
         } catch (URISyntaxException e) {
         }
-    };
+    }
+
+    ;
 
     private final DefaultMutableStaticCatalog catalog;
 
@@ -68,8 +74,8 @@ public class CatalogUpdater {
                 .setCatalogName(catalogName)
                 .setEffectiveDate(effectiveDate.toDate())
                 .setRecurringBillingMode(billingMode)
-                .setProducts(new DefaultProduct[0])
-                .setPlans(new DefaultPlan[0])
+                .setProducts(ImmutableList.<Product>of())
+                .setPlans(ImmutableList.<Plan>of())
                 .setPriceLists(new DefaultPriceListSet(defaultPriceList, new DefaultPriceList[0]))
                 .setPlanRules(getSaneDefaultPlanRules(defaultPriceList));
         if (currencies != null && currencies.length > 0) {
@@ -92,7 +98,6 @@ public class CatalogUpdater {
         }
     }
 
-
     public void addSimplePlanDescriptor(final SimplePlanDescriptor desc) throws CatalogApiException {
 
         // We need at least a planId
@@ -100,12 +105,12 @@ public class CatalogUpdater {
             throw new CatalogApiException(ErrorCode.CAT_INVALID_SIMPLE_PLAN_DESCRIPTOR, desc);
         }
 
-        DefaultPlan plan = getExistingPlan(desc.getPlanId());
+        DefaultPlan plan = (DefaultPlan) getExistingPlan(desc.getPlanId());
         if (plan == null && desc.getProductName() == null) {
             throw new CatalogApiException(ErrorCode.CAT_INVALID_SIMPLE_PLAN_DESCRIPTOR, desc);
         }
 
-        DefaultProduct product = plan != null ? (DefaultProduct) plan.getProduct() : getExistingProduct(desc.getProductName());
+        DefaultProduct product = plan != null ? (DefaultProduct) plan.getProduct() : (DefaultProduct)  getExistingProduct(desc.getProductName());
         if (product == null) {
             product = new DefaultProduct();
             product.setName(desc.getProductName());
@@ -171,9 +176,9 @@ public class CatalogUpdater {
 
         if (desc.getProductCategory() == ProductCategory.ADD_ON) {
             for (final String bp : desc.getAvailableBaseProducts()) {
-                final DefaultProduct targetBasePlan = getExistingProduct(bp);
+                final Product targetBasePlan = getExistingProduct(bp);
                 boolean found = false;
-                for (DefaultProduct cur : targetBasePlan.getAvailable()) {
+                for (Product cur : targetBasePlan.getAvailable()) {
                     if (cur.getName().equals(product.getName())) {
                         found = true;
                         break;
@@ -278,22 +283,20 @@ public class CatalogUpdater {
         }
     }
 
-    private DefaultProduct getExistingProduct(final String productName) {
-        for (final DefaultProduct input : catalog.getCurrentProducts()) {
-            if (input.getName().equals(productName)) {
-                return input;
-            }
+    private Product getExistingProduct(final String productName) {
+        try {
+            return catalog.findCurrentProduct(productName);
+        } catch (final CatalogApiException e) {
+            return null;
         }
-        return null;
     }
 
-    private DefaultPlan getExistingPlan(final String planName) {
-        for (final DefaultPlan input : catalog.getCurrentPlans()) {
-            if (input.getName().equals(planName)) {
-                return input;
-            }
+    private Plan getExistingPlan(final String planName) {
+        try {
+            return catalog.findCurrentPlan(planName);
+        } catch (CatalogApiException e) {
+            return null;
         }
-        return null;
     }
 
     private DefaultPlanRules getSaneDefaultPlanRules(final DefaultPriceList defaultPriceList) {
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultMutableStaticCatalog.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultMutableStaticCatalog.java
index 8e31268..8e83016 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultMutableStaticCatalog.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultMutableStaticCatalog.java
@@ -61,35 +61,16 @@ public class DefaultMutableStaticCatalog extends StandaloneCatalog implements Mu
 
     @Override
     public void addProduct(final Product product) throws CatalogApiException {
-        final Product[] newEntries = allocateNewEntries(getCurrentProducts(), product);
-        setProducts((DefaultProduct[]) newEntries);
+        getCatalogEntityCollectionProduct().add(product);
     }
 
     @Override
     public void addPlan(final Plan plan) throws CatalogApiException {
-        final Plan[] newEntries = allocateNewEntries(getCurrentPlans(), plan);
-        setPlans((DefaultPlan[]) newEntries);
 
-        final DefaultPriceList priceList = getPriceLists().findPriceListFrom(plan.getPriceListName());
-        final List<DefaultPlan> newPriceListPlan = new ArrayList<DefaultPlan>();
-        for (Plan input : newEntries) {
-            if (plan.getName().equals(input.getName())) {
-                newPriceListPlan.add((DefaultPlan) plan);
-                continue;
-            }
-            if (priceList.getPlans() != null) {
-                for (final Plan priceListPlan : priceList.getPlans()) {
-                    if (priceListPlan.getName().equals(input.getName())) {
-                        newPriceListPlan.add((DefaultPlan) priceListPlan);
-                        break;
-                    }
-                }
-            }
-        }
+        getCatalogEntityCollectionPlan().add(plan);
 
-        final Plan[] newPriceListEntries = new DefaultPlan[newPriceListPlan.size()];
-        final Plan[] bar = newPriceListPlan.toArray(newPriceListEntries);
-        priceList.setPlans((DefaultPlan[]) bar);
+        final DefaultPriceList priceList = getPriceLists().findPriceListFrom(plan.getPriceListName());
+        priceList.getCatalogEntityCollectionPlan().add(plan);
     }
 
     @Override
@@ -104,9 +85,8 @@ public class DefaultMutableStaticCatalog extends StandaloneCatalog implements Mu
         currentPrices.setPrices((DefaultPrice[]) newEntries);
     }
 
-    public void addProductAvailableAO(final DefaultProduct targetBasePlan, final DefaultProduct aoProduct) throws CatalogApiException {
-        final Product[] newEntries = allocateNewEntries(targetBasePlan.getAvailable(), aoProduct);
-        targetBasePlan.setAvailable((DefaultProduct[]) newEntries);
+    public void addProductAvailableAO(final Product targetBasePlan, final DefaultProduct aoProduct) throws CatalogApiException {
+        ((DefaultProduct) targetBasePlan).getCatalogEntityCollectionAvailable().add(aoProduct);
     }
 
     private <T> T[] allocateNewEntries(final T[] existingEntries, final T newEntry) throws CatalogApiException {
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
index 856fd91..b99ec4b 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
@@ -218,8 +218,8 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements 
         return this;
     }
 
-    public DefaultPlan setProduct(final DefaultProduct product) {
-        this.product = product;
+    public DefaultPlan setProduct(final Product product) {
+        this.product = (DefaultProduct) product;
         return this;
     }
 
@@ -314,11 +314,10 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements 
     }
 
     private String findPriceListForPlan(final StandaloneCatalog catalog) {
-        for (PriceList cur : catalog.getPriceLists().getAllPriceLists()) {
-            for (Plan p : cur.getPlans()) {
-                if (p.getName().equals(name)) {
-                    return ((DefaultPriceList) cur).getName();
-                }
+        for (final PriceList cur : catalog.getPriceLists().getAllPriceLists()) {
+            final DefaultPriceList curDefaultPriceList = (DefaultPriceList) cur;
+            if (curDefaultPriceList.findPlan(name) != null) {
+                return curDefaultPriceList.getName();
             }
         }
         throw new IllegalStateException("Cannot extract pricelist for plan " + name);
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
index 23d83cb..7335354 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
@@ -17,7 +17,7 @@
 package org.killbill.billing.catalog;
 
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -29,10 +29,10 @@ import javax.xml.bind.annotation.XmlID;
 import javax.xml.bind.annotation.XmlIDREF;
 
 import org.killbill.billing.catalog.api.BillingPeriod;
+import org.killbill.billing.catalog.api.Plan;
 import org.killbill.billing.catalog.api.PriceList;
 import org.killbill.billing.catalog.api.Product;
 import org.killbill.xmlloader.ValidatingConfig;
-import org.killbill.xmlloader.ValidationError;
 import org.killbill.xmlloader.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
@@ -44,22 +44,27 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
 
     @XmlElementWrapper(name = "plans", required = false)
     @XmlIDREF
-    @XmlElement(name = "plan", required = false)
-    private DefaultPlan[] plans;
+    @XmlElement(type=DefaultPlan.class, name = "plan", required = false)
+    private CatalogEntityCollection<Plan> plans;
 
     public DefaultPriceList() {
+        this.plans = new CatalogEntityCollection();
     }
 
     public DefaultPriceList(final DefaultPlan[] plans, final String name) {
-        this.plans = plans;
+        this.plans = new CatalogEntityCollection(plans);
         this.name = name;
     }
 
     @Override
-    public DefaultPlan[] getPlans() {
+    public Collection<Plan> getPlans() {
         return plans;
     }
 
+
+    public CatalogEntityCollection<Plan> getCatalogEntityCollectionPlan() {
+        return plans;
+    }
     /* (non-Javadoc)
       * @see org.killbill.billing.catalog.IPriceList#getName()
       */
@@ -72,15 +77,19 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
       * @see org.killbill.billing.catalog.IPriceList#findPlan(org.killbill.billing.catalog.api.IProduct, org.killbill.billing.catalog.api.BillingPeriod)
       */
     @Override
-    public DefaultPlan[] findPlans(final Product product, final BillingPeriod period) {
-        final List<DefaultPlan> result = new ArrayList<DefaultPlan>(plans.length);
-        for (final DefaultPlan cur : getPlans()) {
+    public Collection<Plan> findPlans(final Product product, final BillingPeriod period) {
+        final List<Plan> result = new ArrayList<Plan>(plans.size());
+        for (final Plan cur : getPlans()) {
             if (cur.getProduct().equals(product) &&
-                    (cur.getRecurringBillingPeriod() != null && cur.getRecurringBillingPeriod().equals(period))) {
+                (cur.getRecurringBillingPeriod() != null && cur.getRecurringBillingPeriod().equals(period))) {
                 result.add(cur);
             }
         }
-        return result.toArray(new DefaultPlan[result.size()]);
+        return result;
+    }
+
+    public Plan findPlan(final String planName) {
+        return plans.findByName(planName);
     }
 
     @Override
@@ -93,8 +102,8 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
         return this;
     }
 
-    public DefaultPriceList setPlans(final DefaultPlan[] plans) {
-        this.plans = plans;
+    public DefaultPriceList setPlans(final Collection<Plan> plans) {
+        this.plans = new CatalogEntityCollection(plans);
         return this;
     }
 
@@ -112,17 +121,16 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
         if (name != null ? !name.equals(that.name) : that.name != null) {
             return false;
         }
-        if (!Arrays.equals(plans, that.plans)) {
+        if (!plans.equals(that.plans)) {
             return false;
         }
-
         return true;
     }
 
     @Override
     public int hashCode() {
         int result = name != null ? name.hashCode() : 0;
-        result = 31 * result + (plans != null ? Arrays.hashCode(plans) : 0);
+        result = 31 * result + (plans != null ? plans.hashCode() : 0);
         return result;
     }
 }
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceListSet.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceListSet.java
index 7e0f5e0..c159833 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceListSet.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceListSet.java
@@ -21,11 +21,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.CatalogApiException;
+import org.killbill.billing.catalog.api.Plan;
 import org.killbill.billing.catalog.api.PriceList;
 import org.killbill.billing.catalog.api.PriceListSet;
 import org.killbill.billing.catalog.api.Product;
@@ -52,21 +54,21 @@ public class DefaultPriceListSet extends ValidatingConfig<StandaloneCatalog> imp
         this.childPriceLists = childPriceLists != null ? childPriceLists : new DefaultPriceList[0];
     }
 
-    public DefaultPlan getPlanFrom(final Product product, final BillingPeriod period, final String priceListName) throws CatalogApiException {
+    public Plan getPlanFrom(final Product product, final BillingPeriod period, final String priceListName) throws CatalogApiException {
 
-        DefaultPlan[] plans = null;
+        Collection<Plan> plans = null;
         final DefaultPriceList pl = findPriceListFrom(priceListName);
         if (pl != null) {
             plans = pl.findPlans(product, period);
         }
-        if (plans.length == 0) {
+        if (plans.size() == 0) {
             plans = defaultPricelist.findPlans(product, period);
         }
-        switch(plans.length) {
+        switch(plans.size()) {
             case 0:
                 return null;
             case 1:
-                return plans[0];
+                return plans.iterator().next();
             default:
                 throw new CatalogApiException(ErrorCode.CAT_MULTIPLE_MATCHING_PLANS_FOR_PRICELIST,
                                               priceListName, product.getName(), period);
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultProduct.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultProduct.java
index 91e4ffb..ffb8e96 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultProduct.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultProduct.java
@@ -18,6 +18,7 @@ package org.killbill.billing.catalog;
 
 import java.net.URI;
 import java.util.Arrays;
+import java.util.Collection;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
@@ -35,7 +36,6 @@ import org.killbill.xmlloader.ValidationErrors;
 
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implements Product {
-    private static final DefaultProduct[] EMPTY_PRODUCT_LIST = new DefaultProduct[0];
 
     @XmlAttribute(required = true)
     @XmlID
@@ -46,13 +46,13 @@ public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implemen
 
     @XmlElementWrapper(name = "included", required = false)
     @XmlIDREF
-    @XmlElement(name = "addonProduct", required = false)
-    private DefaultProduct[] included;
+    @XmlElement(type=DefaultProduct.class, name = "addonProduct", required = false)
+    private CatalogEntityCollection<Product> included;
 
     @XmlElementWrapper(name = "available", required = false)
     @XmlIDREF
-    @XmlElement(name = "addonProduct", required = false)
-    private DefaultProduct[] available;
+    @XmlElement(type=DefaultProduct.class, name = "addonProduct", required = false)
+    private CatalogEntityCollection<Product> available;
 
     @XmlElementWrapper(name = "limits", required = false)
     @XmlElement(name = "limit", required = false)
@@ -72,22 +72,29 @@ public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implemen
     }
 
     @Override
-    public DefaultProduct[] getIncluded() {
-        return included;
+    public Collection<Product> getIncluded() {
+        return included.getEntries();
     }
 
     @Override
-    public DefaultProduct[] getAvailable() {
-        return available;
+    public Collection<Product> getAvailable() {
+        return available.getEntries();
     }
 
+
+    public CatalogEntityCollection<Product> getCatalogEntityCollectionAvailable() {
+        return available;
+    };
+
     public DefaultProduct() {
-        included = EMPTY_PRODUCT_LIST;
-        available = EMPTY_PRODUCT_LIST;
-        limits = new DefaultLimit[0];
+        this.included = new CatalogEntityCollection<Product>();
+        this.available = new CatalogEntityCollection<Product>();
+        this.limits = new DefaultLimit[0];
     }
 
     public DefaultProduct(final String name, final ProductCategory category) {
+        this.included = new CatalogEntityCollection<Product>();
+        this.available = new CatalogEntityCollection<Product>();
         this.category = category;
         this.name = name;
     }
@@ -98,7 +105,7 @@ public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implemen
     }
 
     public boolean isIncluded(final DefaultProduct addon) {
-        for (final DefaultProduct p : included) {
+        for (final Product p : included.getEntries()) {
             if (addon == p) {
                 return true;
             }
@@ -107,7 +114,7 @@ public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implemen
     }
 
     public boolean isAvailable(final DefaultProduct addon) {
-        for (final DefaultProduct p : included) {
+        for (final Product p : included.getEntries()) {
             if (addon == p) {
                 return true;
             }
@@ -168,13 +175,13 @@ public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implemen
         return this;
     }
 
-    public DefaultProduct setIncluded(final DefaultProduct[] included) {
-        this.included = included;
+    public DefaultProduct setIncluded(final Collection<Product> included) {
+        this.included = new CatalogEntityCollection<Product>(included);
         return this;
     }
 
-    public DefaultProduct setAvailable(final DefaultProduct[] available) {
-        this.available = available;
+    public DefaultProduct setAvailable(final Collection<Product> available) {
+        this.available = new CatalogEntityCollection<Product>(available);
         return this;
     }
 
@@ -185,9 +192,14 @@ public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implemen
 
     @Override
     public String toString() {
-        return "DefaultProduct [name=" + name + ", category=" + category + ", included="
-                + Arrays.toString(included) + ", available=" + Arrays.toString(available) + ", catalogName="
-                + catalogName + "]";
+        return "DefaultProduct{" +
+               "name='" + name + '\'' +
+               ", category=" + category +
+               ", included=" + included +
+               ", available=" + available +
+               ", limits=" + Arrays.toString(limits) +
+               ", catalogName='" + catalogName + '\'' +
+               '}';
     }
 
     @Override
@@ -195,41 +207,40 @@ public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implemen
         if (this == o) {
             return true;
         }
-        if (o == null || getClass() != o.getClass()) {
+        if (!(o instanceof DefaultProduct)) {
             return false;
         }
 
-        final DefaultProduct that = (DefaultProduct) o;
+        final DefaultProduct product = (DefaultProduct) o;
 
-        if (!Arrays.equals(available, that.available)) {
-            return false;
-        }
-        if (catalogName != null ? !catalogName.equals(that.catalogName) : that.catalogName != null) {
+        if (name != null ? !name.equals(product.name) : product.name != null) {
             return false;
         }
-        if (category != that.category) {
+        if (category != product.category) {
             return false;
         }
-        if (!Arrays.equals(included, that.included)) {
+        if (included != null ? !included.equals(product.included) : product.included != null) {
             return false;
         }
-        if (!Arrays.equals(limits, that.limits)) {
+        if (available != null ? !available.equals(product.available) : product.available != null) {
             return false;
         }
-        if (name != null ? !name.equals(that.name) : that.name != null) {
+        // Probably incorrect - comparing Object[] arrays with Arrays.equals
+        if (!Arrays.equals(limits, product.limits)) {
             return false;
         }
+        return catalogName != null ? catalogName.equals(product.catalogName) : product.catalogName == null;
 
-        return true;
     }
 
     @Override
     public int hashCode() {
         int result = name != null ? name.hashCode() : 0;
         result = 31 * result + (category != null ? category.hashCode() : 0);
-        result = 31 * result + (included != null ? Arrays.hashCode(included) : 0);
-        result = 31 * result + (available != null ? Arrays.hashCode(available) : 0);
-        result = 31 * result + (limits != null ? Arrays.hashCode(limits) : 0);
+        result = 31 * result + (included != null ? included.hashCode() : 0);
+        result = 31 * result + (available != null ? available.hashCode() : 0);
+        result = 31 * result + Arrays.hashCode(limits);
+        result = 31 * result + (catalogName != null ? catalogName.hashCode() : 0);
         return result;
     }
 }
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/plugin/StandaloneCatalogMapper.java b/catalog/src/main/java/org/killbill/billing/catalog/plugin/StandaloneCatalogMapper.java
index 1b42d71..7c90442 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/plugin/StandaloneCatalogMapper.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/plugin/StandaloneCatalogMapper.java
@@ -19,6 +19,8 @@ package org.killbill.billing.catalog.plugin;
 
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 import javax.annotation.Nullable;
@@ -81,8 +83,8 @@ public class StandaloneCatalogMapper {
     private final String catalogName;
     private final BillingMode recurringBillingMode;
 
-    private Iterable<DefaultProduct> tmpDefaultProducts;
-    private Iterable<DefaultPlan> tmpDefaultPlans;
+    private Collection<Product> tmpDefaultProducts;
+    private Collection<Plan> tmpDefaultPlans;
     private DefaultPriceListSet tmpDefaultPriceListSet;
 
     public StandaloneCatalogMapper(final String catalogName, final BillingMode recurringBillingMode) {
@@ -105,10 +107,10 @@ public class StandaloneCatalogMapper {
         result.setPlanRules(toDefaultPlanRules(pluginCatalog.getPlanRules()));
 
         for (final Product cur : pluginCatalog.getProducts()) {
-            for (DefaultProduct target : result.getCurrentProducts()) {
+            for (Product target :  result.getCurrentProducts()) {
                 if (target.getName().equals(cur.getName())) {
-                    target.setAvailable(toFilteredDefaultProduct(ImmutableList.copyOf(cur.getAvailable())));
-                    target.setIncluded(toFilteredDefaultProduct(ImmutableList.copyOf(cur.getIncluded())));
+                    ((DefaultProduct) target).setAvailable(toFilteredDefaultProduct(ImmutableList.copyOf(cur.getAvailable())));
+                    ((DefaultProduct) target).setIncluded(toFilteredDefaultProduct(ImmutableList.copyOf(cur.getIncluded())));
                     break;
                 }
             }
@@ -250,22 +252,22 @@ public class StandaloneCatalogMapper {
     }
 
 
-    private DefaultProduct[] toDefaultProducts(final Iterable<Product> input) {
+    private Collection<Product> toDefaultProducts(final Iterable<Product> input) {
         if (tmpDefaultProducts == null) {
-            final Function<Product, DefaultProduct> productTransformer = new Function<Product, DefaultProduct>() {
+            final Function<Product, Product> productTransformer = new Function<Product, Product>() {
                 @Override
-                public DefaultProduct apply(final Product input) {
+                public Product apply(final Product input) {
                     return toDefaultProduct(input);
                 }
             };
-            tmpDefaultProducts = ImmutableList.copyOf(Iterables.transform(input, productTransformer));
+            tmpDefaultProducts = ImmutableList.<Product>copyOf(Iterables.transform(input, productTransformer));
         }
-        return toArray(tmpDefaultProducts);
+        return tmpDefaultProducts;
     }
 
-    private DefaultProduct[] toFilteredDefaultProduct(final Iterable<Product> input) {
+    private Collection<Product> toFilteredDefaultProduct(final Iterable<Product> input) {
         if (!input.iterator().hasNext()) {
-            return new DefaultProduct[0];
+            return Collections.emptyList();
         }
         final List<String> inputProductNames = ImmutableList.copyOf(Iterables.transform(input, new Function<Product, String>() {
             @Override
@@ -273,33 +275,33 @@ public class StandaloneCatalogMapper {
                 return input.getName();
             }
         }));
-        final List<DefaultProduct> filteredAndOrdered = new ArrayList<DefaultProduct>(inputProductNames.size());
+        final Collection<Product> filteredAndOrdered = new ArrayList<Product>(inputProductNames.size());
         for (final String cur : inputProductNames) {
-            final DefaultProduct found = findOrIllegalState(tmpDefaultProducts, new Predicate<DefaultProduct>() {
+            final Product found = findOrIllegalState(tmpDefaultProducts, new Predicate<Product>() {
                 @Override
-                public boolean apply(final DefaultProduct inputPredicate) {
+                public boolean apply(final Product inputPredicate) {
                     return inputPredicate.getName().equals(cur);
                 }
             }, "Failed to find product " + cur);
             filteredAndOrdered.add(found);
         }
-        return toArray(filteredAndOrdered);
+        return filteredAndOrdered;
     }
 
-    private DefaultPlan[] toDefaultPlans(final Iterable<Plan> input) {
+    private Collection<Plan> toDefaultPlans(final Iterable<Plan> input) {
         if (tmpDefaultPlans == null) {
-            final Function<Plan, DefaultPlan> planTransformer = new Function<Plan, DefaultPlan>() {
+            final Function<Plan, Plan> planTransformer = new Function<Plan, Plan>() {
                 @Override
-                public DefaultPlan apply(final Plan input) {
+                public Plan apply(final Plan input) {
                     return toDefaultPlan(input);
                 }
             };
-            tmpDefaultPlans = ImmutableList.copyOf(Iterables.transform(input, planTransformer));
+            tmpDefaultPlans = ImmutableList.<Plan>copyOf(Iterables.transform(input, planTransformer));
         }
-        return toArray(tmpDefaultPlans);
+        return tmpDefaultPlans;
     }
 
-    private DefaultPlan[] toFilterDefaultPlans(final Iterable<Plan> input) {
+    private Collection<Plan> toFilterDefaultPlans(final Iterable<Plan> input) {
         if (tmpDefaultPlans == null) {
             throw new IllegalStateException("Cannot filter on uninitialized plans");
         }
@@ -309,17 +311,17 @@ public class StandaloneCatalogMapper {
                 return input.getName();
             }
         }));
-        final List<DefaultPlan> filteredAndOrdered = new ArrayList<DefaultPlan>(inputPlanNames.size());
+        final List<Plan> filteredAndOrdered = new ArrayList<Plan>(inputPlanNames.size());
         for (final String cur : inputPlanNames) {
-            final DefaultPlan found = findOrIllegalState(tmpDefaultPlans, new Predicate<DefaultPlan>() {
+            final Plan found = findOrIllegalState(tmpDefaultPlans, new Predicate<Plan>() {
                 @Override
-                public boolean apply(final DefaultPlan inputPredicate) {
+                public boolean apply(final Plan inputPredicate) {
                     return inputPredicate.getName().equals(cur);
                 }
             }, "Failed to find plan " + cur);
             filteredAndOrdered.add(found);
         }
-        return toArray(filteredAndOrdered);
+        return filteredAndOrdered;
     }
 
     private DefaultPriceListSet toDefaultPriceListSet(final PriceList defaultPriceList, final Iterable<PriceList> childrenPriceLists) {
@@ -395,14 +397,14 @@ public class StandaloneCatalogMapper {
         return result;
     }
 
-    private DefaultProduct toDefaultProduct(@Nullable final Product input) {
+    private Product toDefaultProduct(@Nullable final Product input) {
         if (input == null) {
             return null;
         }
         if (tmpDefaultProducts != null) {
-            final DefaultProduct existingProduct = findOrIllegalState(tmpDefaultProducts, new Predicate<DefaultProduct>() {
+            final Product existingProduct = findOrIllegalState(tmpDefaultProducts, new Predicate<Product>() {
                 @Override
-                public boolean apply(final DefaultProduct predicateInput) {
+                public boolean apply(final Product predicateInput) {
                     return predicateInput.getName().equals(input.getName());
                 }
             }, "Unknown product " + input.getName());
@@ -415,11 +417,11 @@ public class StandaloneCatalogMapper {
         return result;
     }
 
-    private DefaultPlan toDefaultPlan(final Plan input) {
+    private Plan toDefaultPlan(final Plan input) {
         if (tmpDefaultPlans != null) {
-            final DefaultPlan existingPlan = findOrIllegalState(tmpDefaultPlans, new Predicate<DefaultPlan>() {
+            final Plan existingPlan = findOrIllegalState(tmpDefaultPlans, new Predicate<Plan>() {
                 @Override
-                public boolean apply(final DefaultPlan predicateInput) {
+                public boolean apply(final Plan predicateInput) {
                     return predicateInput.getName().equals(input.getName());
                 }
             }, "Unknown plan " + input.getName());
@@ -513,4 +515,4 @@ public class StandaloneCatalogMapper {
         }
         return result;
     }
-}
+}
\ No newline at end of file
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCase.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCase.java
index 49f5267..de0bef2 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCase.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCase.java
@@ -92,7 +92,7 @@ public abstract class DefaultCase<T> extends ValidatingConfig<StandaloneCatalog>
         return errors;
     }
 
-    protected abstract DefaultCase<T> setProduct(DefaultProduct product);
+    protected abstract DefaultCase<T> setProduct(Product product);
 
     protected abstract DefaultCase<T> setProductCategory(ProductCategory productCategory);
 
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java
index a046406..ea441bd 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseChange.java
@@ -154,8 +154,8 @@ public abstract class DefaultCaseChange<T> extends ValidatingConfig<StandaloneCa
         return this;
     }
 
-    public DefaultCaseChange<T> setFromProduct(final DefaultProduct fromProduct) {
-        this.fromProduct = fromProduct;
+    public DefaultCaseChange<T> setFromProduct(final Product fromProduct) {
+        this.fromProduct = (DefaultProduct) fromProduct;
         return this;
     }
 
@@ -174,8 +174,8 @@ public abstract class DefaultCaseChange<T> extends ValidatingConfig<StandaloneCa
         return this;
     }
 
-    public DefaultCaseChange<T> setToProduct(final DefaultProduct toProduct) {
-        this.toProduct = toProduct;
+    public DefaultCaseChange<T> setToProduct(final Product toProduct) {
+        this.toProduct = (DefaultProduct) toProduct;
         return this;
     }
 
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseStandardNaming.java b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseStandardNaming.java
index e922b0e..79c73aa 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseStandardNaming.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/rules/DefaultCaseStandardNaming.java
@@ -22,6 +22,7 @@ import javax.xml.bind.annotation.XmlIDREF;
 import org.killbill.billing.catalog.DefaultPriceList;
 import org.killbill.billing.catalog.DefaultProduct;
 import org.killbill.billing.catalog.api.BillingPeriod;
+import org.killbill.billing.catalog.api.Product;
 import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.catalog.api.rules.Case;
 
@@ -59,8 +60,8 @@ public abstract class DefaultCaseStandardNaming<T> extends DefaultCase<T> implem
         return priceList;
     }
 
-    public DefaultCaseStandardNaming<T> setProduct(final DefaultProduct product) {
-        this.product = product;
+    public DefaultCaseStandardNaming<T> setProduct(final Product product) {
+        this.product = (DefaultProduct) product;
         return this;
     }
 
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
index a2795e3..0511e71 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalog.java
@@ -19,6 +19,7 @@ package org.killbill.billing.catalog;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
@@ -76,15 +77,15 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
     private DefaultUnit[] units;
 
     @XmlElementWrapper(name = "products", required = false)
-    @XmlElement(name = "product", required = false)
-    private DefaultProduct[] products;
+    @XmlElement(type=DefaultProduct.class, name = "product", required = false)
+    private CatalogEntityCollection<Product> products;
 
     @XmlElement(name = "rules", required = true)
     private DefaultPlanRules planRules;
 
     @XmlElementWrapper(name = "plans", required = false)
-    @XmlElement(name = "plan", required = false)
-    private DefaultPlan[] plans;
+    @XmlElement(type=DefaultPlan.class, name = "plan", required = false)
+    private CatalogEntityCollection<Plan> plans;
 
     @XmlElement(name = "priceLists", required = true)
     private DefaultPriceListSet priceLists;
@@ -92,6 +93,8 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
     private URI catalogURI;
 
     public StandaloneCatalog() {
+        this.plans = new CatalogEntityCollection<Plan>();
+        this.products = new CatalogEntityCollection<Product>();
     }
 
     protected StandaloneCatalog(final Date effectiveDate) {
@@ -120,7 +123,12 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
      * @see org.killbill.billing.catalog.ICatalog#getProducts()
      */
     @Override
-    public DefaultProduct[] getCurrentProducts() {
+    public Collection<Product> getCurrentProducts() {
+        return products.getEntries();
+    }
+
+
+    public CatalogEntityCollection<Product>  getCatalogEntityCollectionProduct() {
         return products;
     }
 
@@ -137,14 +145,21 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         return supportedCurrencies;
     }
 
+
+
     @Override
-    public DefaultPlan[] getCurrentPlans() {
+    public Collection<Plan> getCurrentPlans() {
+        return plans.getEntries();
+    }
+
+
+    public CatalogEntityCollection<Plan> getCatalogEntityCollectionPlan() {
         return plans;
     }
 
     public boolean isTemplateCatalog() {
-        return (products == null || products.length == 0) &&
-               (plans == null || plans.length == 0) &&
+        return (products == null || products.size() == 0) &&
+               (plans == null || plans.size() == 0) &&
                (supportedCurrencies == null || supportedCurrencies.length == 0);
     }
 
@@ -168,8 +183,8 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
       * @see org.killbill.billing.catalog.ICatalog#getPlan(java.lang.String, java.lang.String)
       */
     @Override
-    public DefaultPlan createOrFindCurrentPlan(final PlanSpecifier spec, final PlanPhasePriceOverridesWithCallContext unused) throws CatalogApiException {
-        final DefaultPlan result;
+    public Plan createOrFindCurrentPlan(final PlanSpecifier spec, final PlanPhasePriceOverridesWithCallContext unused) throws CatalogApiException {
+        final Plan result;
         if (spec.getPlanName() != null) {
             result = findCurrentPlan(spec.getPlanName());
         } else {
@@ -198,10 +213,9 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         if (name == null || plans == null) {
             throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PLAN, name);
         }
-        for (final DefaultPlan p : plans) {
-            if (p.getName().equals(name)) {
-                return p;
-            }
+        final DefaultPlan result = (DefaultPlan) plans.findByName(name);
+        if (result != null) {
+            return result;
         }
         throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PLAN, name);
     }
@@ -211,10 +225,9 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         if (name == null || products == null) {
             throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PRODUCT, name);
         }
-        for (final DefaultProduct p : products) {
-            if (p.getName().equals(name)) {
-                return p;
-            }
+        final Product result = products.findByName(name);
+        if (result != null) {
+            return result;
         }
         throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PRODUCT, name);
     }
@@ -224,7 +237,6 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         if (name == null || plans == null) {
             throw new CatalogApiException(ErrorCode.CAT_NO_SUCH_PHASE, name);
         }
-
         final String planName = DefaultPlanPhase.planName(name);
         final Plan plan = findCurrentPlan(planName);
         return plan.findPhase(name);
@@ -236,7 +248,6 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         if (name == null || priceLists == null) {
             throw new CatalogApiException(ErrorCode.CAT_PRICE_LIST_NOT_FOUND, name);
         }
-
         return priceLists.findPriceListFrom(name);
     }
 
@@ -278,8 +289,8 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
 
     @Override
     public ValidationErrors validate(final StandaloneCatalog catalog, final ValidationErrors errors) {
-        validateCollection(catalog, errors, products);
-        validateCollection(catalog, errors, plans);
+        validateCollection(catalog, errors, (DefaultProduct[])  products.toArray(new DefaultProduct[products.size()]));
+        validateCollection(catalog, errors, (DefaultPlan[])  plans.toArray(new DefaultPlan[plans.size()]));
         priceLists.validate(catalog, errors);
         planRules.validate(catalog, errors);
         return errors;
@@ -291,11 +302,11 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         super.initialize(catalog, sourceURI);
         planRules.initialize(catalog, sourceURI);
         priceLists.initialize(catalog, sourceURI);
-        for (final DefaultProduct p : products) {
-            p.initialize(catalog, sourceURI);
+        for (final Product p : products.getEntries()) {
+            ((DefaultProduct)p).initialize(catalog, sourceURI);
         }
-        for (final DefaultPlan p : plans) {
-            p.initialize(catalog, sourceURI);
+        for (final Plan p : plans.getEntries()) {
+            ((DefaultPlan) p).initialize(catalog, sourceURI);
         }
     }
 
@@ -312,8 +323,8 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         return phase.compliesWithLimits(unit, value);
     }
 
-    public StandaloneCatalog setProducts(final DefaultProduct[] products) {
-        this.products = products;
+    public StandaloneCatalog setProducts(final Collection<Product> products) {
+        this.products = new CatalogEntityCollection<Product>(products);
         return this;
     }
 
@@ -322,8 +333,8 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         return this;
     }
 
-    public StandaloneCatalog setPlans(final DefaultPlan[] plans) {
-        this.plans = plans;
+    public StandaloneCatalog setPlans(final Collection<Plan> plans) {
+        this.plans = new CatalogEntityCollection<Plan>(plans);
         return this;
     }
 
@@ -379,7 +390,7 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
                     for (BillingPeriod billingPeriod : BillingPeriod.values()) {
                         for (PriceList priceList : getPriceLists().getAllPriceLists()) {
                             if (priceListName == null || priceListName.equals(priceList.getName())) {
-                                Plan[] addonInList = priceList.findPlans(availAddon, billingPeriod);
+                                Collection<Plan> addonInList = priceList.findPlans(availAddon, billingPeriod);
                                 for (Plan cur : addonInList) {
                                     availAddons.add(new DefaultListing(cur, priceList));
                                 }
@@ -391,7 +402,6 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         } catch (CatalogApiException e) {
             // No such product - just return an empty list
         }
-
         return availAddons;
     }
 
@@ -437,13 +447,13 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         if (planRules != null ? !planRules.equals(that.planRules) : that.planRules != null) {
             return false;
         }
-        if (!Arrays.equals(plans, that.plans)) {
+        if (!plans.equals(that.plans)) {
             return false;
         }
         if (priceLists != null ? !priceLists.equals(that.priceLists) : that.priceLists != null) {
             return false;
         }
-        if (!Arrays.equals(products, that.products)) {
+        if (!products.equals(that.products)) {
             return false;
         }
         if (recurringBillingMode != that.recurringBillingMode) {
@@ -455,7 +465,6 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         if (!Arrays.equals(units, that.units)) {
             return false;
         }
-
         return true;
     }
 
@@ -466,9 +475,9 @@ public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> imple
         result = 31 * result + (recurringBillingMode != null ? recurringBillingMode.hashCode() : 0);
         result = 31 * result + (supportedCurrencies != null ? Arrays.hashCode(supportedCurrencies) : 0);
         result = 31 * result + (units != null ? Arrays.hashCode(units) : 0);
-        result = 31 * result + (products != null ? Arrays.hashCode(products) : 0);
+        result = 31 * result + (products != null ? products.hashCode() : 0);
         result = 31 * result + (planRules != null ? planRules.hashCode() : 0);
-        result = 31 * result + (plans != null ? Arrays.hashCode(plans) : 0);
+        result = 31 * result + (plans != null ? plans.hashCode() : 0);
         result = 31 * result + (priceLists != null ? priceLists.hashCode() : 0);
         result = 31 * result + (catalogURI != null ? catalogURI.hashCode() : 0);
         return result;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalogWithPriceOverride.java b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalogWithPriceOverride.java
index fbffc1f..8a42e4b 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalogWithPriceOverride.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/StandaloneCatalogWithPriceOverride.java
@@ -70,8 +70,8 @@ public class StandaloneCatalogWithPriceOverride extends StandaloneCatalog implem
 
 
     @Override
-    public DefaultPlan createOrFindCurrentPlan(final PlanSpecifier spec, final PlanPhasePriceOverridesWithCallContext overrides) throws CatalogApiException {
-        final DefaultPlan defaultPlan = super.createOrFindCurrentPlan(spec, null);
+    public Plan createOrFindCurrentPlan(final PlanSpecifier spec, final PlanPhasePriceOverridesWithCallContext overrides) throws CatalogApiException {
+        final Plan defaultPlan = super.createOrFindCurrentPlan(spec, null);
         if (overrides == null ||
             overrides.getOverrides() == null ||
             overrides.getOverrides().isEmpty()) {
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java b/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java
index ea97bcb..fbf5591 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/VersionedCatalog.java
@@ -20,6 +20,7 @@ package org.killbill.billing.catalog;
 
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
@@ -249,7 +250,7 @@ public class VersionedCatalog extends ValidatingConfig<VersionedCatalog> impleme
     }
 
     @Override
-    public DefaultProduct[] getProducts(final DateTime requestedDate) throws CatalogApiException {
+    public Collection<Product> getProducts(final DateTime requestedDate) throws CatalogApiException {
         return versionForDate(requestedDate).getCurrentProducts();
     }
 
@@ -259,7 +260,7 @@ public class VersionedCatalog extends ValidatingConfig<VersionedCatalog> impleme
     }
 
     @Override
-    public DefaultPlan[] getPlans(final DateTime requestedDate) throws CatalogApiException {
+    public Collection<Plan> getPlans(final DateTime requestedDate) throws CatalogApiException {
         return versionForDate(requestedDate).getCurrentPlans();
     }
 
@@ -435,7 +436,7 @@ public class VersionedCatalog extends ValidatingConfig<VersionedCatalog> impleme
     }
 
     @Override
-    public Product[] getCurrentProducts() throws CatalogApiException {
+    public Collection<Product> getCurrentProducts() throws CatalogApiException {
         return versionForDate(clock.getUTCNow()).getCurrentProducts();
     }
 
@@ -445,7 +446,7 @@ public class VersionedCatalog extends ValidatingConfig<VersionedCatalog> impleme
     }
 
     @Override
-    public Plan[] getCurrentPlans() throws CatalogApiException {
+    public Collection<Plan> getCurrentPlans() throws CatalogApiException {
         return versionForDate(clock.getUTCNow()).getCurrentPlans();
     }
 
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/caching/TestEhCacheCatalogCache.java b/catalog/src/test/java/org/killbill/billing/catalog/caching/TestEhCacheCatalogCache.java
index a5e675b..dca3946 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/caching/TestEhCacheCatalogCache.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/caching/TestEhCacheCatalogCache.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -33,6 +34,7 @@ import org.killbill.billing.catalog.StandaloneCatalog;
 import org.killbill.billing.catalog.StandaloneCatalogWithPriceOverride;
 import org.killbill.billing.catalog.VersionedCatalog;
 import org.killbill.billing.catalog.api.CatalogApiException;
+import org.killbill.billing.catalog.api.Product;
 import org.killbill.xmlloader.UriAccessor;
 import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
@@ -83,8 +85,8 @@ public class TestEhCacheCatalogCache extends CatalogTestSuiteNoDB {
 
         final VersionedCatalog result = catalogCache.getCatalog(true, true, internalCallContext);
         Assert.assertNotNull(result);
-        final DefaultProduct[] products = result.getProducts(clock.getUTCNow());
-        Assert.assertEquals(products.length, 3);
+        final Collection<Product> products = result.getProducts(clock.getUTCNow());
+        Assert.assertEquals(products.size(), 3);
 
         // Verify the lookup with other contexts
         final VersionedCatalog resultForMultiTenantContext = new VersionedCatalog(result.getClock());
@@ -155,14 +157,14 @@ public class TestEhCacheCatalogCache extends CatalogTestSuiteNoDB {
         // Verify the lookup for this tenant
         final VersionedCatalog result = catalogCache.getCatalog(true, true, multiTenantContext);
         Assert.assertNotNull(result);
-        final DefaultProduct[] products = result.getProducts(clock.getUTCNow());
-        Assert.assertEquals(products.length, 6);
+        final Collection<Product> products = result.getProducts(clock.getUTCNow());
+        Assert.assertEquals(products.size(), 6);
 
         // Verify the lookup for another tenant
         final VersionedCatalog otherResult = catalogCache.getCatalog(true, true, otherMultiTenantContext);
         Assert.assertNotNull(otherResult);
-        final DefaultProduct[] otherProducts = otherResult.getProducts(clock.getUTCNow());
-        Assert.assertEquals(otherProducts.length, 3);
+        final Collection<Product> otherProducts = otherResult.getProducts(clock.getUTCNow());
+        Assert.assertEquals(otherProducts.size(), 3);
 
         shouldThrow.set(true);
 
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLWriter.java b/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLWriter.java
index 5d7966f..b431e9a 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLWriter.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/io/TestXMLWriter.java
@@ -117,7 +117,7 @@ public class TestXMLWriter extends CatalogTestSuiteNoDB {
 
         final String newCatalogStr = XMLWriter.writeXML((StandaloneCatalog) mutableCatalog, StandaloneCatalog.class);
         final StandaloneCatalog newCatalog = XMLLoader.getObjectFromStream(new URI("dummy"), new ByteArrayInputStream(newCatalogStr.getBytes(Charset.forName("UTF-8"))), StandaloneCatalog.class);
-        assertEquals(newCatalog.getCurrentPlans().length, catalog.getCurrentPlans().length + 1);
+        assertEquals(newCatalog.getCurrentPlans().size(), catalog.getCurrentPlans().size() + 1);
 
         final Plan plan = newCatalog.findCurrentPlan("dynamic-monthly");
         assertEquals(plan.getName(), "dynamic-monthly");
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/MockCatalog.java b/catalog/src/test/java/org/killbill/billing/catalog/MockCatalog.java
index ca6adad..5c788a0 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/MockCatalog.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/MockCatalog.java
@@ -16,16 +16,19 @@
 
 package org.killbill.billing.catalog;
 
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Date;
-import java.util.Set;
+import java.util.Iterator;
+import java.util.LinkedList;
 
 import org.joda.time.DateTime;
-
 import org.killbill.billing.catalog.api.BillingActionPolicy;
 import org.killbill.billing.catalog.api.BillingAlignment;
-import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.Catalog;
 import org.killbill.billing.catalog.api.CatalogApiException;
+import org.killbill.billing.catalog.api.CatalogEntity;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.Plan;
 import org.killbill.billing.catalog.api.PlanAlignmentChange;
@@ -44,6 +47,8 @@ import org.killbill.billing.catalog.rules.DefaultCaseChangePlanPolicy;
 import org.killbill.billing.catalog.rules.DefaultCaseCreateAlignment;
 import org.killbill.billing.catalog.rules.DefaultPlanRules;
 
+import com.google.common.collect.ImmutableList;
+
 public class MockCatalog extends StandaloneCatalog implements Catalog {
 
     private static final String[] PRODUCT_NAMES = new String[]{"TestProduct1", "TestProduct2", "TestProduct3"};
@@ -55,7 +60,7 @@ public class MockCatalog extends StandaloneCatalog implements Catalog {
     public MockCatalog() {
         setEffectiveDate(new Date());
         setProducts(MockProduct.createAll());
-        setPlans((DefaultPlan[]) MockPlan.createAll());
+        setPlans(MockPlan.createAll());
         populateRules();
         populatePriceLists();
     }
@@ -74,14 +79,19 @@ public class MockCatalog extends StandaloneCatalog implements Catalog {
     }
 
     public void populatePriceLists() {
-        final DefaultPlan[] plans = getCurrentPlans();
-
-        final DefaultPriceList[] priceList = new DefaultPriceList[plans.length - 1];
-        for (int i = 1; i < plans.length; i++) {
-            priceList[i - 1] = new DefaultPriceList(new DefaultPlan[]{plans[i]}, plans[i].getName() + "-pl");
+        final Collection<Plan> plans = getCurrentPlans();
+
+        final DefaultPriceList[] priceList = new DefaultPriceList[plans.size() - 1];
+        int i = 1;
+        final Iterator<Plan> it = plans.iterator();
+        final Plan initialPlan = it.next();
+        while (it.hasNext()) {
+            final Plan plan = it.next();
+            priceList[i - 1] = new DefaultPriceList(new DefaultPlan[] { (DefaultPlan) plan}, plan.getName() + "-pl");
+            i++;
         }
 
-        final DefaultPriceListSet set = new DefaultPriceListSet(new PriceListDefault(new DefaultPlan[]{plans[0]}), priceList);
+        final DefaultPriceListSet set = new DefaultPriceListSet(new PriceListDefault(new DefaultPlan[]{(DefaultPlan) initialPlan}), priceList);
         setPriceLists(set);
     }
 
@@ -100,12 +110,12 @@ public class MockCatalog extends StandaloneCatalog implements Catalog {
     }
 
     @Override
-    public Product[] getProducts(final DateTime requestedDate) throws CatalogApiException {
+    public Collection<Product> getProducts(final DateTime requestedDate) throws CatalogApiException {
         return getCurrentProducts();
     }
 
     @Override
-    public Plan[] getPlans(final DateTime requestedDate) throws CatalogApiException {
+    public Collection<Plan> getPlans(final DateTime requestedDate) throws CatalogApiException {
         return getCurrentPlans();
     }
 
@@ -235,6 +245,23 @@ public class MockCatalog extends StandaloneCatalog implements Catalog {
         return canCreatePlan;
     }
 
+
+    public DefaultProduct getCurrentProduct(int idx) {
+        return (DefaultProduct) getCurrentProducts().toArray()[idx];
+    }
+
+    private <T extends CatalogEntity> void convertCurrentEntries(final Collection<T> unordered, final T [] result) {
+        // Tests are not so well written and make assumption on how such entries are ordered
+        final LinkedList<T> list = new LinkedList<T>(unordered);
+        Collections.sort(list, new Comparator<T>() {
+            @Override
+            public int compare(final T o1, final T o2) {
+                return o1.getName().compareTo(o2.getName());
+            }
+        });
+        list.toArray(result);
+    }
+
     public void setCanCreatePlan(final boolean canCreatePlan) {
         this.canCreatePlan = canCreatePlan;
     }
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/MockPlan.java b/catalog/src/test/java/org/killbill/billing/catalog/MockPlan.java
index e77c761..54a95ba 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/MockPlan.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/MockPlan.java
@@ -16,10 +16,16 @@
 
 package org.killbill.billing.catalog;
 
+import java.util.Collection;
+
+import org.killbill.billing.catalog.api.Plan;
+
+import com.google.common.collect.ImmutableList;
+
 public class MockPlan extends DefaultPlan {
 
     public static MockPlan createBicycleTrialEvergreen1USD(final int trialDurationInDays) {
-        return new MockPlan("BicycleTrialEvergreen1USD",
+        return new MockPlan("1-BicycleTrialEvergreen1USD",
                             MockProduct.createBicycle(),
                             new DefaultPlanPhase[]{MockPlanPhase.createTrial(trialDurationInDays)},
                             MockPlanPhase.create1USDMonthlyEvergreen(),
@@ -27,7 +33,7 @@ public class MockPlan extends DefaultPlan {
     }
 
     public static MockPlan createBicycleTrialEvergreen1USD() {
-        return new MockPlan("BicycleTrialEvergreen1USD",
+        return new MockPlan("1-BicycleTrialEvergreen1USD",
                             MockProduct.createBicycle(),
                             new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial()},
                             MockPlanPhase.create1USDMonthlyEvergreen(),
@@ -35,7 +41,7 @@ public class MockPlan extends DefaultPlan {
     }
 
     public static MockPlan createSportsCarTrialEvergreen100USD() {
-        return new MockPlan("SportsCarTrialEvergreen100USD",
+        return new MockPlan("4-SportsCarTrialEvergreen100USD",
                             MockProduct.createSportsCar(),
                             new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial()},
                             MockPlanPhase.createUSDMonthlyEvergreen("100.00", null),
@@ -43,7 +49,7 @@ public class MockPlan extends DefaultPlan {
     }
 
     public static MockPlan createPickupTrialEvergreen10USD() {
-        return new MockPlan("PickupTrialEvergreen10USD",
+        return new MockPlan("3-PickupTrialEvergreen10USD",
                             MockProduct.createPickup(),
                             new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial()},
                             MockPlanPhase.createUSDMonthlyEvergreen("10.00", null),
@@ -51,7 +57,7 @@ public class MockPlan extends DefaultPlan {
     }
 
     public static MockPlan createJetTrialEvergreen1000USD() {
-        return new MockPlan("JetTrialEvergreen1000USD",
+        return new MockPlan("5-JetTrialEvergreen1000USD",
                             MockProduct.createJet(),
                             new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial()},
                             MockPlanPhase.create1USDMonthlyEvergreen(),
@@ -59,7 +65,7 @@ public class MockPlan extends DefaultPlan {
     }
 
     public static MockPlan createJetTrialFixedTermEvergreen1000USD() {
-        return new MockPlan("JetTrialEvergreen1000USD",
+        return new MockPlan("6-JetTrialEvergreen1000USD",
                             MockProduct.createJet(),
                             new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial(), MockPlanPhase.createUSDMonthlyFixedTerm("500.00", null, 6)},
                             MockPlanPhase.create1USDMonthlyEvergreen(),
@@ -67,7 +73,7 @@ public class MockPlan extends DefaultPlan {
     }
 
     public static MockPlan createHornMonthlyNoTrial1USD() {
-        return new MockPlan("Horn1USD",
+        return new MockPlan("7-Horn1USD",
                             MockProduct.createHorn(),
                             new DefaultPlanPhase[]{},
                             MockPlanPhase.create1USDMonthlyEvergreen(),
@@ -75,7 +81,7 @@ public class MockPlan extends DefaultPlan {
     }
 
     public MockPlan() {
-        this("BicycleTrialEvergreen1USD",
+        this("1-BicycleTrialEvergreen1USD",
              MockProduct.createBicycle(),
              new DefaultPlanPhase[]{MockPlanPhase.create30DayTrial()},
              MockPlanPhase.create1USDMonthlyEvergreen(),
@@ -96,7 +102,7 @@ public class MockPlan extends DefaultPlan {
     }
 
     public static MockPlan createBicycleNoTrialEvergreen1USD() {
-        return new MockPlan("BicycleNoTrialEvergreen1USD",
+        return new MockPlan("2-BicycleNoTrialEvergreen1USD",
                             MockProduct.createBicycle(),
                             new DefaultPlanPhase[]{},
                             MockPlanPhase.createUSDMonthlyEvergreen("1.0", null),
@@ -119,16 +125,14 @@ public class MockPlan extends DefaultPlan {
         setPlansAllowedInBundle(1);
     }
 
-    public static DefaultPlan[] createAll() {
-        return new DefaultPlan[]{
-                createBicycleTrialEvergreen1USD(),
-                createBicycleNoTrialEvergreen1USD(),
-                createPickupTrialEvergreen10USD(),
-                createSportsCarTrialEvergreen100USD(),
-                createJetTrialEvergreen1000USD(),
-                createJetTrialFixedTermEvergreen1000USD(),
-                createHornMonthlyNoTrial1USD()
-        };
+    public static Collection<Plan> createAll() {
+        return ImmutableList.<Plan>of(createBicycleTrialEvergreen1USD(),
+                               createBicycleNoTrialEvergreen1USD(),
+                               createPickupTrialEvergreen10USD(),
+                               createSportsCarTrialEvergreen100USD(),
+                               createJetTrialEvergreen1000USD(),
+                               createJetTrialFixedTermEvergreen1000USD(),
+                               createHornMonthlyNoTrial1USD());
     }
 
 
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/MockProduct.java b/catalog/src/test/java/org/killbill/billing/catalog/MockProduct.java
index f0a718e..5693004 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/MockProduct.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/MockProduct.java
@@ -16,8 +16,13 @@
 
 package org.killbill.billing.catalog;
 
+import java.util.Collection;
+
+import org.killbill.billing.catalog.api.Product;
 import org.killbill.billing.catalog.api.ProductCategory;
 
+import com.google.common.collect.ImmutableList;
+
 public class MockProduct extends DefaultProduct {
 
     public MockProduct() {
@@ -33,23 +38,23 @@ public class MockProduct extends DefaultProduct {
     }
 
     public static MockProduct createBicycle() {
-        return new MockProduct("Bicycle", ProductCategory.BASE, "Vehcles");
+        return new MockProduct("1-Bicycle", ProductCategory.BASE, "Vehcles");
     }
 
     public static MockProduct createPickup() {
-        return new MockProduct("Pickup", ProductCategory.BASE, "Vehcles");
+        return new MockProduct("2-Pickup", ProductCategory.BASE, "Vehcles");
     }
 
     public static MockProduct createSportsCar() {
-        return new MockProduct("SportsCar", ProductCategory.BASE, "Vehcles");
+        return new MockProduct("3-SportsCar", ProductCategory.BASE, "Vehcles");
     }
 
     public static MockProduct createJet() {
-        return new MockProduct("Jet", ProductCategory.BASE, "Vehcles");
+        return new MockProduct("4-Jet", ProductCategory.BASE, "Vehcles");
     }
 
     public static MockProduct createHorn() {
-        return new MockProduct("Horn", ProductCategory.ADD_ON, "Vehcles");
+        return new MockProduct("5-Horn", ProductCategory.ADD_ON, "Vehcles");
     }
 
     public static MockProduct createSpotlight() {
@@ -57,18 +62,17 @@ public class MockProduct extends DefaultProduct {
     }
 
     public static MockProduct createRedPaintJob() {
-        return new MockProduct("RedPaintJob", ProductCategory.ADD_ON, "Vehcles");
+        return new MockProduct("6-RedPaintJob", ProductCategory.ADD_ON, "Vehcles");
     }
 
-    public static DefaultProduct[] createAll() {
-        return new MockProduct[]{
+    public static Collection<Product> createAll() {
+        return ImmutableList.<Product>of(
                 createBicycle(),
                 createPickup(),
                 createSportsCar(),
                 createJet(),
                 createHorn(),
-                createRedPaintJob()
-        };
+                createRedPaintJob());
     }
 
 
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCase.java b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCase.java
index 93774c4..6f55bcb 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCase.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCase.java
@@ -19,6 +19,7 @@ package org.killbill.billing.catalog.rules;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlIDREF;
 
+import org.killbill.billing.catalog.api.Product;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -84,8 +85,8 @@ public class TestCase extends CatalogTestSuiteNoDB {
             return priceList;
         }
 
-        protected DefaultCaseResult setProduct(final DefaultProduct product) {
-            this.product = product;
+        protected DefaultCaseResult setProduct(final Product product) {
+            this.product = (DefaultProduct) product;
             return this;
         }
 
@@ -109,7 +110,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
     public void testBasic() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -120,7 +121,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, cat.getCurrentProduct(1).getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
         assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), cat);
         assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", cat);
     }
@@ -129,7 +130,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
     public void testWildCardProduct() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -141,7 +142,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertion(Result.FOO, cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertion(Result.FOO, cr, cat.getCurrentProduct(1).getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
         assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), cat);
         assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", cat);
     }
@@ -150,7 +151,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
     public void testWildCardProductCategory() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -162,7 +163,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, cat.getCurrentProduct(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);
         assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", cat);
@@ -172,7 +173,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
     public void testWildCardBillingPeriod() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -184,7 +185,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, cat.getCurrentProduct(1).getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), cat);
         assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", cat);
     }
@@ -193,7 +194,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
     public void testWildCardPriceList() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -205,7 +206,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
-        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), cat);
+        assertionNull(cr, cat.getCurrentProduct(1).getName(), ProductCategory.BASE, 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);
     }
@@ -214,7 +215,7 @@ public class TestCase extends CatalogTestSuiteNoDB {
     public void testCaseOrder() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
         final DefaultCaseResult cr0 = new DefaultCaseResult(
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCaseChange.java b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCaseChange.java
index e207fff..6528a3f 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCaseChange.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCaseChange.java
@@ -71,10 +71,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testBasic() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr = new DefaultCaseChangeResult(
@@ -92,14 +92,14 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
                   PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      cat.getCurrentProduct(1).getName(), product2.getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
                       PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      product1.getName(), cat.getCurrentProduct(1).getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -122,13 +122,13 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           cat.getCurrentProduct(1).getName(), priceList2.getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           priceList1.getName(), cat.getCurrentProduct(1).getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
@@ -143,10 +143,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testWildcardFromProduct() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr = new DefaultCaseChangeResult(
@@ -164,14 +164,14 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
                   PhaseType.EVERGREEN, cat);
 
         assertion(Result.FOO, cr,
-                  cat.getCurrentProducts()[1].getName(), product2.getName(),
+                  cat.getCurrentProduct(1).getName(), product2.getName(),
                   BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                   priceList1.getName(), priceList2.getName(),
                   PhaseType.EVERGREEN, cat);
 
 
         assertionNull(cr,
-                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      product1.getName(), cat.getCurrentProduct(1).getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.ANNUAL, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -187,13 +187,13 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           cat.getCurrentProduct(1).getName(), priceList2.getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           priceList1.getName(), cat.getCurrentProduct(1).getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
@@ -208,10 +208,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testWildcardToProduct() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr = new DefaultCaseChangeResult(
@@ -229,7 +229,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
                   PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      cat.getCurrentProduct(1).getName(), product2.getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -237,7 +237,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
 
 
         assertion(Result.FOO, cr,
-                  product1.getName(), cat.getCurrentProducts()[1].getName(),
+                  product1.getName(), cat.getCurrentProduct(1).getName(),
                   BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                   priceList1.getName(), priceList2.getName(),
                   PhaseType.EVERGREEN, cat);
@@ -259,13 +259,13 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           cat.getCurrentProduct(1).getName(), priceList2.getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           priceList1.getName(), cat.getCurrentProduct(1).getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
@@ -280,10 +280,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testWildcardFromProductCategory() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr = new DefaultCaseChangeResult(
@@ -301,14 +301,14 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
                   PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      cat.getCurrentProduct(1).getName(), product2.getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
                       PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      product1.getName(), cat.getCurrentProduct(1).getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -337,13 +337,13 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           cat.getCurrentProduct(1).getName(), priceList2.getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           priceList1.getName(), cat.getCurrentProduct(1).getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
@@ -358,10 +358,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testWildcardToProductCategory() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr = new DefaultCaseChangeResult(
@@ -379,14 +379,14 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
                   PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      cat.getCurrentProduct(1).getName(), product2.getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
                       PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      product1.getName(), cat.getCurrentProduct(1).getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -416,13 +416,13 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           cat.getCurrentProduct(1).getName(), priceList2.getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           priceList1.getName(), cat.getCurrentProduct(1).getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
@@ -437,10 +437,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testWildcardFromBillingPeriod() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr = new DefaultCaseChangeResult(
@@ -458,14 +458,14 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
                   PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      cat.getCurrentProduct(1).getName(), product2.getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
                       PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      product1.getName(), cat.getCurrentProduct(1).getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -487,13 +487,13 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           cat.getCurrentProduct(1).getName(), priceList2.getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           priceList1.getName(), cat.getCurrentProduct(1).getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
@@ -508,10 +508,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testWildCardToBillingPeriod() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr = new DefaultCaseChangeResult(
@@ -529,7 +529,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
                   PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      cat.getCurrentProduct(1).getName(), product2.getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -537,7 +537,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
 
 
         assertionNull(cr,
-                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      product1.getName(), cat.getCurrentProduct(1).getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -559,13 +559,13 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           cat.getCurrentProduct(1).getName(), priceList2.getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           priceList1.getName(), cat.getCurrentProduct(1).getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
@@ -580,10 +580,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testWildCardFromPriceList() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr = new DefaultCaseChangeResult(
@@ -601,7 +601,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
                   PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      cat.getCurrentProduct(1).getName(), product2.getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -609,7 +609,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
 
 
         assertionNull(cr,
-                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      product1.getName(), cat.getCurrentProduct(1).getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -638,7 +638,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           priceList1.getName(), cat.getCurrentProduct(1).getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
@@ -653,10 +653,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testWildcardToPriceList() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr = new DefaultCaseChangeResult(
@@ -674,7 +674,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
                   PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      cat.getCurrentProduct(1).getName(), product2.getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -682,7 +682,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
 
 
         assertionNull(cr,
-                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      product1.getName(), cat.getCurrentProduct(1).getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -705,7 +705,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           cat.getCurrentProduct(1).getName(), priceList2.getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertion(Result.FOO, cr,
@@ -726,10 +726,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testWildcardPlanPhase() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr = new DefaultCaseChangeResult(
@@ -747,7 +747,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
                   PhaseType.EVERGREEN, cat);
 
         assertionNull(cr,
-                      cat.getCurrentProducts()[1].getName(), product2.getName(),
+                      cat.getCurrentProduct(1).getName(), product2.getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -755,7 +755,7 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
 
 
         assertionNull(cr,
-                      product1.getName(), cat.getCurrentProducts()[1].getName(),
+                      product1.getName(), cat.getCurrentProduct(1).getName(),
                       ProductCategory.BASE, ProductCategory.BASE,
                       BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
                       priceList1.getName(), priceList2.getName(),
@@ -778,13 +778,13 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           cat.getCurrentProducts()[1].getName(), priceList2.getName(),
+                           cat.getCurrentProduct(1).getName(), priceList2.getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertionException(cr,
                            product1.getName(), product2.getName(),
                            BillingPeriod.MONTHLY, BillingPeriod.MONTHLY,
-                           priceList1.getName(), cat.getCurrentProducts()[1].getName(),
+                           priceList1.getName(), cat.getCurrentProduct(1).getName(),
                            PhaseType.EVERGREEN, cat);
 
         assertion(Result.FOO, cr,
@@ -798,10 +798,10 @@ public class TestCaseChange extends CatalogTestSuiteNoDB {
     public void testOrder() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        final DefaultProduct product2 = cat.getCurrentProducts()[2];
+        final DefaultProduct product2 = cat.getCurrentProduct(2);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[1];
 
         final DefaultCaseChangeResult cr0 = new DefaultCaseChangeResult(
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCasePhase.java b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCasePhase.java
index 22ecc52..2db00d3 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCasePhase.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestCasePhase.java
@@ -61,7 +61,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
     public void testBasic() {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -73,7 +73,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, cat.getCurrentProduct(1).getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
         assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
         assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
         assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
@@ -83,7 +83,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
     public void testWildCardProduct() {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -95,7 +95,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-        assertion(Result.FOO, cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertion(Result.FOO, cr, cat.getCurrentProduct(1).getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
         assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
         assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
         assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
@@ -105,7 +105,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
     public void testWildCardProductCategory() {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -117,7 +117,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, cat.getCurrentProduct(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);
         assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
@@ -128,7 +128,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
     public void testWildCardBillingPeriod() {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -140,7 +140,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, cat.getCurrentProduct(1).getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
         assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
         assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
@@ -150,7 +150,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
     public void testWildCardPriceList() {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -162,7 +162,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, cat.getCurrentProduct(1).getName(), ProductCategory.BASE, 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);
         assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
@@ -172,7 +172,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
     public void testWildCardPhaseType() {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
         final DefaultCaseResult cr = new DefaultCaseResult(
@@ -184,7 +184,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
                 Result.FOO);
 
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
-        assertionNull(cr, cat.getCurrentProducts()[1].getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
+        assertionNull(cr, cat.getCurrentProduct(1).getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.EVERGREEN, cat);
         assertionNull(cr, product.getName(), ProductCategory.BASE, BillingPeriod.ANNUAL, priceList.getName(), PhaseType.EVERGREEN, cat);
         assertionException(cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, "dipsy", PhaseType.EVERGREEN, cat);
         assertion(Result.FOO, cr, product.getName(), ProductCategory.BASE, BillingPeriod.MONTHLY, priceList.getName(), PhaseType.TRIAL, cat);
@@ -194,7 +194,7 @@ public class TestCasePhase extends CatalogTestSuiteNoDB {
     public void testOrder() throws CatalogApiException {
         final MockCatalog cat = new MockCatalog();
 
-        final DefaultProduct product = cat.getCurrentProducts()[0];
+        final DefaultProduct product = cat.getCurrentProduct(0);
         final DefaultPriceList priceList = cat.getPriceLists().getDefaultPricelist();
 
         final DefaultCaseResult cr0 = new DefaultCaseResult(
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestPlanRules.java b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestPlanRules.java
index 66fa6bf..950ea45 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/rules/TestPlanRules.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/rules/TestPlanRules.java
@@ -57,7 +57,7 @@ public class TestPlanRules extends CatalogTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testExistingPriceListIsKept() throws CatalogApiException {
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
         final PlanPhaseSpecifier from = new PlanPhaseSpecifier(product1.getName(), BillingPeriod.MONTHLY, priceList1.getName(), PhaseType.EVERGREEN);
@@ -79,8 +79,8 @@ public class TestPlanRules extends CatalogTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testBaseCase() throws CatalogApiException {
-        final DefaultProduct product1 = cat.getCurrentProducts()[0];
-        final DefaultProduct product2 = cat.getCurrentProducts()[1];
+        final DefaultProduct product1 = cat.getCurrentProduct(0);
+        final DefaultProduct product2 = cat.getCurrentProduct(1);
         final DefaultPriceList priceList1 = cat.findCurrentPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
         final DefaultPriceList priceList2 = cat.getPriceLists().getChildPriceLists()[0];
 
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/TestCatalogUpdater.java b/catalog/src/test/java/org/killbill/billing/catalog/TestCatalogUpdater.java
index 6f2af55..a973ad1 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/TestCatalogUpdater.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/TestCatalogUpdater.java
@@ -20,7 +20,6 @@ package org.killbill.billing.catalog;
 import java.io.ByteArrayInputStream;
 import java.math.BigDecimal;
 import java.net.URI;
-import java.net.URISyntaxException;
 import java.nio.charset.Charset;
 
 import org.joda.time.DateTime;
@@ -59,11 +58,10 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
         final CatalogUpdater catalogUpdater = new CatalogUpdater("dummy", BillingMode.IN_ADVANCE, now, null);
         final String catalogXML = catalogUpdater.getCatalogXML();
         final StandaloneCatalog catalog = XMLLoader.getObjectFromStream(new URI("dummy"), new ByteArrayInputStream(catalogXML.getBytes(Charset.forName("UTF-8"))), StandaloneCatalog.class);
-        assertEquals(catalog.getCurrentPlans().length, 0);
+        assertEquals(catalog.getCurrentPlans().size(), 0);
     }
 
-
-        @Test(groups = "fast")
+    @Test(groups = "fast")
     public void testAddNoTrialPlanOnFirstCatalog() throws CatalogApiException {
 
         final DateTime now = clock.getUTCNow();
@@ -75,13 +73,13 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
 
         final StandaloneCatalog catalog = catalogUpdater.getCatalog();
 
-        assertEquals(catalog.getCurrentProducts().length, 1);
+        assertEquals(catalog.getCurrentProducts().size(), 1);
 
-        final Product product = catalog.getCurrentProducts()[0];
+        final Product product = catalog.getCurrentProducts().iterator().next();
         assertEquals(product.getName(), "Foo");
         assertEquals(product.getCategory(), ProductCategory.BASE);
 
-        assertEquals(catalog.getCurrentPlans().length, 1);
+        assertEquals(catalog.getCurrentPlans().size(), 1);
 
         final Plan plan = catalog.findCurrentPlan("foo-monthly");
         assertEquals(plan.getName(), "foo-monthly");
@@ -99,8 +97,8 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
         assertEquals(catalog.getPriceLists().getAllPriceLists().size(), 1);
         final PriceList priceList = catalog.getPriceLists().getAllPriceLists().get(0);
         assertEquals(priceList.getName(), new PriceListDefault().getName());
-        assertEquals(priceList.getPlans().length, 1);
-        assertEquals(priceList.getPlans()[0].getName(), "foo-monthly");
+        assertEquals(priceList.getPlans().size(), 1);
+        assertEquals(priceList.getPlans().iterator().next().getName(), "foo-monthly");
     }
 
 
@@ -116,13 +114,13 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
 
         final StandaloneCatalog catalog = catalogUpdater.getCatalog();
 
-        assertEquals(catalog.getCurrentProducts().length, 1);
+        assertEquals(catalog.getCurrentProducts().size(), 1);
 
-        final Product product = catalog.getCurrentProducts()[0];
+        final Product product = catalog.getCurrentProducts().iterator().next();
         assertEquals(product.getName(), "Foo");
         assertEquals(product.getCategory(), ProductCategory.BASE);
 
-        assertEquals(catalog.getCurrentPlans().length, 1);
+        assertEquals(catalog.getCurrentPlans().size(), 1);
 
         final Plan plan = catalog.findCurrentPlan("foo-monthly");
         assertEquals(plan.getName(), "foo-monthly");
@@ -146,8 +144,8 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
         assertEquals(catalog.getPriceLists().getAllPriceLists().size(), 1);
         final PriceList priceList = catalog.getPriceLists().getAllPriceLists().get(0);
         assertEquals(priceList.getName(), new PriceListDefault().getName());
-        assertEquals(priceList.getPlans().length, 1);
-        assertEquals(priceList.getPlans()[0].getName(), "foo-monthly");
+        assertEquals(priceList.getPlans().size(), 1);
+        assertEquals(priceList.getPlans().iterator().next().getName(), "foo-monthly");
     }
 
 
@@ -158,7 +156,7 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
         final StandaloneCatalog originalCatalog = XMLLoader.getObjectFromString(Resources.getResource("SpyCarBasic.xml").toExternalForm(), StandaloneCatalog.class);
         assertEquals(originalCatalog.getPriceLists().getAllPriceLists().size(), 1);
         assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getName(), new PriceListDefault().getName());
-        assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getPlans().length, 3);
+        assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getPlans().size(), 3);
 
         final CatalogUpdater catalogUpdater = new CatalogUpdater(originalCatalog);
 
@@ -183,7 +181,7 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
         assertEquals(catalog.getPriceLists().getAllPriceLists().size(), 1);
         final PriceList priceList = catalog.getPriceLists().getAllPriceLists().get(0);
         assertEquals(priceList.getName(), new PriceListDefault().getName());
-        assertEquals(priceList.getPlans().length, 4);
+        assertEquals(priceList.getPlans().size(), 4);
     }
 
 
@@ -193,7 +191,7 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
         final StandaloneCatalog originalCatalog = XMLLoader.getObjectFromString(Resources.getResource("SpyCarBasic.xml").toExternalForm(), StandaloneCatalog.class);
         assertEquals(originalCatalog.getPriceLists().getAllPriceLists().size(), 1);
         assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getName(), new PriceListDefault().getName());
-        assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getPlans().length, 3);
+        assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getPlans().size(), 3);
 
         final CatalogUpdater catalogUpdater = new CatalogUpdater(originalCatalog);
 
@@ -224,7 +222,7 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
         final StandaloneCatalog originalCatalog = enhanceOriginalCatalogForInvalidTestCases("SpyCarBasic.xml");
         assertEquals(originalCatalog.getPriceLists().getAllPriceLists().size(), 1);
         assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getName(), new PriceListDefault().getName());
-        assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getPlans().length, 5);
+        assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getPlans().size(), 5);
 
         CatalogUpdater catalogUpdater = new CatalogUpdater(originalCatalog);
 
@@ -265,7 +263,7 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
         final StandaloneCatalog originalCatalog = XMLLoader.getObjectFromString(Resources.getResource("SpyCarBasic.xml").toExternalForm(), StandaloneCatalog.class);
         assertEquals(originalCatalog.getPriceLists().getAllPriceLists().size(), 1);
         assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getName(), new PriceListDefault().getName());
-        assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getPlans().length, 3);
+        assertEquals(originalCatalog.getPriceLists().getAllPriceLists().get(0).getPlans().size(), 3);
 
         final CatalogUpdater catalogUpdater = new CatalogUpdater(originalCatalog);
 
@@ -282,7 +280,7 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "        <currency>GBP</currency>\n" +
                                    "    </currencies>\n" +
                                    "    <products>\n" +
-                                   "        <product name=\"Standard\">\n" +
+                                   "        <product name=\"Dynamic\">\n" +
                                    "            <category>BASE</category>\n" +
                                    "            <included/>\n" +
                                    "            <available/>\n" +
@@ -294,13 +292,13 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "            <available/>\n" +
                                    "            <limits/>\n" +
                                    "        </product>\n" +
-                                   "        <product name=\"Super\">\n" +
+                                   "        <product name=\"Standard\">\n" +
                                    "            <category>BASE</category>\n" +
                                    "            <included/>\n" +
                                    "            <available/>\n" +
                                    "            <limits/>\n" +
                                    "        </product>\n" +
-                                   "        <product name=\"Dynamic\">\n" +
+                                   "        <product name=\"Super\">\n" +
                                    "            <category>BASE</category>\n" +
                                    "            <included/>\n" +
                                    "            <available/>\n" +
@@ -340,13 +338,13 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "        </priceList>\n" +
                                    "    </rules>\n" +
                                    "    <plans>\n" +
-                                   "        <plan name=\"standard-monthly\">\n" +
-                                   "            <product>Standard</product>\n" +
+                                   "        <plan name=\"dynamic-annual\">\n" +
+                                   "            <product>Dynamic</product>\n" +
                                    "            <initialPhases>\n" +
                                    "                <phase type=\"TRIAL\">\n" +
                                    "                    <duration>\n" +
                                    "                        <unit>DAYS</unit>\n" +
-                                   "                        <number>30</number>\n" +
+                                   "                        <number>14</number>\n" +
                                    "                    </duration>\n" +
                                    "                    <fixed type=\"ONE_TIME\">\n" +
                                    "                        <fixedPrice>\n" +
@@ -354,10 +352,6 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "<currency>USD</currency>\n" +
                                    "<value>0</value>\n" +
                                    "                            </price>\n" +
-                                   "                            <price>\n" +
-                                   "<currency>GBP</currency>\n" +
-                                   "<value>0</value>\n" +
-                                   "                            </price>\n" +
                                    "                        </fixedPrice>\n" +
                                    "                    </fixed>\n" +
                                    "                    <usages/>\n" +
@@ -372,12 +366,8 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "                    <billingPeriod>MONTHLY</billingPeriod>\n" +
                                    "                    <recurringPrice>\n" +
                                    "                        <price>\n" +
-                                   "                            <currency>GBP</currency>\n" +
-                                   "                            <value>75.00</value>\n" +
-                                   "                        </price>\n" +
-                                   "                        <price>\n" +
                                    "                            <currency>USD</currency>\n" +
-                                   "                            <value>100.00</value>\n" +
+                                   "                            <value>10</value>\n" +
                                    "                        </price>\n" +
                                    "                    </recurringPrice>\n" +
                                    "                </recurring>\n" +
@@ -430,8 +420,8 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "            </finalPhase>\n" +
                                    "            <plansAllowedInBundle>-1</plansAllowedInBundle>\n" +
                                    "        </plan>\n" +
-                                   "        <plan name=\"super-monthly\">\n" +
-                                   "            <product>Super</product>\n" +
+                                   "        <plan name=\"standard-monthly\">\n" +
+                                   "            <product>Standard</product>\n" +
                                    "            <initialPhases>\n" +
                                    "                <phase type=\"TRIAL\">\n" +
                                    "                    <duration>\n" +
@@ -463,11 +453,11 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "                    <recurringPrice>\n" +
                                    "                        <price>\n" +
                                    "                            <currency>GBP</currency>\n" +
-                                   "                            <value>750.00</value>\n" +
+                                   "                            <value>75.00</value>\n" +
                                    "                        </price>\n" +
                                    "                        <price>\n" +
                                    "                            <currency>USD</currency>\n" +
-                                   "                            <value>1000.00</value>\n" +
+                                   "                            <value>100.00</value>\n" +
                                    "                        </price>\n" +
                                    "                    </recurringPrice>\n" +
                                    "                </recurring>\n" +
@@ -475,13 +465,13 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "            </finalPhase>\n" +
                                    "            <plansAllowedInBundle>-1</plansAllowedInBundle>\n" +
                                    "        </plan>\n" +
-                                   "        <plan name=\"dynamic-annual\">\n" +
-                                   "            <product>Dynamic</product>\n" +
+                                   "        <plan name=\"super-monthly\">\n" +
+                                   "            <product>Super</product>\n" +
                                    "            <initialPhases>\n" +
                                    "                <phase type=\"TRIAL\">\n" +
                                    "                    <duration>\n" +
                                    "                        <unit>DAYS</unit>\n" +
-                                   "                        <number>14</number>\n" +
+                                   "                        <number>30</number>\n" +
                                    "                    </duration>\n" +
                                    "                    <fixed type=\"ONE_TIME\">\n" +
                                    "                        <fixedPrice>\n" +
@@ -489,6 +479,10 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "<currency>USD</currency>\n" +
                                    "<value>0</value>\n" +
                                    "                            </price>\n" +
+                                   "                            <price>\n" +
+                                   "<currency>GBP</currency>\n" +
+                                   "<value>0</value>\n" +
+                                   "                            </price>\n" +
                                    "                        </fixedPrice>\n" +
                                    "                    </fixed>\n" +
                                    "                    <usages/>\n" +
@@ -503,8 +497,12 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "                    <billingPeriod>MONTHLY</billingPeriod>\n" +
                                    "                    <recurringPrice>\n" +
                                    "                        <price>\n" +
+                                   "                            <currency>GBP</currency>\n" +
+                                   "                            <value>750.00</value>\n" +
+                                   "                        </price>\n" +
+                                   "                        <price>\n" +
                                    "                            <currency>USD</currency>\n" +
-                                   "                            <value>10</value>\n" +
+                                   "                            <value>1000.00</value>\n" +
                                    "                        </price>\n" +
                                    "                    </recurringPrice>\n" +
                                    "                </recurring>\n" +
@@ -516,10 +514,10 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "    <priceLists>\n" +
                                    "        <defaultPriceList name=\"DEFAULT\">\n" +
                                    "            <plans>\n" +
-                                   "                <plan>standard-monthly</plan>\n" +
+                                   "                <plan>dynamic-annual</plan>\n" +
                                    "                <plan>sports-monthly</plan>\n" +
+                                   "                <plan>standard-monthly</plan>\n" +
                                    "                <plan>super-monthly</plan>\n" +
-                                   "                <plan>dynamic-annual</plan>\n" +
                                    "            </plans>\n" +
                                    "        </defaultPriceList>\n" +
                                    "    </priceLists>\n" +
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/TestInternationalPrice.java b/catalog/src/test/java/org/killbill/billing/catalog/TestInternationalPrice.java
index a3803e2..12cc090 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/TestInternationalPrice.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/TestInternationalPrice.java
@@ -63,9 +63,9 @@ public class TestInternationalPrice extends CatalogTestSuiteNoDB {
     public void testPriceInitialization() throws URISyntaxException, CatalogApiException {
         final StandaloneCatalog c = new MockCatalog();
         c.setSupportedCurrencies(new Currency[]{Currency.GBP, Currency.EUR, Currency.USD, Currency.BRL, Currency.MXN});
-        ((DefaultInternationalPrice) c.getCurrentPlans()[0].getFinalPhase().getRecurring().getRecurringPrice()).setPrices(null);
+        ((DefaultInternationalPrice) c.getCurrentPlans().iterator().next().getFinalPhase().getRecurring().getRecurringPrice()).setPrices(null);
         c.initialize(c, new URI("foo://bar"));
-        Assert.assertEquals(c.getCurrentPlans()[0].getFinalPhase().getRecurring().getRecurringPrice().getPrice(Currency.GBP), new BigDecimal(0));
+        Assert.assertEquals(c.getCurrentPlans().iterator().next().getFinalPhase().getRecurring().getRecurringPrice().getPrice(Currency.GBP), new BigDecimal(0));
     }
 
     @Test(groups = "fast")
diff --git a/catalog/src/test/java/org/killbill/billing/catalog/TestStandaloneCatalog.java b/catalog/src/test/java/org/killbill/billing/catalog/TestStandaloneCatalog.java
index 93b491e..78b4554 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/TestStandaloneCatalog.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/TestStandaloneCatalog.java
@@ -16,12 +16,15 @@
 
 package org.killbill.billing.catalog;
 
+import org.killbill.billing.catalog.api.Plan;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.PhaseType;
 
+import com.google.common.collect.ImmutableList;
+
 public class TestStandaloneCatalog extends CatalogTestSuiteNoDB {
 
     @Test(groups = "fast")
@@ -38,7 +41,7 @@ public class TestStandaloneCatalog extends CatalogTestSuiteNoDB {
         phaseDiscount1.setPlan(plan1);
         phaseDiscount2.setPlan(plan2);
 
-        final StandaloneCatalog cat = new MockCatalog().setPlans(new DefaultPlan[]{plan1, plan2});
+        final StandaloneCatalog cat = new MockCatalog().setPlans(ImmutableList.<Plan>of(plan1, plan2));
 
         Assert.assertEquals(cat.findCurrentPhase("TestPlan1-discount"), phaseDiscount1);
         Assert.assertEquals(cat.findCurrentPhase("TestPlan2-discount"), phaseDiscount2);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatter.java b/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
index 337a9b5..44f2a30 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
@@ -26,7 +26,6 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.UUID;
 
 import org.joda.money.CurrencyUnit;
@@ -72,11 +71,10 @@ public class DefaultInvoiceFormatter implements InvoiceFormatter {
     private final CurrencyConversionApi currencyConversionApi;
     private final InternalTenantContext context;
     private final ResourceBundleFactory bundleFactory;
-    private final Map<java.util.Currency, Locale> currencyLocaleMap;
 
     public DefaultInvoiceFormatter(final TranslatorConfig config, final Invoice invoice, final Locale locale,
                                    final CurrencyConversionApi currencyConversionApi, final ResourceBundleFactory bundleFactory,
-                                   final InternalTenantContext context, final Map<java.util.Currency, Locale> currencyLocaleMap) {
+                                   final InternalTenantContext context) {
         this.config = config;
         this.invoice = invoice;
         this.dateFormatter = DateTimeFormat.mediumDate().withLocale(locale);
@@ -84,7 +82,6 @@ public class DefaultInvoiceFormatter implements InvoiceFormatter {
         this.currencyConversionApi = currencyConversionApi;
         this.bundleFactory = bundleFactory;
         this.context = context;
-        this.currencyLocaleMap = currencyLocaleMap;
     }
 
     @Override
@@ -240,8 +237,8 @@ public class DefaultInvoiceFormatter implements InvoiceFormatter {
         dfs.setInternationalCurrencySymbol(currencyUnit.getCurrencyCode());
 
         try {
-            final java.util.Currency currency = java.util.Currency.getInstance(invoiceCurrencyCode);
-            dfs.setCurrencySymbol(currency.getSymbol(currencyLocaleMap.get(currency)));
+            Currency currency = Currency.fromCode(invoiceCurrencyCode);
+            dfs.setCurrencySymbol(currency.getSymbol());
         } catch (final IllegalArgumentException e) {
             dfs.setCurrencySymbol(currencyUnit.getSymbol(locale));
         }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatterFactory.java b/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatterFactory.java
index b9e405b..5c9a5da 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatterFactory.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatterFactory.java
@@ -46,10 +46,16 @@ public class DefaultInvoiceFormatterFactory implements InvoiceFormatterFactory {
         }
     }
 
+    /*
+      public DefaultInvoiceFormatter(final TranslatorConfig config, final Invoice invoice, final Locale locale,
+                                   final CurrencyConversionApi currencyConversionApi, final ResourceBundleFactory bundleFactory,
+                                   final InternalTenantContext context) {
+     */
+
     @Override
     public InvoiceFormatter createInvoiceFormatter(final TranslatorConfig config, final Invoice invoice, final Locale locale, final CurrencyConversionApi currencyConversionApi,
                                                    final ResourceBundleFactory bundleFactory, final InternalTenantContext context) {
-        return new DefaultInvoiceFormatter(config, invoice, locale, currencyConversionApi, bundleFactory, context, currencyLocaleMap);
+        return new DefaultInvoiceFormatter(config, invoice, locale, currencyConversionApi, bundleFactory, context);
     }
 
     @VisibleForTesting
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java b/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
index 3fa01dd..8789a2b 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
@@ -91,7 +91,7 @@ public class TestDefaultInvoiceFormatter extends InvoiceTestSuiteNoDB {
         Assert.assertEquals(invoice.getCreditedAmount().doubleValue(), 0.00);
 
         // Verify the merge
-        final InvoiceFormatter formatter = new DefaultInvoiceFormatter(config, invoice, Locale.US, null, resourceBundleFactory, internalCallContext, defaultInvoiceFormatterFactory.getCurrencyLocaleMap());
+        final InvoiceFormatter formatter = new DefaultInvoiceFormatter(config, invoice, Locale.US, null, resourceBundleFactory, internalCallContext);
         final List<InvoiceItem> invoiceItems = formatter.getInvoiceItems();
         Assert.assertEquals(invoiceItems.size(), 1);
         Assert.assertEquals(invoiceItems.get(0).getInvoiceItemType(), InvoiceItemType.FIXED);
@@ -140,7 +140,7 @@ public class TestDefaultInvoiceFormatter extends InvoiceTestSuiteNoDB {
         Assert.assertEquals(invoice.getRefundedAmount().doubleValue(), -1.00);
 
         // Verify the merge
-        final InvoiceFormatter formatter = new DefaultInvoiceFormatter(config, invoice, Locale.US, null, resourceBundleFactory, internalCallContext, defaultInvoiceFormatterFactory.getCurrencyLocaleMap());
+        final InvoiceFormatter formatter = new DefaultInvoiceFormatter(config, invoice, Locale.US, null, resourceBundleFactory, internalCallContext);
         final List<InvoiceItem> invoiceItems = formatter.getInvoiceItems();
         Assert.assertEquals(invoiceItems.size(), 4);
         Assert.assertEquals(invoiceItems.get(0).getInvoiceItemType(), InvoiceItemType.FIXED);
@@ -202,13 +202,13 @@ public class TestDefaultInvoiceFormatter extends InvoiceTestSuiteNoDB {
                     "    <td class=\"amount\"><strong>{{invoice.formattedBalance}}</strong></td>\n" +
                     "</tr>",
                     "<tr>\n" +
-                    "    <td class=\"amount\"><strong>1 499,958 ر.ع.\u200F</strong></td>\n" +
+                    "    <td class=\"amount\"><strong>1 499,958 ر.ع</strong></td>\n" +
                     "</tr>\n" +
                     "<tr>\n" +
-                    "    <td class=\"amount\"><strong>0,000 ر.ع.\u200F</strong></td>\n" +
+                    "    <td class=\"amount\"><strong>0,000 ر.ع</strong></td>\n" +
                     "</tr>\n" +
                     "<tr>\n" +
-                    "    <td class=\"amount\"><strong>1 499,958 ر.ع.\u200F</strong></td>\n" +
+                    "    <td class=\"amount\"><strong>1 499,958 ر.ع</strong></td>\n" +
                     "</tr>",
                     Locale.FRANCE);
     }
@@ -232,13 +232,13 @@ public class TestDefaultInvoiceFormatter extends InvoiceTestSuiteNoDB {
                     "    <td class=\"amount\"><strong>{{invoice.formattedBalance}}</strong></td>\n" +
                     "</tr>",
                     "<tr>\n" +
-                    "    <td class=\"amount\"><strong>1 500 ¥</strong></td>\n" +
+                    "    <td class=\"amount\"><strong>1 500 ¥</strong></td>\n" +
                     "</tr>\n" +
                     "<tr>\n" +
-                    "    <td class=\"amount\"><strong>0 ¥</strong></td>\n" +
+                    "    <td class=\"amount\"><strong>0 ¥</strong></td>\n" +
                     "</tr>\n" +
                     "<tr>\n" +
-                    "    <td class=\"amount\"><strong>1 500 ¥</strong></td>\n" +
+                    "    <td class=\"amount\"><strong>1 500 ¥</strong></td>\n" +
                     "</tr>",
                     Locale.FRANCE);
     }
@@ -262,13 +262,13 @@ public class TestDefaultInvoiceFormatter extends InvoiceTestSuiteNoDB {
                     "    <td class=\"amount\"><strong>{{invoice.formattedBalance}}</strong></td>\n" +
                     "</tr>",
                     "<tr>\n" +
-                    "    <td class=\"amount\"><strong>BTC1,105.28843439</strong></td>\n" +
+                    "    <td class=\"amount\"><strong>Ƀ1,105.28843439</strong></td>\n" +
                     "</tr>\n" +
                     "<tr>\n" +
-                    "    <td class=\"amount\"><strong>BTC0.00000000</strong></td>\n" +
+                    "    <td class=\"amount\"><strong>Ƀ0.00000000</strong></td>\n" +
                     "</tr>\n" +
                     "<tr>\n" +
-                    "    <td class=\"amount\"><strong>BTC1,105.28843439</strong></td>\n" +
+                    "    <td class=\"amount\"><strong>Ƀ1,105.28843439</strong></td>\n" +
                     "</tr>",
                     Locale.US);
     }
@@ -513,7 +513,7 @@ public class TestDefaultInvoiceFormatter extends InvoiceTestSuiteNoDB {
 
         data.put("text", translator);
 
-        data.put("invoice", new DefaultInvoiceFormatter(config, invoice, Locale.US, currencyConversionApi, resourceBundleFactory, internalCallContext, defaultInvoiceFormatterFactory.getCurrencyLocaleMap()));
+        data.put("invoice", new DefaultInvoiceFormatter(config, invoice, Locale.US, currencyConversionApi, resourceBundleFactory, internalCallContext));
 
         final String formattedText = templateEngine.executeTemplateText(template, data);
 
@@ -522,7 +522,7 @@ public class TestDefaultInvoiceFormatter extends InvoiceTestSuiteNoDB {
 
     private void checkOutput(final Invoice invoice, final String template, final String expected, final Locale locale) {
         final Map<String, Object> data = new HashMap<String, Object>();
-        data.put("invoice", new DefaultInvoiceFormatter(config, invoice, locale, null, resourceBundleFactory, internalCallContext, defaultInvoiceFormatterFactory.getCurrencyLocaleMap()));
+        data.put("invoice", new DefaultInvoiceFormatter(config, invoice, locale, null, resourceBundleFactory, internalCallContext));
 
         final String formattedText = templateEngine.executeTemplateText(template, data);
         Assert.assertEquals(formattedText, expected);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CatalogJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CatalogJson.java
index 79a2b8b..1f44b5d 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CatalogJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CatalogJson.java
@@ -20,6 +20,7 @@ package org.killbill.billing.jaxrs.json;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -80,7 +81,7 @@ public class CatalogJson {
         currencies = Arrays.asList(catalog.getSupportedCurrencies(requestedDate));
         priceLists = new ArrayList<PriceListJson>();
 
-        final Plan[] plans = catalog.getPlans(requestedDate);
+        final Collection<Plan> plans = catalog.getPlans(requestedDate);
         final Map<String, ProductJson> productMap = new HashMap<String, ProductJson>();
         for (final Plan plan : plans) {
             // Build the product associated with this plan
@@ -190,7 +191,7 @@ public class CatalogJson {
         return pricesJson;
     }
 
-    private List<String> toProductNames(final Product[] in) {
+    private List<String> toProductNames(final Collection<Product> in) {
         return Lists.transform(ImmutableList.<Product>copyOf(in),
                                new Function<Product, String>() {
                                    @Override
diff --git a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
index 9caf8ea..331a0dd 100644
--- a/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
+++ b/junction/src/test/java/org/killbill/billing/junction/plumbing/billing/TestBillingApi.java
@@ -122,7 +122,7 @@ public class TestBillingApi extends JunctionTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testBillingEventsNoBillingPeriod() throws CatalogApiException, AccountApiException {
-        final Plan nextPlan = catalog.findPlan("PickupTrialEvergreen10USD", clock.getUTCNow());
+        final Plan nextPlan = catalog.findPlan("3-PickupTrialEvergreen10USD", clock.getUTCNow());
         // The trial has no billing period
         final PlanPhase nextPhase = nextPlan.getAllPhases()[0];
         final DateTime now = createSubscriptionCreationEvent(nextPlan, nextPhase);
@@ -135,7 +135,7 @@ public class TestBillingApi extends JunctionTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testBillingEventsSubscriptionAligned() throws CatalogApiException, AccountApiException {
-        final Plan nextPlan = catalog.findPlan("PickupTrialEvergreen10USD", clock.getUTCNow());
+        final Plan nextPlan = catalog.findPlan("3-PickupTrialEvergreen10USD", clock.getUTCNow());
         final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
         final DateTime now = createSubscriptionCreationEvent(nextPlan, nextPhase);
 
@@ -150,7 +150,7 @@ public class TestBillingApi extends JunctionTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testBillingEventsAccountAligned() throws CatalogApiException, AccountApiException {
-        final Plan nextPlan = catalog.findPlan("PickupTrialEvergreen10USD", clock.getUTCNow());
+        final Plan nextPlan = catalog.findPlan("3-PickupTrialEvergreen10USD", clock.getUTCNow());
         final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
         final DateTime now = createSubscriptionCreationEvent(nextPlan, nextPhase);
 
@@ -163,14 +163,14 @@ public class TestBillingApi extends JunctionTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testBillingEventsBundleAligned() throws CatalogApiException, AccountApiException {
-        final Plan nextPlan = catalog.findPlan("Horn1USD", clock.getUTCNow());
+        final Plan nextPlan = catalog.findPlan("7-Horn1USD", clock.getUTCNow());
         final PlanPhase nextPhase = nextPlan.getAllPhases()[0];
         final DateTime now = createSubscriptionCreationEvent(nextPlan, nextPhase);
 
         final Account account = createAccount(1);
 
         catalog.setBillingAlignment(BillingAlignment.BUNDLE);
-        ((MockSubscription) subscription).setPlan(catalog.findPlan("PickupTrialEvergreen10USD", now));
+        ((MockSubscription) subscription).setPlan(catalog.findPlan("3-PickupTrialEvergreen10USD", now));
 
         final SortedSet<BillingEvent> events = billingInternalApi.getBillingEventsForAccountAndUpdateAccountBCD(account.getId(), null, internalCallContext);
         // The expected BCD is when the subscription started
@@ -179,7 +179,7 @@ public class TestBillingApi extends JunctionTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testBillingEventsWithBlock() throws CatalogApiException, AccountApiException {
-        final Plan nextPlan = catalog.findPlan("PickupTrialEvergreen10USD", clock.getUTCNow());
+        final Plan nextPlan = catalog.findPlan("3-PickupTrialEvergreen10USD", clock.getUTCNow());
         final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
         final DateTime now = createSubscriptionCreationEvent(nextPlan, nextPhase);
 
@@ -201,7 +201,7 @@ public class TestBillingApi extends JunctionTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testBillingEventsAutoInvoicingOffAccount() throws CatalogApiException, AccountApiException, TagApiException {
-        final Plan nextPlan = catalog.findPlan("PickupTrialEvergreen10USD", clock.getUTCNow());
+        final Plan nextPlan = catalog.findPlan("3-PickupTrialEvergreen10USD", clock.getUTCNow());
         final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
         createSubscriptionCreationEvent(nextPlan, nextPhase);
 
@@ -217,7 +217,7 @@ public class TestBillingApi extends JunctionTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testBillingEventsAutoInvoicingOffBundle() throws CatalogApiException, AccountApiException, TagApiException {
-        final Plan nextPlan = catalog.findPlan("PickupTrialEvergreen10USD", clock.getUTCNow());
+        final Plan nextPlan = catalog.findPlan("3-PickupTrialEvergreen10USD", clock.getUTCNow());
         final PlanPhase nextPhase = nextPlan.getAllPhases()[1];
         createSubscriptionCreationEvent(nextPlan, nextPhase);
 

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index 4abb7b2..c1bbb5b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.130-SNAPSHOT</version>
+        <version>0.131-SNAPSHOT</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.17.5-SNAPSHOT</version>
diff --git a/subscription/src/main/java/org/killbill/billing/subscription/engine/addon/AddonUtils.java b/subscription/src/main/java/org/killbill/billing/subscription/engine/addon/AddonUtils.java
index 7098709..8fd9da7 100644
--- a/subscription/src/main/java/org/killbill/billing/subscription/engine/addon/AddonUtils.java
+++ b/subscription/src/main/java/org/killbill/billing/subscription/engine/addon/AddonUtils.java
@@ -16,6 +16,7 @@
 
 package org.killbill.billing.subscription.engine.addon;
 
+import java.util.Collection;
 import java.util.List;
 
 import org.joda.time.DateTime;
@@ -105,7 +106,7 @@ public class AddonUtils {
 
     private boolean isAddonAvailable(final Product baseProduct, final Plan targetAddOnPlan) {
         final Product targetAddonProduct = targetAddOnPlan.getProduct();
-        final Product[] availableAddOns = baseProduct.getAvailable();
+        final Collection<Product> availableAddOns = baseProduct.getAvailable();
 
         for (final Product curAv : availableAddOns) {
             if (curAv.getName().equals(targetAddonProduct.getName())) {
@@ -117,7 +118,7 @@ public class AddonUtils {
 
     private boolean isAddonIncluded(final Product baseProduct, final Plan targetAddOnPlan) {
         final Product targetAddonProduct = targetAddOnPlan.getProduct();
-        final Product[] includedAddOns = baseProduct.getIncluded();
+        final Collection<Product> includedAddOns = baseProduct.getIncluded();
         for (final Product curAv : includedAddOns) {
             if (curAv.getName().equals(targetAddonProduct.getName())) {
                 return true;
diff --git a/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestDefaultSubscriptionTransferApi.java b/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestDefaultSubscriptionTransferApi.java
index 466b2e2..9601f74 100644
--- a/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestDefaultSubscriptionTransferApi.java
+++ b/subscription/src/test/java/org/killbill/billing/subscription/api/transfer/TestDefaultSubscriptionTransferApi.java
@@ -113,12 +113,12 @@ public class TestDefaultSubscriptionTransferApi extends SubscriptionTestSuiteNoD
 
             @Override
             public String getPlanName() {
-                return "BicycleTrialEvergreen1USD";
+                return "1-BicycleTrialEvergreen1USD";
             }
 
             @Override
             public String getPlanPhaseName() {
-                return SubscriptionBaseTransitionType.CANCEL.equals(subscriptionTransitionType) ? null : "BicycleTrialEvergreen1USD-trial";
+                return SubscriptionBaseTransitionType.CANCEL.equals(subscriptionTransitionType) ? null : "1-BicycleTrialEvergreen1USD-trial";
             }
 
             @Override
@@ -134,7 +134,7 @@ public class TestDefaultSubscriptionTransferApi extends SubscriptionTestSuiteNoD
             @Override
             public PlanPhaseSpecifier getPlanPhaseSpecifier() {
                 return SubscriptionBaseTransitionType.CANCEL.equals(subscriptionTransitionType) ? null :
-                       new PlanPhaseSpecifier("BicycleTrialEvergreen1USD",  BillingPeriod.NO_BILLING_PERIOD,
+                       new PlanPhaseSpecifier("1-BicycleTrialEvergreen1USD",  BillingPeriod.NO_BILLING_PERIOD,
                                               PriceListSet.DEFAULT_PRICELIST_NAME, PhaseType.FIXEDTERM);
             }
 
diff --git a/util/src/test/java/org/killbill/billing/mock/MockPriceList.java b/util/src/test/java/org/killbill/billing/mock/MockPriceList.java
index 0d22447..9722cb2 100644
--- a/util/src/test/java/org/killbill/billing/mock/MockPriceList.java
+++ b/util/src/test/java/org/killbill/billing/mock/MockPriceList.java
@@ -16,6 +16,7 @@
 
 package org.killbill.billing.mock;
 
+import java.util.Collection;
 import java.util.UUID;
 
 import org.killbill.billing.catalog.api.BillingPeriod;
@@ -23,6 +24,8 @@ import org.killbill.billing.catalog.api.Plan;
 import org.killbill.billing.catalog.api.PriceList;
 import org.killbill.billing.catalog.api.Product;
 
+import com.google.common.collect.ImmutableList;
+
 public class MockPriceList implements PriceList {
     private final String name;
     private final Plan plan;
@@ -42,10 +45,8 @@ public class MockPriceList implements PriceList {
     }
 
     @Override
-    public Plan[] findPlans(final Product product, final BillingPeriod period) {
-        final Plan[] result = new Plan[1];
-        result[0] = plan;
-        return result;
+    public Collection<Plan> findPlans(final Product product, final BillingPeriod period) {
+        return ImmutableList.of(plan);
     }
 
     public Plan getPlan() {
@@ -53,7 +54,8 @@ public class MockPriceList implements PriceList {
     }
 
     @Override
-    public Plan[] getPlans() {
-        return new Plan[] { plan };
+    public Collection<Plan> getPlans() {
+        return ImmutableList.of(plan);
     }
+
 }
diff --git a/util/src/test/java/org/killbill/billing/mock/MockProduct.java b/util/src/test/java/org/killbill/billing/mock/MockProduct.java
index 046c18a..3e3ad3e 100644
--- a/util/src/test/java/org/killbill/billing/mock/MockProduct.java
+++ b/util/src/test/java/org/killbill/billing/mock/MockProduct.java
@@ -16,17 +16,21 @@
 
 package org.killbill.billing.mock;
 
+import java.util.Collection;
+
 import org.killbill.billing.catalog.api.Limit;
 import org.killbill.billing.catalog.api.Product;
 import org.killbill.billing.catalog.api.ProductCategory;
 
+import com.google.common.collect.ImmutableList;
+
 public class MockProduct implements Product {
 
     private final String name;
     private final ProductCategory category;
     private final String catalogName;
-    private final Product[] included;
-    private final Product[] available;
+    private final Collection<Product> included;
+    private final Collection<Product> available;
 
     public MockProduct() {
         this("TestProduct", ProductCategory.BASE, "Vehicules");
@@ -40,8 +44,8 @@ public class MockProduct implements Product {
         this.name = name;
         this.category = category;
         this.catalogName = catalogName;
-        this.included = included;
-        this.available = available;
+        this.included = ImmutableList.copyOf(included);
+        this.available = ImmutableList.copyOf(available);
     }
 
     @Override
@@ -60,12 +64,12 @@ public class MockProduct implements Product {
     }
 
     @Override
-    public Product[] getAvailable() {
+    public Collection<Product> getAvailable() {
         return available;
     }
 
     @Override
-    public Product[] getIncluded() {
+    public Collection<Product> getIncluded() {
         return included;
     }