killbill-memoizeit

Merge branch 'work-for-release-0.19.x' of github.com:killbill/killbill

4/4/2017 10:39:07 PM

Changes

Details

diff --git a/catalog/src/main/java/org/killbill/billing/catalog/caching/EhCacheCatalogCache.java b/catalog/src/main/java/org/killbill/billing/catalog/caching/EhCacheCatalogCache.java
index 4d33096..e479224 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/caching/EhCacheCatalogCache.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/caching/EhCacheCatalogCache.java
@@ -145,7 +145,7 @@ public class EhCacheCatalogCache implements CatalogCache {
             // A null latestCatalogUpdatedDate by passing caching, by fetching full catalog from plugin below (compatibility mode with 0.18.x or non optimized plugin api mode)
             //
             if (latestCatalogUpdatedDate != null) {
-                final VersionedCatalog tenantCatalog = (VersionedCatalog) cacheController.get(internalTenantContext.getTenantRecordId());
+                final VersionedCatalog tenantCatalog = (VersionedCatalog) cacheController.get(internalTenantContext.getTenantRecordId(), cacheLoaderArgument);
                 if (tenantCatalog != null) {
                     if (tenantCatalog.getEffectiveDate().compareTo(latestCatalogUpdatedDate.toDate()) == 0) {
                         // Current cached version matches the one from the plugin
@@ -160,7 +160,7 @@ public class EhCacheCatalogCache implements CatalogCache {
                 logger.info("Returning catalog from plugin {} on tenant {} ", service, internalTenantContext.getTenantRecordId());
                 final VersionedCatalog resolvedPluginCatalog = versionedCatalogMapper.toVersionedCatalog(pluginCatalog, internalTenantContext);
                 cacheController.remove(internalTenantContext.getTenantRecordId());
-                cacheController.add(internalTenantContext.getTenantRecordId(), resolvedPluginCatalog);
+                cacheController.putIfAbsent(internalTenantContext.getTenantRecordId(), resolvedPluginCatalog);
                 return resolvedPluginCatalog;
             }
         }
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 f9aa7e4..cf7c9a3 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlan.java
@@ -66,6 +66,9 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements 
     @XmlID
     private String name;
 
+    @XmlAttribute(required = false)
+    private String prettyName;
+
     @XmlElement(required = false)
     private Date effectiveDateForExistingSubscriptions;
 
@@ -112,49 +115,30 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements 
         return effectiveDateForExistingSubscriptions;
     }
 
-    public void setEffectiveDateForExistingSubscriptions(
-            final Date effectiveDateForExistingSubscriptions) {
-        this.effectiveDateForExistingSubscriptions = effectiveDateForExistingSubscriptions;
-    }
 
     @Override
     public DefaultPlanPhase[] getInitialPhases() {
         return initialPhases;
     }
 
-    public DefaultPlan setInitialPhases(final DefaultPlanPhase[] phases) {
-        this.initialPhases = phases;
-        return this;
-    }
-
     @Override
     public Product getProduct() {
         return product;
     }
 
-    public DefaultPlan setProduct(final Product product) {
-        this.product = (DefaultProduct) product;
-        return this;
-    }
-
     @Override
     public String getPriceListName() {
         return priceListName;
     }
 
-    public DefaultPlan setPriceListName(final String priceListName) {
-        this.priceListName = priceListName;
-        return this;
-    }
-
     @Override
     public String getName() {
         return name;
     }
 
-    public DefaultPlan setName(final String name) {
-        this.name = name;
-        return this;
+    @Override
+    public String getPrettyName() {
+        return prettyName;
     }
 
     @Override
@@ -162,11 +146,6 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements 
         return finalPhase;
     }
 
-    public DefaultPlan setFinalPhase(final DefaultPlanPhase finalPhase) {
-        this.finalPhase = finalPhase;
-        return this;
-    }
-
     @Override
     public PlanPhase[] getAllPhases() {
         final int length = initialPhases.length + 1;
@@ -202,11 +181,6 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements 
         return plansAllowedInBundle;
     }
 
-    public DefaultPlan setPlansAllowedInBundle(final Integer plansAllowedInBundle) {
-        this.plansAllowedInBundle = plansAllowedInBundle;
-        return this;
-    }
-
     @Override
     public Iterator<PlanPhase> getInitialPhaseIterator() {
         final Collection<PlanPhase> list = new ArrayList<PlanPhase>();
@@ -219,6 +193,9 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements 
         super.initialize(catalog, sourceURI);
         CatalogSafetyInitializer.initializeNonRequiredNullFieldsWithDefaultValue(this);
 
+        if (prettyName == null) {
+            this.prettyName = name;
+        }
         if (finalPhase != null) {
             finalPhase.setPlan(this);
             finalPhase.initialize(catalog, sourceURI);
@@ -267,6 +244,46 @@ public class DefaultPlan extends ValidatingConfig<StandaloneCatalog> implements 
         return errors;
     }
 
+    public void setEffectiveDateForExistingSubscriptions(
+            final Date effectiveDateForExistingSubscriptions) {
+        this.effectiveDateForExistingSubscriptions = effectiveDateForExistingSubscriptions;
+    }
+
+    public DefaultPlan setName(final String name) {
+        this.name = name;
+        return this;
+    }
+
+    public DefaultPlan setPrettyName(final String prettyName) {
+        this.prettyName = prettyName;
+        return this;
+    }
+
+    public DefaultPlan setFinalPhase(final DefaultPlanPhase finalPhase) {
+        this.finalPhase = finalPhase;
+        return this;
+    }
+
+    public DefaultPlan setProduct(final Product product) {
+        this.product = (DefaultProduct) product;
+        return this;
+    }
+
+    public DefaultPlan setPriceListName(final String priceListName) {
+        this.priceListName = priceListName;
+        return this;
+    }
+
+    public DefaultPlan setInitialPhases(final DefaultPlanPhase[] phases) {
+        this.initialPhases = phases;
+        return this;
+    }
+
+    public DefaultPlan setPlansAllowedInBundle(final Integer plansAllowedInBundle) {
+        this.plansAllowedInBundle = plansAllowedInBundle;
+        return this;
+    }
+
     @Override
     public DateTime dateOfFirstRecurringNonZeroCharge(final DateTime subscriptionStartDate, final PhaseType initialPhaseType) {
         DateTime result = subscriptionStartDate;
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhase.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhase.java
index b2bd6cb..b2508a5 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhase.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPlanPhase.java
@@ -49,6 +49,9 @@ import com.google.common.collect.Iterables;
 @XmlAccessorType(XmlAccessType.NONE)
 public class DefaultPlanPhase extends ValidatingConfig<StandaloneCatalog> implements PlanPhase {
 
+    @XmlAttribute(required = false)
+    private String prettyName;
+
     @XmlAttribute(required = true)
     private PhaseType type;
 
@@ -147,6 +150,11 @@ public class DefaultPlanPhase extends ValidatingConfig<StandaloneCatalog> implem
     }
 
     @Override
+    public String getPrettyName() {
+        return prettyName != null ? prettyName : getName();
+    }
+
+    @Override
     public Duration getDuration() {
         return duration;
     }
@@ -196,6 +204,11 @@ public class DefaultPlanPhase extends ValidatingConfig<StandaloneCatalog> implem
         duration.initialize(root, uri);
     }
 
+    public DefaultPlanPhase setPrettyName(final String prettyName) {
+        this.prettyName = prettyName;
+        return this;
+    }
+
     public DefaultPlanPhase setFixed(final DefaultFixed fixed) {
         this.fixed = fixed;
         return this;
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 a67783a..7e686b2 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultPriceList.java
@@ -43,6 +43,9 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
     @XmlID
     private String name;
 
+    @XmlAttribute(required = false)
+    private String prettyName;
+
     @XmlElementWrapper(name = "plans", required = true)
     @XmlIDREF
     @XmlElement(type=DefaultPlan.class, name = "plan", required = false)
@@ -74,6 +77,11 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
         return name;
     }
 
+    @Override
+    public String getPrettyName() {
+        return prettyName;
+    }
+
     /* (non-Javadoc)
       * @see org.killbill.billing.catalog.IPriceList#findPlan(org.killbill.billing.catalog.api.IProduct, org.killbill.billing.catalog.api.BillingPeriod)
       */
@@ -103,6 +111,10 @@ public class DefaultPriceList extends ValidatingConfig<StandaloneCatalog> implem
     public void initialize(final StandaloneCatalog catalog, final URI sourceURI) {
         super.initialize(catalog, sourceURI);
         CatalogSafetyInitializer.initializeNonRequiredNullFieldsWithDefaultValue(this);
+
+        if (prettyName == null) {
+            this.prettyName = name;
+        }
     }
 
     public DefaultPriceList setName(final String name) {
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 af95ceb..1af8c29 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultProduct.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultProduct.java
@@ -42,6 +42,9 @@ public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implemen
     @XmlID
     private String name;
 
+    @XmlAttribute(required = false)
+    private String prettyName;
+
     @XmlElement(required = true)
     private ProductCategory category;
 
@@ -105,6 +108,11 @@ public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implemen
         return name;
     }
 
+    @Override
+    public String getPrettyName() {
+        return prettyName;
+    }
+
     public boolean isIncluded(final DefaultProduct addon) {
         for (final Product p : included.getEntries()) {
             if (addon == p) {
@@ -156,6 +164,9 @@ public class DefaultProduct extends ValidatingConfig<StandaloneCatalog> implemen
         for (DefaultLimit cur : limits) {
             cur.initialize(catalog, sourceURI);
         }
+        if (prettyName == null) {
+            this.prettyName = name;
+        }
         catalogName = catalog.getCatalogName();
     }
 
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUnit.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUnit.java
index f82499d..9d3f148 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUnit.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUnit.java
@@ -43,6 +43,11 @@ public class DefaultUnit extends ValidatingConfig<StandaloneCatalog> implements 
     }
 
     @Override
+    public String getPrettyName() {
+        return name;
+    }
+
+    @Override
     public ValidationErrors validate(StandaloneCatalog root, ValidationErrors errors) {
         return errors;
     }
diff --git a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java
index 3786ce7..ce2a92a 100644
--- a/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java
+++ b/catalog/src/main/java/org/killbill/billing/catalog/DefaultUsage.java
@@ -59,6 +59,9 @@ public class DefaultUsage extends ValidatingConfig<StandaloneCatalog> implements
     @XmlID
     private String name;
 
+    @XmlAttribute(required = false)
+    private String prettyName;
+
     @XmlAttribute(required = true)
     private BillingMode billingMode;
 
@@ -150,6 +153,11 @@ public class DefaultUsage extends ValidatingConfig<StandaloneCatalog> implements
     }
 
     @Override
+    public String getPrettyName() {
+        return prettyName;
+    }
+
+    @Override
     public BillingMode getBillingMode() {
         return billingMode;
     }
@@ -228,6 +236,10 @@ public class DefaultUsage extends ValidatingConfig<StandaloneCatalog> implements
         super.initialize(root, uri);
         CatalogSafetyInitializer.initializeNonRequiredNullFieldsWithDefaultValue(this);
 
+        if (prettyName == null) {
+            this.prettyName = name;
+        }
+
         for (DefaultLimit limit : limits) {
             limit.initialize(root, uri);
         }
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 af11ffe..f0707ed 100644
--- a/catalog/src/test/java/org/killbill/billing/catalog/TestCatalogUpdater.java
+++ b/catalog/src/test/java/org/killbill/billing/catalog/TestCatalogUpdater.java
@@ -281,25 +281,25 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "    </currencies>\n" +
                                    "    <units/>\n" +
                                    "    <products>\n" +
-                                   "        <product name=\"Dynamic\">\n" +
+                                   "        <product name=\"Dynamic\" prettyName=\"Dynamic\">\n" +
                                    "            <category>BASE</category>\n" +
                                    "            <included/>\n" +
                                    "            <available/>\n" +
                                    "            <limits/>\n" +
                                    "        </product>\n" +
-                                   "        <product name=\"Sports\">\n" +
+                                   "        <product name=\"Sports\" prettyName=\"Sports\">\n" +
                                    "            <category>BASE</category>\n" +
                                    "            <included/>\n" +
                                    "            <available/>\n" +
                                    "            <limits/>\n" +
                                    "        </product>\n" +
-                                   "        <product name=\"Standard\">\n" +
+                                   "        <product name=\"Standard\" prettyName=\"Standard\">\n" +
                                    "            <category>BASE</category>\n" +
                                    "            <included/>\n" +
                                    "            <available/>\n" +
                                    "            <limits/>\n" +
                                    "        </product>\n" +
-                                   "        <product name=\"Super\">\n" +
+                                   "        <product name=\"Super\" prettyName=\"Super\">\n" +
                                    "            <category>BASE</category>\n" +
                                    "            <included/>\n" +
                                    "            <available/>\n" +
@@ -339,7 +339,7 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "        </priceList>\n" +
                                    "    </rules>\n" +
                                    "    <plans>\n" +
-                                   "        <plan name=\"dynamic-annual\">\n" +
+                                   "        <plan name=\"dynamic-annual\" prettyName=\"dynamic-annual\">\n" +
                                    "            <product>Dynamic</product>\n" +
                                    "            <initialPhases>\n" +
                                    "                <phase type=\"TRIAL\">\n" +
@@ -376,7 +376,7 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "            </finalPhase>\n" +
                                    "            <plansAllowedInBundle>-1</plansAllowedInBundle>\n" +
                                    "        </plan>\n" +
-                                   "        <plan name=\"sports-monthly\">\n" +
+                                   "        <plan name=\"sports-monthly\" prettyName=\"sports-monthly\">\n" +
                                    "            <product>Sports</product>\n" +
                                    "            <initialPhases>\n" +
                                    "                <phase type=\"TRIAL\">\n" +
@@ -412,7 +412,7 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "            </finalPhase>\n" +
                                    "            <plansAllowedInBundle>-1</plansAllowedInBundle>\n" +
                                    "        </plan>\n" +
-                                   "        <plan name=\"standard-monthly\">\n" +
+                                   "        <plan name=\"standard-monthly\" prettyName=\"standard-monthly\">\n" +
                                    "            <product>Standard</product>\n" +
                                    "            <initialPhases>\n" +
                                    "                <phase type=\"TRIAL\">\n" +
@@ -448,7 +448,7 @@ public class TestCatalogUpdater extends CatalogTestSuiteNoDB {
                                    "            </finalPhase>\n" +
                                    "            <plansAllowedInBundle>-1</plansAllowedInBundle>\n" +
                                    "        </plan>\n" +
-                                   "        <plan name=\"super-monthly\">\n" +
+                                   "        <plan name=\"super-monthly\" prettyName=\"super-monthly\">\n" +
                                    "            <product>Super</product>\n" +
                                    "            <initialPhases>\n" +
                                    "                <phase type=\"TRIAL\">\n" +
diff --git a/catalog/src/test/resources/catalogTest.xml b/catalog/src/test/resources/catalogTest.xml
index 78e4449..d15d55f 100644
--- a/catalog/src/test/resources/catalogTest.xml
+++ b/catalog/src/test/resources/catalogTest.xml
@@ -448,7 +448,7 @@
             </finalPhase>
         </plan>
 
-        <plan name="shotgun-monthly">
+        <plan name="shotgun-monthly" prettyName="Shotgun Monthly">
             <product>Shotgun</product>
             <initialPhases>
                 <phase type="TRIAL">
@@ -1220,14 +1220,14 @@
                 </recurring>
             </finalPhase>
         </plan>
-        <plan name="bullets-usage-in-arrear">
+        <plan name="bullets-usage-in-arrear" prettyName="Bullet Monthly Plan">
             <product>Bullets</product>
-            <finalPhase type="EVERGREEN">
+            <finalPhase type="EVERGREEN" prettyName="Bullet Monthly Plan Evergreen">
                 <duration>
                     <unit>UNLIMITED</unit>
                 </duration>
                 <usages>
-                    <usage name="bullets-usage-in-arrear-usage" billingMode="IN_ARREAR" usageType="CONSUMABLE">
+                    <usage name="bullets-usage-in-arrear-usage" prettyName="Bullet Usage In Arrear" billingMode="IN_ARREAR" usageType="CONSUMABLE">
                         <billingPeriod>MONTHLY</billingPeriod>
                         <tiers>
                             <tier>
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
index 90f868b..ca4e3c1 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
@@ -140,8 +140,7 @@ public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
                 return ImmutableList.<Invoice>of(invoice);
             }
         };
-        final List<InvoiceItem> createdInvoiceItems = invoiceApiHelper.dispatchToInvoicePluginsAndInsertItems(accountId, false, withAccountLock, callContext);
-
+        invoiceApiHelper.dispatchToInvoicePluginsAndInsertItems(accountId, false, withAccountLock, callContext);
         return new DefaultInvoicePayment(refund);
     }
 
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
index c19bb7c..b3733a3 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -36,10 +36,11 @@ import org.killbill.billing.account.api.AccountApiException;
 import org.killbill.billing.account.api.AccountInternalApi;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.catalog.api.Catalog;
+import org.killbill.billing.catalog.api.CatalogApiException;
+import org.killbill.billing.catalog.api.CatalogService;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.InvoiceDispatcher;
-import org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications;
-import org.killbill.billing.invoice.InvoiceDispatcher.FutureAccountNotifications.SubscriptionNotification;
 import org.killbill.billing.invoice.api.DryRunArguments;
 import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceApiException;
@@ -78,7 +79,6 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.inject.Inject;
 
@@ -97,6 +97,8 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
     private final InternalCallContextFactory internalCallContextFactory;
     private final PersistentBus eventBus;
 
+    private final CatalogService catalogService;
+
     @Inject
     public DefaultInvoiceUserApi(final InvoiceDao dao,
                                  final InvoiceDispatcher dispatcher,
@@ -105,6 +107,7 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                                  final TagInternalApi tagApi,
                                  final InvoiceApiHelper invoiceApiHelper,
                                  final HtmlInvoiceGenerator generator,
+                                 final CatalogService catalogService,
                                  final InternalCallContextFactory internalCallContextFactory) {
         this.dao = dao;
         this.dispatcher = dispatcher;
@@ -112,34 +115,39 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
         this.tagApi = tagApi;
         this.invoiceApiHelper = invoiceApiHelper;
         this.generator = generator;
+        this.catalogService = catalogService;
         this.internalCallContextFactory = internalCallContextFactory;
         this.eventBus = eventBus;
     }
 
     @Override
     public List<Invoice> getInvoicesByAccount(final UUID accountId, boolean includesMigrated, final TenantContext context) {
+
+
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
         final List<InvoiceModelDao> invoicesByAccount = includesMigrated ?
-                                                        dao.getAllInvoicesByAccount(internalCallContextFactory.createInternalTenantContext(accountId, context)) :
-                                                        dao.getInvoicesByAccount(internalCallContextFactory.createInternalTenantContext(accountId, context));
+                                                        dao.getAllInvoicesByAccount(internalTenantContext) :
+                                                        dao.getInvoicesByAccount(internalTenantContext);
 
-        return fromInvoiceModelDao(invoicesByAccount);
+        return fromInvoiceModelDao(invoicesByAccount, getCatalogSafelyForPrettyNames(internalTenantContext));
     }
 
     @Override
     public List<Invoice> getInvoicesByAccount(final UUID accountId, final LocalDate fromDate, final TenantContext context) {
-        final List<InvoiceModelDao> invoicesByAccount = dao.getInvoicesByAccount(fromDate, internalCallContextFactory.createInternalTenantContext(accountId, context));
-        return fromInvoiceModelDao(invoicesByAccount);
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
+        final List<InvoiceModelDao> invoicesByAccount = dao.getInvoicesByAccount(fromDate, internalTenantContext);
+        return fromInvoiceModelDao(invoicesByAccount, getCatalogSafelyForPrettyNames(internalTenantContext));
     }
 
     @Override
     public Invoice getInvoiceByPayment(final UUID paymentId, final TenantContext context) throws InvoiceApiException {
-        final InternalTenantContext tenantContext = internalCallContextFactory.createInternalTenantContext(paymentId, ObjectType.PAYMENT, context);
-        final UUID invoiceId = dao.getInvoiceIdByPaymentId(paymentId, tenantContext);
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(paymentId, ObjectType.PAYMENT, context);
+        final UUID invoiceId = dao.getInvoiceIdByPaymentId(paymentId, internalTenantContext);
         if (invoiceId == null) {
             throw new InvoiceApiException(ErrorCode.INVOICE_NOT_FOUND, paymentId);
         }
-        final InvoiceModelDao invoiceModelDao = dao.getById(invoiceId, tenantContext);
-        return new DefaultInvoice(invoiceModelDao);
+        final InvoiceModelDao invoiceModelDao = dao.getById(invoiceId, internalTenantContext);
+        return new DefaultInvoice(invoiceModelDao, getCatalogSafelyForPrettyNames(internalTenantContext));
     }
 
     @Override
@@ -194,19 +202,22 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
 
     @Override
     public Invoice getInvoice(final UUID invoiceId, final TenantContext context) throws InvoiceApiException {
-        return new DefaultInvoice(dao.getById(invoiceId, internalCallContextFactory.createInternalTenantContext(invoiceId, ObjectType.INVOICE, context)));
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(invoiceId, ObjectType.INVOICE, context);
+        return new DefaultInvoice(dao.getById(invoiceId, internalTenantContext), getCatalogSafelyForPrettyNames(internalTenantContext));
     }
 
     @Override
     public Invoice getInvoiceByNumber(final Integer number, final TenantContext context) throws InvoiceApiException {
         // The account record id will be populated in the DAO
-        return new DefaultInvoice(dao.getByNumber(number, internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(context)));
+        final InternalTenantContext internalTenantContextWithoutAccountRecordId = internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(context);
+        return new DefaultInvoice(dao.getByNumber(number, internalTenantContextWithoutAccountRecordId), getCatalogSafelyForPrettyNames(internalTenantContextWithoutAccountRecordId));
     }
 
     @Override
     public List<Invoice> getUnpaidInvoicesByAccountId(final UUID accountId, final LocalDate upToDate, final TenantContext context) {
-        final List<InvoiceModelDao> unpaidInvoicesByAccountId = dao.getUnpaidInvoicesByAccountId(accountId, upToDate, internalCallContextFactory.createInternalTenantContext(accountId, context));
-        return fromInvoiceModelDao(unpaidInvoicesByAccountId);
+        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(accountId, context);
+        final List<InvoiceModelDao> unpaidInvoicesByAccountId = dao.getUnpaidInvoicesByAccountId(accountId, upToDate, internalTenantContext);
+        return fromInvoiceModelDao(unpaidInvoicesByAccountId, getCatalogSafelyForPrettyNames(internalTenantContext));
     }
 
     @Override
@@ -514,12 +525,12 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
         }
     }
 
-    private List<Invoice> fromInvoiceModelDao(final Collection<InvoiceModelDao> invoiceModelDaos) {
+    private List<Invoice> fromInvoiceModelDao(final Collection<InvoiceModelDao> invoiceModelDaos, final Catalog catalog) {
         return ImmutableList.<Invoice>copyOf(Collections2.transform(invoiceModelDaos,
                                                                     new Function<InvoiceModelDao, Invoice>() {
                                                                         @Override
                                                                         public Invoice apply(final InvoiceModelDao input) {
-                                                                            return new DefaultInvoice(input);
+                                                                            return new DefaultInvoice(input, catalog);
                                                                         }
                                                                     }));
     }
@@ -574,4 +585,13 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
             }
         }));
     }
+
+    private Catalog getCatalogSafelyForPrettyNames(final InternalTenantContext internalTenantContext) {
+        try {
+            return catalogService.getFullCatalog(true, true, internalTenantContext);
+        } catch (final CatalogApiException e) {
+            log.warn(String.format("Failed to extract catalog to fill invoice item pretty names for tenantRecordId='%s', ignoring...", internalTenantContext.getTenantRecordId()), internalTenantContext.getTenantRecordId());
+            return null;
+        }
+    }
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/AdjInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/AdjInvoiceItem.java
index e126f90..6a7eb2e 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/AdjInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/AdjInvoiceItem.java
@@ -33,7 +33,7 @@ public abstract class AdjInvoiceItem extends InvoiceItemBase {
     AdjInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId,
                    final LocalDate startDate, final LocalDate endDate, @Nullable final String description,
                    final BigDecimal amount, final Currency currency, @Nullable final UUID reversingId) {
-        super(id, createdDate, invoiceId, accountId, null, null, description, null, null, null, startDate, endDate, amount, currency, reversingId);
+        super(id, createdDate, invoiceId, accountId, null, null, description, startDate, endDate, amount, null, currency, reversingId);
     }
 
     @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java b/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
index 89f60a5..c041450 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
@@ -26,6 +26,7 @@ import javax.annotation.Nullable;
 
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
+import org.killbill.billing.catalog.api.Catalog;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.entity.EntityBase;
 import org.killbill.billing.invoice.api.Invoice;
@@ -74,7 +75,7 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
     }
 
     // This CTOR is used to return an existing invoice and must include everything (items, payments, tags,..)
-    public DefaultInvoice(final InvoiceModelDao invoiceModelDao) {
+    public DefaultInvoice(final InvoiceModelDao invoiceModelDao, @Nullable final Catalog catalog) {
         this(invoiceModelDao.getId(), invoiceModelDao.getCreatedDate(), invoiceModelDao.getAccountId(),
              invoiceModelDao.getInvoiceNumber(), invoiceModelDao.getInvoiceDate(), invoiceModelDao.getTargetDate(),
              invoiceModelDao.getCurrency(), invoiceModelDao.getProcessedCurrency(), invoiceModelDao.isMigrated(),
@@ -83,7 +84,7 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
         addInvoiceItems(Collections2.transform(invoiceModelDao.getInvoiceItems(), new Function<InvoiceItemModelDao, InvoiceItem>() {
             @Override
             public InvoiceItem apply(final InvoiceItemModelDao input) {
-                return InvoiceItemFactory.fromModelDao(input);
+                return InvoiceItemFactory.fromModelDaoWithCatalog(input, catalog);
             }
         }));
         addPayments(Collections2.transform(invoiceModelDao.getInvoicePayments(), new Function<InvoicePaymentModelDao, InvoicePayment>() {
@@ -94,6 +95,10 @@ public class DefaultInvoice extends EntityBase implements Invoice, Cloneable {
         }));
     }
 
+    public DefaultInvoice(final InvoiceModelDao invoiceModelDao) {
+        this(invoiceModelDao, null);
+    }
+
     public DefaultInvoice(final UUID accountId, final LocalDate invoiceDate, final Currency currency) {
         this(UUID.randomUUID(), null, accountId, null, invoiceDate, null, currency, currency, false, false, InvoiceStatus.DRAFT, true, null);
     }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/ExternalChargeInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/ExternalChargeInvoiceItem.java
index f97eeff..c993dd5 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/ExternalChargeInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/ExternalChargeInvoiceItem.java
@@ -30,18 +30,18 @@ import org.killbill.billing.util.UUIDs;
 public class ExternalChargeInvoiceItem extends InvoiceItemBase {
 
     public ExternalChargeInvoiceItem(final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId, @Nullable final String description,
-                                     final LocalDate date, final BigDecimal amount, final Currency currency) {
-        this(UUIDs.randomUUID(), invoiceId, accountId, bundleId, description, date, amount, currency);
+                                     final LocalDate effectiveDate, final BigDecimal amount, final Currency currency) {
+        this(UUIDs.randomUUID(), invoiceId, accountId, bundleId, description, effectiveDate, amount, currency);
     }
 
     public ExternalChargeInvoiceItem(final UUID id, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
-                                     @Nullable final String description, final LocalDate date, final BigDecimal amount, final Currency currency) {
-        this(id, null, invoiceId, accountId, bundleId, description, date, amount, currency);
+                                     @Nullable final String description, final LocalDate effectiveDate, final BigDecimal amount, final Currency currency) {
+        this(id, null, invoiceId, accountId, bundleId, description, effectiveDate, amount, currency);
     }
 
     public ExternalChargeInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
-                                     @Nullable final String description, final LocalDate date, final BigDecimal amount, final Currency currency) {
-        super(id, createdDate, invoiceId, accountId, bundleId, null, description, null, null, null, date, null, amount, currency);
+                                     @Nullable final String description, final LocalDate effectiveDate, final BigDecimal amount, final Currency currency) {
+        super(id, createdDate, invoiceId, accountId, bundleId, null, description, effectiveDate, null, amount, null, currency, null);
     }
 
     @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/FixedPriceInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/FixedPriceInvoiceItem.java
index 9a29b6f..b177056 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/FixedPriceInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/FixedPriceInvoiceItem.java
@@ -29,7 +29,7 @@ import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.util.UUIDs;
 
-public class FixedPriceInvoiceItem extends InvoiceItemBase {
+public class FixedPriceInvoiceItem extends InvoiceItemCatalogBase {
 
     public FixedPriceInvoiceItem(final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId, @Nullable final UUID subscriptionId,
                                  final String planName, final String phaseName,
@@ -40,7 +40,13 @@ public class FixedPriceInvoiceItem extends InvoiceItemBase {
     public FixedPriceInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID bundleId,
                                  final UUID subscriptionId, final String planName, final String phaseName,
                                  @Nullable final String description, final LocalDate date, final BigDecimal amount, final Currency currency) {
-        super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, date, null, amount, currency);
+        super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, date, null, amount, null, currency, null);
+    }
+
+    public FixedPriceInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID bundleId,
+                                 final UUID subscriptionId, final String planName, final String phaseName, final String prettyPlanName, final String prettyPhaseName,
+                                 @Nullable final String description, final LocalDate date, final BigDecimal amount, final Currency currency) {
+        super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, prettyPlanName, prettyPhaseName, null, date, null, amount, null, currency, null);
     }
 
     @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java
index 3f9b13b..b9eda76 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemBase.java
@@ -46,8 +46,6 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem 
     /* Fixed and recurring specific */
     protected final UUID subscriptionId;
     protected final UUID bundleId;
-    protected final String planName;
-    protected final String phaseName;
 
     /* Recurring specific */
     protected final BigDecimal rate;
@@ -55,57 +53,21 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem 
     /* RepairAdjInvoiceItem */
     protected final UUID linkedItemId;
 
-    /* Usage specific */
-    protected final String usageName;
 
-    @Override
-    public String toString() {
-        // Note: we don't use all fields here, as the output would be overwhelming
-        // (we output all invoice items as they are generated).
-        final StringBuilder sb = new StringBuilder();
-        sb.append(getInvoiceItemType());
-        sb.append("{startDate=").append(startDate);
-        sb.append(", endDate=").append(endDate);
-        sb.append(", amount=").append(amount);
-        sb.append(", rate=").append(rate);
-        sb.append(", subscriptionId=").append(subscriptionId);
-        sb.append(", linkedItemId=").append(linkedItemId);
-        sb.append('}');
-        return sb.toString();
-    }
-
-    /*
-    * CTORs with ID; called from DAO when rehydrating
-    */
-    // No rate and no reversing item
-    public InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
-                           @Nullable final UUID subscriptionId, @Nullable final String description, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
-                           final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final Currency currency) {
-        this(id, createdDate, invoiceId, accountId, null, bundleId, subscriptionId, description, planName, phaseName, usageName, startDate, endDate, amount, null, currency, null);
-    }
-
-    // With rate but no reversing item
     public InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
-                           @Nullable final UUID subscriptionId, @Nullable final String description, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
-                           final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency) {
-        this(id, createdDate, invoiceId, accountId, null, bundleId, subscriptionId, description, planName, phaseName, usageName, startDate, endDate, amount, rate, currency, null);
-    }
-
-    // With  reversing item, no rate
-    public InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
-                           @Nullable final UUID subscriptionId, @Nullable final String description, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
-                           final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final Currency currency, final UUID reversedItemId) {
-        this(id, createdDate, invoiceId, accountId, null, bundleId, subscriptionId, description, planName, phaseName, usageName, startDate, endDate, amount, null, currency, reversedItemId);
+                           @Nullable final UUID subscriptionId, @Nullable final String description,
+                           final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, final UUID reversedItemId) {
+        this(id, createdDate, invoiceId, accountId, null, bundleId, subscriptionId, description, startDate, endDate, amount, rate, currency, reversedItemId);
     }
 
     // For parent invoices
     public InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID childAccountId,
                              final BigDecimal amount, final Currency currency, final String description) {
-        this(id, createdDate, invoiceId, accountId, childAccountId, null, null, description, null, null, null, null, null, amount, null, currency, null);
+        this(id, createdDate, invoiceId, accountId, childAccountId, null, null, description, null, null, amount, null, currency, null);
     }
 
     private InvoiceItemBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID childAccountId, @Nullable final UUID bundleId,
-                            @Nullable final UUID subscriptionId, @Nullable final String description, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
+                            @Nullable final UUID subscriptionId, @Nullable final String description,
                             @Nullable final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency,
                             final UUID reversedItemId) {
         super(id, createdDate, createdDate);
@@ -115,9 +77,6 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem 
         this.subscriptionId = subscriptionId;
         this.bundleId = bundleId;
         this.description = description;
-        this.planName = planName;
-        this.phaseName = phaseName;
-        this.usageName = usageName;
         this.startDate = startDate;
         this.endDate = endDate;
         this.amount = amount == null || currency == null ? amount : KillBillMoney.of(amount, currency);
@@ -147,16 +106,6 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem 
     }
 
     @Override
-    public String getPlanName() {
-        return planName;
-    }
-
-    @Override
-    public String getPhaseName() {
-        return phaseName;
-    }
-
-    @Override
     public BigDecimal getAmount() {
         return amount;
     }
@@ -186,16 +135,44 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem 
         return linkedItemId;
     }
 
+
+    @Override
+    public UUID getChildAccountId() {
+        return childAccountId;
+    }
+
+
+    @Override
+    public String getPlanName() {
+        return null;
+    }
+
+    @Override
+    public String getPrettyPlanName() {
+        return null;
+    }
+
+    @Override
+    public String getPhaseName() {
+        return null;
+    }
+
+    @Override
+    public String getPrettyPhaseName() {
+        return null;
+    }
+
     @Override
     public String getUsageName() {
-        return usageName;
+        return null;
     }
 
     @Override
-    public UUID getChildAccountId() {
-        return childAccountId;
+    public String getPrettyUsageName() {
+        return null;
     }
 
+
     @Override
     public boolean equals(final Object o) {
 
@@ -256,12 +233,6 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem 
         if (currency != that.currency) {
             return false;
         }
-        if (phaseName != null ? !phaseName.equals(that.phaseName) : that.phaseName != null) {
-            return false;
-        }
-        if (planName != null ? !planName.equals(that.planName) : that.planName != null) {
-            return false;
-        }
         return true;
     }
 
@@ -278,14 +249,41 @@ public abstract class InvoiceItemBase extends EntityBase implements InvoiceItem 
         result = 31 * result + (subscriptionId != null ? subscriptionId.hashCode() : 0);
         result = 31 * result + (bundleId != null ? bundleId.hashCode() : 0);
         result = 31 * result + (description != null ? description.hashCode() : 0);
-        result = 31 * result + (planName != null ? planName.hashCode() : 0);
-        result = 31 * result + (phaseName != null ? phaseName.hashCode() : 0);
         result = 31 * result + (rate != null ? rate.hashCode() : 0);
         result = 31 * result + (linkedItemId != null ? linkedItemId.hashCode() : 0);
         return result;
     }
 
     @Override
+    public String toString() {
+        // Note: we don't use all fields here, as the output would be overwhelming
+        // (we output all invoice items as they are generated).
+        final StringBuilder sb = new StringBuilder();
+        sb.append(getInvoiceItemType());
+        sb.append("{");
+        if (startDate != null) {
+            sb.append("startDate=").append(startDate);
+        }
+        if (endDate != null) {
+            sb.append("endDate=").append(endDate);
+        }
+        if (amount != null) {
+            sb.append("amount=").append(amount);
+        }
+        if (rate != null) {
+            sb.append("rate=").append(rate);
+        }
+        if (subscriptionId != null) {
+            sb.append("subscriptionId=").append(subscriptionId);
+        }
+        if (linkedItemId != null) {
+            sb.append("linkedItemId=").append(linkedItemId);
+        }
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
     public abstract InvoiceItemType getInvoiceItemType();
 
     @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemCatalogBase.java b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemCatalogBase.java
new file mode 100644
index 0000000..6ad9068
--- /dev/null
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemCatalogBase.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 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.invoice.model;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.invoice.api.InvoiceItem;
+
+public abstract class InvoiceItemCatalogBase extends InvoiceItemBase implements InvoiceItem {
+
+    protected final String planName;
+    protected final String phaseName;
+    protected final String usageName;
+
+    protected final String prettyPlanName;
+    protected final String prettyPhaseName;
+    protected final String prettyUsageName;
+
+    public InvoiceItemCatalogBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
+                                  @Nullable final UUID subscriptionId, @Nullable final String description, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
+                                  final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, @Nullable final UUID linkedItemId) {
+        this(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, null, null, null, startDate, endDate, amount, rate, currency, linkedItemId);
+    }
+
+
+    public InvoiceItemCatalogBase(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
+                                  @Nullable final UUID subscriptionId, @Nullable final String description, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
+                                  @Nullable final String prettyPlanName, @Nullable final String prettyPhaseName, @Nullable final String prettyUsageName,
+                                  final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final BigDecimal rate, final Currency currency, @Nullable final UUID linkedItemId) {
+        super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, startDate, endDate, amount, rate, currency, linkedItemId);
+        this.planName = planName;
+        this.phaseName = phaseName;
+        this.usageName = usageName;
+        this.prettyPlanName = prettyPlanName;
+        this.prettyPhaseName = prettyPhaseName;
+        this.prettyUsageName = prettyUsageName;
+    }
+
+
+    @Override
+    public String getPlanName() {
+        return planName;
+    }
+
+    @Override
+    public String getPhaseName() {
+        return phaseName;
+    }
+
+    @Override
+    public String getUsageName() {
+        return usageName;
+    }
+
+
+    @Override
+    public String getPrettyPlanName() {
+        return prettyPlanName;
+    }
+
+    @Override
+    public String getPrettyPhaseName() {
+        return prettyPhaseName;
+    }
+
+    @Override
+    public String getPrettyUsageName() {
+        return prettyUsageName;
+    }
+
+
+    @Override
+    public boolean matches(final Object o) {
+
+        if (!super.matches(o)) {
+            return  false;
+        }
+        final InvoiceItemCatalogBase that = (InvoiceItemCatalogBase) o;
+        if (phaseName != null ? !phaseName.equals(that.phaseName) : that.phaseName != null) {
+            return false;
+        }
+        if (planName != null ? !planName.equals(that.planName) : that.planName != null) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31 * result + (planName != null ? planName.hashCode() : 0);
+        result = 31 * result + (phaseName != null ? phaseName.hashCode() : 0);
+        result = 31 * result + (usageName != null ? usageName.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        // Note: we don't use all fields here, as the output would be overwhelming
+        // (we output all invoice items as they are generated).
+        final StringBuilder sb = new StringBuilder();
+        sb.append(getInvoiceItemType());
+        sb.append("{");
+        if (planName != null) {
+            sb.append("planName=").append(planName);
+        }
+        if (phaseName != null) {
+            sb.append("phaseName=").append(phaseName);
+        }
+        if (usageName != null) {
+            sb.append("usageName=").append(usageName);
+        }
+        if (startDate != null) {
+            sb.append("startDate=").append(startDate);
+        }
+        if (endDate != null) {
+            sb.append("endDate=").append(endDate);
+        }
+        if (amount != null) {
+            sb.append("amount=").append(amount);
+        }
+        if (rate != null) {
+            sb.append("rate=").append(rate);
+        }
+        if (subscriptionId != null) {
+            sb.append("subscriptionId=").append(subscriptionId);
+        }
+        if (linkedItemId != null) {
+            sb.append("linkedItemId=").append(linkedItemId);
+        }
+        sb.append('}');
+        return sb.toString();
+    }
+
+}
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java
index c4b0f5a..fa93938 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java
@@ -21,18 +21,33 @@ package org.killbill.billing.invoice.model;
 import java.math.BigDecimal;
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
+import org.killbill.billing.catalog.api.Catalog;
+import org.killbill.billing.catalog.api.CatalogApiException;
 import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.catalog.api.Plan;
+import org.killbill.billing.catalog.api.PlanPhase;
+import org.killbill.billing.catalog.api.Usage;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.invoice.dao.InvoiceItemModelDao;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class InvoiceItemFactory {
 
+    private static final Logger log = LoggerFactory.getLogger(InvoiceItemFactory.class);
+
     private InvoiceItemFactory() {}
 
     public static InvoiceItem fromModelDao(final InvoiceItemModelDao invoiceItemModelDao) {
+        return fromModelDaoWithCatalog(invoiceItemModelDao, null);
+    }
+
+    public static InvoiceItem fromModelDaoWithCatalog(final InvoiceItemModelDao invoiceItemModelDao, @Nullable final Catalog catalog) {
         if (invoiceItemModelDao == null) {
             return null;
         }
@@ -55,17 +70,23 @@ public class InvoiceItemFactory {
         final Currency currency = invoiceItemModelDao.getCurrency();
         final UUID linkedItemId = invoiceItemModelDao.getLinkedItemId();
 
-        final InvoiceItem item;
         final InvoiceItemType type = invoiceItemModelDao.getType();
+
+        final String [] prettyNames = computePrettyName(type, createdDate, planName, phaseName, usageName, catalog);
+        String prettyPlanName = prettyNames[0];
+        String prettyPlanPhaseName = prettyNames[1];
+        String prettyUsageName = prettyNames[2];
+
+        final InvoiceItem item;
         switch (type) {
             case EXTERNAL_CHARGE:
                 item = new ExternalChargeInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, description, startDate, amount, currency);
                 break;
             case FIXED:
-                item = new FixedPriceInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, description, startDate, amount, currency);
+                item = new FixedPriceInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, prettyPlanName, prettyPlanPhaseName, description, startDate, amount, currency);
                 break;
             case RECURRING:
-                item = new RecurringInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, description, startDate, endDate, amount, rate, currency);
+                item = new RecurringInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, prettyPlanName, prettyPlanPhaseName, description, startDate, endDate, amount, rate, currency);
                 break;
             case CBA_ADJ:
                 item = new CreditBalanceAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, linkedItemId, description, amount, currency);
@@ -80,10 +101,10 @@ public class InvoiceItemFactory {
                 item = new ItemAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, description, amount, currency, linkedItemId);
                 break;
             case USAGE:
-                item = new UsageInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, startDate, endDate, description, amount, currency);
+                item = new UsageInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, prettyPlanName, prettyPlanPhaseName, prettyUsageName, startDate, endDate, description, amount, currency);
                 break;
             case TAX:
-                item = new TaxInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, startDate, description, amount, currency, linkedItemId);
+                item = new TaxInvoiceItem(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, prettyPlanName, prettyPlanPhaseName, prettyUsageName, startDate, description, amount, currency, linkedItemId);
                 break;
             case PARENT_SUMMARY:
                 item = new ParentInvoiceItem(id, createdDate, invoiceId, accountId, childAccountId, amount, currency, description);
@@ -91,7 +112,61 @@ public class InvoiceItemFactory {
             default:
                 throw new RuntimeException("Unexpected type of event item " + type);
         }
-
         return item;
     }
+
+    //
+    // Returns an array of string for 'pretty' names [prettyPlanName, prettyPlanPhaseName, prettyUsageName]
+    //
+    private static String [] computePrettyName(final InvoiceItemType type, final DateTime createdDate, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName, @Nullable final Catalog catalog) {
+
+        final String [] result = new String[3];
+
+        final boolean computePrettyName = catalog != null &&
+                                          (type == InvoiceItemType.FIXED || type == InvoiceItemType.RECURRING || type == InvoiceItemType.TAX || type == InvoiceItemType.USAGE);
+
+        String prettyPlanName = null;
+        String prettyPlanPhaseName = null;
+        String prettyUsageName = null;
+
+        // Trying to optimize safe default behavior by checking both input and each intermediary null result at each step -- and doing poor on the Cyclomatic complexity
+        try {
+            if (computePrettyName) {
+
+                if (planName != null) {
+                    final Plan plan = catalog.findPlan(planName, createdDate);
+                    if (plan != null) {
+                        prettyPlanName = plan.getPrettyName();
+
+                        if (phaseName != null) {
+                            final PlanPhase planPhase = plan.findPhase(phaseName);
+                            if (planPhase != null) {
+                                prettyPlanPhaseName = planPhase.getPrettyName();
+
+                                if (usageName != null) {
+                                    Usage usage = null;
+                                    for (Usage cur : planPhase.getUsages()) {
+                                        if (cur.getName().equals(usageName)) {
+                                            usage = cur;
+                                            break;
+                                        }
+                                    }
+                                    if (usage != null) {
+                                        prettyUsageName = usage.getPrettyName();
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (final CatalogApiException e) {
+            log.warn("Failed to compute invoice pretty names:", e.getMessage());
+        } finally {
+            result[0] = prettyPlanName;
+            result[1] = prettyPlanPhaseName;
+            result[2] = prettyUsageName;
+        }
+        return result;
+    }
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/RecurringInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/RecurringInvoiceItem.java
index f2a4b87..45b9866 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/RecurringInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/RecurringInvoiceItem.java
@@ -31,7 +31,7 @@ import org.killbill.billing.util.UUIDs;
 
 import com.google.common.base.MoreObjects;
 
-public class RecurringInvoiceItem extends InvoiceItemBase {
+public class RecurringInvoiceItem extends InvoiceItemCatalogBase {
 
     public RecurringInvoiceItem(final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId,
                                 final String planName, final String phaseName, final LocalDate startDate, final LocalDate endDate,
@@ -42,13 +42,13 @@ public class RecurringInvoiceItem extends InvoiceItemBase {
     public RecurringInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId,
                                 final String planName, final String phaseName, final LocalDate startDate, final LocalDate endDate,
                                 final BigDecimal amount, final BigDecimal rate, final Currency currency) {
-        this(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, null, startDate, endDate, amount, rate, currency);
+        this(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, null, null, null, startDate, endDate, amount, rate, currency);
     }
 
     public RecurringInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId,
-                                final String planName, final String phaseName, @Nullable final String description, final LocalDate startDate, final LocalDate endDate,
+                                final String planName, final String phaseName, final String prettyPlanName, final String prettyPhaseName, @Nullable final String description, final LocalDate startDate, final LocalDate endDate,
                                 final BigDecimal amount, final BigDecimal rate, final Currency currency) {
-        super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, startDate, endDate, amount, rate, currency);
+        super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, null, prettyPlanName, prettyPhaseName, null, startDate, endDate, amount, rate, currency, null);
     }
 
     @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/TaxInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/TaxInvoiceItem.java
index 0b1396f..cd708e9 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/TaxInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/TaxInvoiceItem.java
@@ -27,7 +27,7 @@ import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.util.UUIDs;
 
-public class TaxInvoiceItem extends InvoiceItemBase {
+public class TaxInvoiceItem extends InvoiceItemCatalogBase {
 
     public TaxInvoiceItem(final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId, @Nullable final String description,
                           final LocalDate date, final BigDecimal amount, final Currency currency) {
@@ -36,13 +36,14 @@ public class TaxInvoiceItem extends InvoiceItemBase {
 
     public TaxInvoiceItem(final UUID id, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
                           @Nullable final String description, final LocalDate date, final BigDecimal amount, final Currency currency) {
-        this(id, null, invoiceId, accountId, bundleId, null, null, null, null, date, description, amount, currency, null);
+        this(id, null, invoiceId, accountId, bundleId, null, null, null, null, null, null, null, date, description, amount, currency, null);
     }
 
     public TaxInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId,
                           @Nullable final UUID subscriptionId, @Nullable final String planName, @Nullable final String phaseName, @Nullable final String usageName,
+                          @Nullable final String prettyPlanName, @Nullable final String prettyPhaseName, @Nullable final String prettyUsageName,
                           final LocalDate date, @Nullable final String description, final BigDecimal amount, final Currency currency, @Nullable final UUID linkedItemId) {
-        super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, date, null, amount, currency, linkedItemId);
+        super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, prettyPlanName, prettyPhaseName, prettyUsageName, date, null, amount, null, currency, linkedItemId);
     }
 
     @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java
index 15591d0..3f66f69 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/UsageInvoiceItem.java
@@ -30,18 +30,19 @@ import org.killbill.billing.util.UUIDs;
 
 import com.google.common.base.MoreObjects;
 
-public class UsageInvoiceItem extends InvoiceItemBase {
+public class UsageInvoiceItem extends InvoiceItemCatalogBase {
 
     public UsageInvoiceItem(final UUID invoiceId, final UUID accountId, @Nullable final UUID bundleId, @Nullable final UUID subscriptionId,
                             final String planName, final String phaseName, final String usageName,
                             final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final Currency currency) {
-        this(UUIDs.randomUUID(), null, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, startDate, endDate, null, amount, currency);
+        this(UUIDs.randomUUID(), null, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, null, null, null, startDate, endDate, null, amount, currency);
     }
 
     public UsageInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final UUID bundleId,
                             final UUID subscriptionId, final String planName, final String phaseName, final String usageName,
+                            final String prettyPlanName, final String prettyPhaseName, final String prettyUsageName,
                             final LocalDate startDate, final LocalDate endDate, @Nullable final String description, final BigDecimal amount, final Currency currency) {
-        super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, startDate, endDate, amount, currency);
+        super(id, createdDate, invoiceId, accountId, bundleId, subscriptionId, description, planName, phaseName, usageName, prettyPlanName, prettyPhaseName, prettyUsageName, startDate, endDate, amount, null, currency, null);
     }
 
     @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceItemFormatter.java b/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceItemFormatter.java
index 47e18a3..f59f5d8 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceItemFormatter.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceItemFormatter.java
@@ -143,16 +143,31 @@ public class DefaultInvoiceItemFormatter implements InvoiceItemFormatter {
     }
 
     @Override
+    public String getPrettyPlanName() {
+        return Strings.nullToEmpty(translator.getTranslation(item.getPrettyPlanName()));
+    }
+
+    @Override
     public String getPhaseName() {
         return Strings.nullToEmpty(translator.getTranslation(item.getPhaseName()));
     }
 
     @Override
+    public String getPrettyPhaseName() {
+        return Strings.nullToEmpty(translator.getTranslation(item.getPrettyPhaseName()));
+    }
+
+    @Override
     public String getUsageName() {
         return Strings.nullToEmpty(translator.getTranslation(item.getUsageName()));
     }
 
     @Override
+    public String getPrettyUsageName() {
+        return Strings.nullToEmpty(translator.getTranslation(item.getPrettyUsageName()));
+    }
+
+    @Override
     public UUID getId() {
         return item.getId();
     }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceItemJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceItemJson.java
index 0d9c15c..8ad9cc1 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceItemJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoiceItemJson.java
@@ -55,6 +55,9 @@ public class InvoiceItemJson extends JsonBase {
     private final String planName;
     private final String phaseName;
     private final String usageName;
+    private final String prettyPlanName;
+    private final String prettyPhaseName;
+    private final String prettyUsageName;
     private final String itemType;
     private final String description;
     private final LocalDate startDate;
@@ -74,6 +77,9 @@ public class InvoiceItemJson extends JsonBase {
                            @JsonProperty("planName") final String planName,
                            @JsonProperty("phaseName") final String phaseName,
                            @JsonProperty("usageName") final String usageName,
+                           @JsonProperty("prettyPlanName") final String prettyPlanName,
+                           @JsonProperty("prettyPhaseName") final String prettyPhaseName,
+                           @JsonProperty("prettyUsageName") final String prettyUsageName,
                            @JsonProperty("itemType") final String itemType,
                            @JsonProperty("description") final String description,
                            @JsonProperty("startDate") final LocalDate startDate,
@@ -93,6 +99,9 @@ public class InvoiceItemJson extends JsonBase {
         this.planName = planName;
         this.phaseName = phaseName;
         this.usageName = usageName;
+        this.prettyPlanName = prettyPlanName;
+        this.prettyPhaseName = prettyPhaseName;
+        this.prettyUsageName = prettyUsageName;
         this.itemType = itemType;
         this.description = description;
         this.startDate = startDate;
@@ -105,7 +114,9 @@ public class InvoiceItemJson extends JsonBase {
     public InvoiceItemJson(final InvoiceItem item, final List<InvoiceItem> childItems, @Nullable final List<AuditLog> auditLogs) {
         this(toString(item.getId()), toString(item.getInvoiceId()), toString(item.getLinkedItemId()),
              toString(item.getAccountId()), toString(item.getChildAccountId()), toString(item.getBundleId()), toString(item.getSubscriptionId()),
-             item.getPlanName(), item.getPhaseName(), item.getUsageName(), item.getInvoiceItemType().toString(),
+             item.getPlanName(), item.getPhaseName(), item.getUsageName(),
+             item.getPrettyPlanName(), item.getPrettyPhaseName(), item.getPrettyUsageName(),
+             item.getInvoiceItemType().toString(),
              item.getDescription(), item.getStartDate(), item.getEndDate(),
              item.getAmount(), item.getCurrency().name(), toInvoiceItemJson(childItems), toAuditLogJson(auditLogs));
     }
@@ -185,16 +196,31 @@ public class InvoiceItemJson extends JsonBase {
             }
 
             @Override
+            public String getPrettyPlanName() {
+                return prettyPlanName;
+            }
+
+            @Override
             public String getPhaseName() {
                 return phaseName;
             }
 
             @Override
+            public String getPrettyPhaseName() {
+                return prettyPhaseName;
+            }
+
+            @Override
             public String getUsageName() {
                 return usageName;
             }
 
             @Override
+            public String getPrettyUsageName() {
+                return prettyUsageName;
+            }
+
+            @Override
             public BigDecimal getRate() {
                 return null;
             }
@@ -270,6 +296,18 @@ public class InvoiceItemJson extends JsonBase {
         return usageName;
     }
 
+    public String getPrettyPlanName() {
+        return prettyPlanName;
+    }
+
+    public String getPrettyPhaseName() {
+        return prettyPhaseName;
+    }
+
+    public String getPrettyUsageName() {
+        return prettyUsageName;
+    }
+
     public String getItemType() {
         return itemType;
     }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index b89a910..a7ad890 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -562,6 +562,9 @@ public class InvoiceResource extends JaxRsResourceBase {
                                                    input.getPlanName(),
                                                    input.getPhaseName(),
                                                    input.getUsageName(),
+                                                   input.getPrettyPlanName(),
+                                                   input.getPrettyPhaseName(),
+                                                   input.getPrettyUsageName(),
                                                    input.getItemType(),
                                                    input.getDescription(),
                                                    input.getStartDate(),
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
index bd54e91..42f51ba 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceItemJsonSimple.java
@@ -21,14 +21,13 @@ import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.LocalDate;
-import org.mockito.Mockito;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.jaxrs.JaxrsTestSuiteNoDB;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.Test;
 
 import static org.killbill.billing.jaxrs.JaxrsTestUtils.createAuditLogsJson;
 
@@ -54,8 +53,10 @@ public class TestInvoiceItemJsonSimple extends JaxrsTestSuiteNoDB {
         final Currency currency = Currency.MXN;
         final List<AuditLogJson> auditLogs = createAuditLogsJson(clock.getUTCNow());
         final InvoiceItemJson invoiceItemJson = new InvoiceItemJson(invoiceItemId, invoiceId, linkedInvoiceItemId, accountId, childAccountId,
-                                                                                      bundleId, subscriptionId, planName, phaseName, usageName, type, description,
-                                                                                      startDate, endDate, amount, currency.name(), null, auditLogs);
+                                                                    bundleId, subscriptionId, planName, phaseName, usageName,
+                                                                    null, null, null,
+                                                                    type, description,
+                                                                    startDate, endDate, amount, currency.name(), null, auditLogs);
         Assert.assertEquals(invoiceItemJson.getInvoiceItemId(), invoiceItemId);
         Assert.assertEquals(invoiceItemJson.getInvoiceId(), invoiceId);
         Assert.assertEquals(invoiceItemJson.getLinkedInvoiceItemId(), linkedInvoiceItemId);
diff --git a/payment/src/test/java/org/killbill/billing/payment/MockRecurringInvoiceItem.java b/payment/src/test/java/org/killbill/billing/payment/MockRecurringInvoiceItem.java
index 6cb7be3..fa16ee5 100644
--- a/payment/src/test/java/org/killbill/billing/payment/MockRecurringInvoiceItem.java
+++ b/payment/src/test/java/org/killbill/billing/payment/MockRecurringInvoiceItem.java
@@ -49,28 +49,6 @@ public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem 
         this(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, startDate, endDate, amount, currency, rate, null);
     }
 
-    public MockRecurringInvoiceItem(final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId,
-                                    final String planName, final String phaseName, final String usageName, final LocalDate startDate, final LocalDate endDate,
-                                    final BigDecimal amount, final BigDecimal rate, final Currency currency, final UUID reversedItemId) {
-        this(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, startDate, endDate,
-             amount, currency, rate, reversedItemId);
-    }
-
-    public MockRecurringInvoiceItem(final UUID id, final UUID invoiceId, final UUID accountId, final UUID bundleId,
-                                    final UUID subscriptionId, final String planName, final String phaseName, final String usageName,
-                                    final LocalDate startDate, final LocalDate endDate, final BigDecimal amount,
-                                    final BigDecimal rate, final Currency currency) {
-        this(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, startDate, endDate, amount, currency, rate, null);
-
-    }
-
-    public MockRecurringInvoiceItem(final UUID id, final UUID invoiceId, final UUID accountId, final UUID bundleId,
-                                    final UUID subscriptionId, final String planName, final String phaseName, final String usageName,
-                                    final LocalDate startDate, final LocalDate endDate, final BigDecimal amount,
-                                    final BigDecimal rate, final Currency currency, final UUID reversedItemId) {
-        this(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName, startDate, endDate, amount, currency, rate, reversedItemId);
-    }
-
     public MockRecurringInvoiceItem(final UUID invoiceId, final UUID accountId, final UUID bundleId, final UUID subscriptionId, final String planName, final String phaseName, final String usageName,
                                     final LocalDate startDate, final LocalDate endDate, final BigDecimal amount, final Currency currency, final BigDecimal rate, final UUID reversedItemId) {
         this(UUID.randomUUID(), invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, usageName,
@@ -127,16 +105,31 @@ public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem 
     }
 
     @Override
+    public String getPrettyPlanName() {
+        return planName;
+    }
+
+    @Override
     public String getPhaseName() {
         return phaseName;
     }
 
     @Override
+    public String getPrettyPhaseName() {
+        return phaseName;
+    }
+
+    @Override
     public String getUsageName() {
         return usageName;
     }
 
     @Override
+    public String getPrettyUsageName() {
+        return usageName;
+    }
+
+    @Override
     public BigDecimal getAmount() {
         return amount;
     }
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java
index 9ee931b..8c611f6 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java
@@ -69,7 +69,7 @@ public class TestInvoice extends TestJaxrsBase {
 
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false, false, AuditLevel.FULL);
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false, false, AuditLevel.FULL, requestOptions);
         assertEquals(invoices.size(), 2);
         for (final Invoice invoiceJson : invoices) {
             Assert.assertEquals(invoiceJson.getAuditLogs().size(), 1);
@@ -85,21 +85,21 @@ public class TestInvoice extends TestJaxrsBase {
         final Invoice invoiceJson = invoices.get(0);
 
         // Check get with & without items
-        assertTrue(killBillClient.getInvoice(invoiceJson.getInvoiceId(), Boolean.FALSE).getItems().isEmpty());
-        assertTrue(killBillClient.getInvoice(invoiceJson.getInvoiceNumber(), Boolean.FALSE).getItems().isEmpty());
-        assertEquals(killBillClient.getInvoice(invoiceJson.getInvoiceId(), Boolean.TRUE).getItems().size(), invoiceJson.getItems().size());
-        assertEquals(killBillClient.getInvoice(invoiceJson.getInvoiceNumber(), Boolean.TRUE).getItems().size(), invoiceJson.getItems().size());
+        assertTrue(killBillClient.getInvoice(invoiceJson.getInvoiceId(), Boolean.FALSE, Boolean.FALSE, requestOptions).getItems().isEmpty());
+        assertTrue(killBillClient.getInvoice(invoiceJson.getInvoiceNumber(), Boolean.FALSE, Boolean.FALSE, requestOptions).getItems().isEmpty());
+        assertEquals(killBillClient.getInvoice(invoiceJson.getInvoiceId(), Boolean.TRUE, Boolean.FALSE, requestOptions).getItems().size(), invoiceJson.getItems().size());
+        assertEquals(killBillClient.getInvoice(invoiceJson.getInvoiceNumber(), Boolean.TRUE, Boolean.FALSE, requestOptions).getItems().size(), invoiceJson.getItems().size());
 
         // Check we can retrieve an individual invoice
-        final Invoice firstInvoice = killBillClient.getInvoice(invoiceJson.getInvoiceId());
+        final Invoice firstInvoice = killBillClient.getInvoice(invoiceJson.getInvoiceId(), requestOptions);
         assertEquals(firstInvoice, invoiceJson);
 
         // Check we can retrieve the invoice by number
-        final Invoice firstInvoiceByNumberJson = killBillClient.getInvoice(invoiceJson.getInvoiceNumber());
+        final Invoice firstInvoiceByNumberJson = killBillClient.getInvoice(invoiceJson.getInvoiceNumber(), requestOptions);
         assertEquals(firstInvoiceByNumberJson, invoiceJson);
 
         // Check we can retrieve the HTML version
-        final String htmlInvoice = killBillClient.getInvoiceAsHtml(invoiceJson.getInvoiceId());
+        final String htmlInvoice = killBillClient.getInvoiceAsHtml(invoiceJson.getInvoiceId(), requestOptions);
         assertEquals(htmlInvoice, "<html>\n" +
                                   "    <head>\n" +
                                   "        <style type=\"text/css\">\n" +
@@ -201,7 +201,7 @@ public class TestInvoice extends TestJaxrsBase {
         final InvoiceDryRun dryRunArg = new InvoiceDryRun(DryRunType.UPCOMING_INVOICE, null,
                                                           null, null, null, null, null, null, null, null, null, null);
 
-        final Invoice dryRunInvoice = killBillClient.createDryRunInvoice(accountJson.getAccountId(), null, dryRunArg, createdBy, reason, comment);
+        final Invoice dryRunInvoice = killBillClient.createDryRunInvoice(accountJson.getAccountId(), null, dryRunArg, requestOptions);
         assertEquals(dryRunInvoice.getBalance(), new BigDecimal("249.95"));
         assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2012, 6, 25));
         assertEquals(dryRunInvoice.getItems().size(), 1);
@@ -211,10 +211,10 @@ public class TestInvoice extends TestJaxrsBase {
 
         final LocalDate futureDate = dryRunInvoice.getTargetDate();
         // The one more time with no DryRun
-        killBillClient.createInvoice(accountJson.getAccountId(), futureDate, createdBy, reason, comment);
+        killBillClient.createInvoice(accountJson.getAccountId(), futureDate, requestOptions);
 
         // Check again # invoices, should be 3 this time
-        final List<Invoice> newInvoiceList = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
+        final List<Invoice> newInvoiceList = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
         assertEquals(newInvoiceList.size(), 3);
     }
 
@@ -227,7 +227,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountWithDefaultPaymentMethod();
         final InvoiceDryRun dryRunArg = new InvoiceDryRun(DryRunType.TARGET_DATE, SubscriptionEventType.START_BILLING,
                                                           null, "Assault-Rifle", ProductCategory.BASE, BillingPeriod.ANNUAL, null, null, null, null, null, null);
-        final Invoice dryRunInvoice = killBillClient.createDryRunInvoice(accountJson.getAccountId(), new LocalDate(initialDate, DateTimeZone.forID(accountJson.getTimeZone())), dryRunArg, createdBy, reason, comment);
+        final Invoice dryRunInvoice = killBillClient.createDryRunInvoice(accountJson.getAccountId(), new LocalDate(initialDate, DateTimeZone.forID(accountJson.getTimeZone())), dryRunArg, requestOptions);
         assertEquals(dryRunInvoice.getItems().size(), 1);
 
     }
@@ -238,7 +238,7 @@ public class TestInvoice extends TestJaxrsBase {
 
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
         assertEquals(invoices.size(), 2);
 
         final Invoice invoiceWithPositiveAmount = Iterables.tryFind(invoices, new Predicate<Invoice>() {
@@ -249,7 +249,7 @@ public class TestInvoice extends TestJaxrsBase {
         }).orNull();
         Assert.assertNotNull(invoiceWithPositiveAmount);
 
-        final InvoicePayments objFromJson = killBillClient.getInvoicePayment(invoiceWithPositiveAmount.getInvoiceId());
+        final InvoicePayments objFromJson = killBillClient.getInvoicePayment(invoiceWithPositiveAmount.getInvoiceId(), requestOptions);
         assertEquals(objFromJson.size(), 1);
         assertEquals(invoiceWithPositiveAmount.getAmount().compareTo(objFromJson.get(0).getPurchasedAmount()), 0);
     }
@@ -262,20 +262,20 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Check there was no payment made
-        assertEquals(killBillClient.getPaymentsForAccount(accountJson.getAccountId()).size(), 0);
+        assertEquals(killBillClient.getPaymentsForAccount(accountJson.getAccountId(), requestOptions).size(), 0);
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
         assertEquals(invoices.size(), 2);
         final Invoice invoiceToPay = invoices.get(1);
         assertEquals(invoiceToPay.getBalance().compareTo(BigDecimal.ZERO), 1);
 
         // Pay all invoices
-        killBillClient.payAllInvoices(accountJson.getAccountId(), true, null, createdBy, reason, comment);
-        for (final Invoice invoice : killBillClient.getInvoicesForAccount(accountJson.getAccountId())) {
+        killBillClient.payAllInvoices(accountJson.getAccountId(), true, null, requestOptions);
+        for (final Invoice invoice : killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions)) {
             assertEquals(invoice.getBalance().compareTo(BigDecimal.ZERO), 0);
         }
-        assertEquals(killBillClient.getPaymentsForAccount(accountJson.getAccountId()).size(), 1);
+        assertEquals(killBillClient.getPaymentsForAccount(accountJson.getAccountId(), requestOptions).size(), 1);
     }
 
     @Test(groups = "slow", description = "Can create an insta-payment")
@@ -286,7 +286,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
         assertEquals(invoices.size(), 2);
 
         for (final Invoice cur : invoices) {
@@ -299,7 +299,7 @@ public class TestInvoice extends TestJaxrsBase {
             invoicePayment.setPurchasedAmount(cur.getBalance());
             invoicePayment.setAccountId(accountJson.getAccountId());
             invoicePayment.setTargetInvoiceId(cur.getInvoiceId());
-            final InvoicePayment objFromJson = killBillClient.createInvoicePayment(invoicePayment, true, createdBy, reason, comment);
+            final InvoicePayment objFromJson = killBillClient.createInvoicePayment(invoicePayment, true, requestOptions);
             assertEquals(cur.getBalance().compareTo(objFromJson.getPurchasedAmount()), 0);
         }
     }
@@ -309,11 +309,11 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Verify we didn't get any invoicePayment
-        final List<InvoicePayment> noPaymentsFromJson = killBillClient.getInvoicePaymentsForAccount(accountJson.getAccountId());
+        final List<InvoicePayment> noPaymentsFromJson = killBillClient.getInvoicePaymentsForAccount(accountJson.getAccountId(), requestOptions);
         assertEquals(noPaymentsFromJson.size(), 0);
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
         final UUID invoiceId = invoices.get(1).getInvoiceId();
@@ -323,17 +323,17 @@ public class TestInvoice extends TestJaxrsBase {
         invoicePayment.setPurchasedAmount(BigDecimal.TEN);
         invoicePayment.setAccountId(accountJson.getAccountId());
         invoicePayment.setTargetInvoiceId(invoiceId);
-        killBillClient.createInvoicePayment(invoicePayment, true, createdBy, reason, comment);
+        killBillClient.createInvoicePayment(invoicePayment, true, requestOptions);
 
         // Verify we indeed got the invoicePayment
-        final List<InvoicePayment> paymentsFromJson = killBillClient.getInvoicePaymentsForAccount(accountJson.getAccountId());
+        final List<InvoicePayment> paymentsFromJson = killBillClient.getInvoicePaymentsForAccount(accountJson.getAccountId(), requestOptions);
         assertEquals(paymentsFromJson.size(), 1);
         assertEquals(paymentsFromJson.get(0).getPurchasedAmount().compareTo(BigDecimal.TEN), 0);
         assertEquals(paymentsFromJson.get(0).getTargetInvoiceId(), invoiceId);
 
         // Check the PaymentMethod from paymentMethodId returned in the Payment object
         final UUID paymentMethodId = paymentsFromJson.get(0).getPaymentMethodId();
-        final PaymentMethod paymentMethodJson = killBillClient.getPaymentMethod(paymentMethodId);
+        final PaymentMethod paymentMethodJson = killBillClient.getPaymentMethod(paymentMethodId, requestOptions);
         assertEquals(paymentMethodJson.getPaymentMethodId(), paymentMethodId);
         assertEquals(paymentMethodJson.getAccountId(), accountJson.getAccountId());
         assertEquals(paymentMethodJson.getPluginName(), ExternalPaymentProviderPlugin.PLUGIN_NAME);
@@ -345,7 +345,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false);
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false, requestOptions);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
         final Invoice invoice = invoices.get(1);
@@ -360,10 +360,10 @@ public class TestInvoice extends TestJaxrsBase {
         adjustmentInvoiceItem.setAccountId(accountJson.getAccountId());
         adjustmentInvoiceItem.setInvoiceId(invoice.getInvoiceId());
         adjustmentInvoiceItem.setInvoiceItemId(invoiceItem.getInvoiceItemId());
-        killBillClient.adjustInvoiceItem(invoiceItem, createdBy, reason, comment);
+        killBillClient.adjustInvoiceItem(invoiceItem, requestOptions);
 
         // Verify the new invoice balance is zero
-        final Invoice adjustedInvoice = killBillClient.getInvoice(invoice.getInvoiceId(), true, AuditLevel.FULL);
+        final Invoice adjustedInvoice = killBillClient.getInvoice(invoice.getInvoiceId(), true, false, AuditLevel.FULL, requestOptions);
         assertEquals(adjustedInvoice.getAmount().compareTo(BigDecimal.ZERO), 0);
 
         // Verify invoice audit logs
@@ -406,7 +406,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false);
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false, requestOptions);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
         final Invoice invoice = invoices.get(1);
@@ -424,10 +424,10 @@ public class TestInvoice extends TestJaxrsBase {
         adjustmentInvoiceItem.setInvoiceItemId(invoiceItem.getInvoiceItemId());
         adjustmentInvoiceItem.setAmount(adjustedAmount);
         adjustmentInvoiceItem.setCurrency(invoice.getCurrency().name());
-        killBillClient.adjustInvoiceItem(adjustmentInvoiceItem, createdBy, reason, comment);
+        killBillClient.adjustInvoiceItem(adjustmentInvoiceItem, requestOptions);
 
         // Verify the new invoice balance
-        final Invoice adjustedInvoice = killBillClient.getInvoice(invoice.getInvoiceId());
+        final Invoice adjustedInvoice = killBillClient.getInvoice(invoice.getInvoiceId(), requestOptions);
         final BigDecimal adjustedInvoiceBalance = invoice.getBalance().add(adjustedAmount.negate()).setScale(2, BigDecimal.ROUND_HALF_UP);
         assertEquals(adjustedInvoice.getBalance().compareTo(adjustedInvoiceBalance), 0, String.format("Adjusted invoice balance is %s, should be %s", adjustedInvoice.getBalance(), adjustedInvoiceBalance));
     }
@@ -437,7 +437,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
@@ -446,15 +446,16 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge.setAmount(chargeAmount);
         externalCharge.setCurrency(accountJson.getCurrency());
         externalCharge.setDescription(UUID.randomUUID().toString());
-        final InvoiceItem createdExternalCharge = killBillClient.createExternalCharge(externalCharge, clock.getUTCToday(), false, true, createdBy, reason, comment);
-        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharge.getInvoiceId(), true);
+        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(ImmutableList.of(externalCharge), clock.getUTCToday(), false, true, requestOptions);
+        assertEquals(createdExternalCharges.size(), 1);
+        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true, false, requestOptions);
         assertEquals(invoiceWithItems.getBalance().compareTo(chargeAmount), 0);
         assertEquals(invoiceWithItems.getItems().size(), 1);
         assertEquals(invoiceWithItems.getItems().get(0).getDescription(), externalCharge.getDescription());
         assertNull(invoiceWithItems.getItems().get(0).getBundleId());
 
         // Verify the total number of invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 3);
     }
 
     @Test(groups = "slow", description = "Can create multiple external charges")
@@ -462,7 +463,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
@@ -483,13 +484,13 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge2.setDescription(UUID.randomUUID().toString());
         externalCharges.add(externalCharge2);
 
-        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(externalCharges, clock.getUTCToday(), false, true, createdBy, reason, comment);
+        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(externalCharges, clock.getUTCToday(), false, true, requestOptions);
         assertEquals(createdExternalCharges.size(), 2);
-        assertEquals(createdExternalCharges.get(0).getCurrency().toString(), accountJson.getCurrency());
-        assertEquals(createdExternalCharges.get(1).getCurrency().toString(), accountJson.getCurrency());
+        assertEquals(createdExternalCharges.get(0).getCurrency(), accountJson.getCurrency());
+        assertEquals(createdExternalCharges.get(1).getCurrency(), accountJson.getCurrency());
 
         // Verify the total number of invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 3);
     }
 
     @Test(groups = "slow", description = "Can create multiple external charges with same invoice and external keys")
@@ -497,7 +498,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
@@ -518,23 +519,20 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge2.setDescription(UUID.randomUUID().toString());
         externalCharges.add(externalCharge2);
 
-        String paymentExternalKey = "anyPaymentExternalKey";
-        String transactionExternalKey = "anyTransactionExternalKey";
+        final String paymentExternalKey = "anyPaymentExternalKey";
+        final String transactionExternalKey = "anyTransactionExternalKey";
 
         final List<InvoiceItem> createdExternalCharges =
                 killBillClient.createExternalCharges(externalCharges, clock.getUTCToday(), true, true,
-                                                     paymentExternalKey, transactionExternalKey, RequestOptions.builder()
-                                                                                                               .withCreatedBy(createdBy)
-                                                                                                               .withReason(reason)
-                                                                                                               .withComment(comment).build());
+                                                     paymentExternalKey, transactionExternalKey, requestOptions);
         assertEquals(createdExternalCharges.size(), 2);
-        assertEquals(createdExternalCharges.get(0).getCurrency().toString(), accountJson.getCurrency());
-        assertEquals(createdExternalCharges.get(1).getCurrency().toString(), accountJson.getCurrency());
+        assertEquals(createdExternalCharges.get(0).getCurrency(), accountJson.getCurrency());
+        assertEquals(createdExternalCharges.get(1).getCurrency(), accountJson.getCurrency());
 
         // Verify the total number of invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 3);
 
-        Payments payments = killBillClient.getPaymentsForAccount(accountJson.getAccountId(), AuditLevel.NONE, RequestOptions.empty());
+        final Payments payments = killBillClient.getPaymentsForAccount(accountJson.getAccountId(), AuditLevel.NONE, requestOptions);
         assertNotNull(payments);
         // Verify payment with paymentExternalKey provided
         assertEquals(payments.get(payments.size() - 1).getPaymentExternalKey(), paymentExternalKey);
@@ -547,7 +545,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
@@ -555,14 +553,15 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge.setAccountId(accountJson.getAccountId());
         externalCharge.setAmount(chargeAmount);
         externalCharge.setCurrency(accountJson.getCurrency());
-        final InvoiceItem createdExternalCharge = killBillClient.createExternalCharge(externalCharge, clock.getUTCToday(), true, true, createdBy, reason, comment);
-        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharge.getInvoiceId(), true);
+        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(ImmutableList.<InvoiceItem>of(externalCharge), clock.getUTCToday(), true, true, requestOptions);
+        assertEquals(createdExternalCharges.size(), 1);
+        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true);
         assertEquals(invoiceWithItems.getBalance().compareTo(BigDecimal.ZERO), 0);
         assertEquals(invoiceWithItems.getItems().size(), 1);
         assertNull(invoiceWithItems.getItems().get(0).getBundleId());
 
         // Verify the total number of invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 3);
     }
 
     @Test(groups = "slow", description = "Can create an external charge for a bundle")
@@ -570,7 +569,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
@@ -580,14 +579,15 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge.setAmount(chargeAmount);
         externalCharge.setCurrency(accountJson.getCurrency());
         externalCharge.setBundleId(bundleId);
-        final InvoiceItem createdExternalCharge = killBillClient.createExternalCharge(externalCharge, clock.getUTCToday(), false, true, createdBy, reason, comment);
-        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharge.getInvoiceId(), true);
+        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(ImmutableList.<InvoiceItem>of(externalCharge), clock.getUTCToday(), false, true, requestOptions);
+        assertEquals(createdExternalCharges.size(), 1);
+        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true);
         assertEquals(invoiceWithItems.getBalance().compareTo(chargeAmount), 0);
         assertEquals(invoiceWithItems.getItems().size(), 1);
         assertEquals(invoiceWithItems.getItems().get(0).getBundleId(), bundleId);
 
         // Verify the total number of invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 3);
     }
 
     @Test(groups = "slow", description = "Can create an external charge on an existing invoice")
@@ -595,7 +595,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false);
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false, requestOptions);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
         final UUID invoiceId = invoices.get(1).getInvoiceId();
@@ -609,13 +609,14 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge.setAmount(chargeAmount);
         externalCharge.setCurrency(accountJson.getCurrency());
         externalCharge.setInvoiceId(invoiceId);
-        final InvoiceItem createdExternalCharge = killBillClient.createExternalCharge(externalCharge, clock.getUTCToday(), false, true, createdBy, reason, comment);
-        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharge.getInvoiceId(), true);
+        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(ImmutableList.of(externalCharge), clock.getUTCToday(), false, true, requestOptions);
+        assertEquals(createdExternalCharges.size(), 1);
+        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true, false, requestOptions);
         assertEquals(invoiceWithItems.getItems().size(), originalNumberOfItemsForInvoice + 1);
         assertNull(invoiceWithItems.getItems().get(originalNumberOfItemsForInvoice).getBundleId());
 
         // Verify the new invoice balance
-        final Invoice adjustedInvoice = killBillClient.getInvoice(invoiceId);
+        final Invoice adjustedInvoice = killBillClient.getInvoice(invoiceId, requestOptions);
         final BigDecimal adjustedInvoiceBalance = originalInvoiceAmount.add(chargeAmount.setScale(2, RoundingMode.HALF_UP));
         assertEquals(adjustedInvoice.getBalance().compareTo(adjustedInvoiceBalance), 0);
     }
@@ -625,11 +626,10 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false);
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false, requestOptions);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
         final UUID invoiceId = invoices.get(1).getInvoiceId();
-        final BigDecimal originalInvoiceAmount = invoices.get(1).getAmount();
         final int originalNumberOfItemsForInvoice = invoices.get(1).getItems().size();
 
         // Post an external charge
@@ -639,13 +639,14 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge.setAmount(chargeAmount);
         externalCharge.setCurrency(accountJson.getCurrency());
         externalCharge.setInvoiceId(invoiceId);
-        final InvoiceItem createdExternalCharge = killBillClient.createExternalCharge(externalCharge, clock.getUTCToday(), true, true, createdBy, reason, comment);
-        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharge.getInvoiceId(), true);
+        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(ImmutableList.of(externalCharge), clock.getUTCToday(), true, true, requestOptions);
+        assertEquals(createdExternalCharges.size(), 1);
+        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true,false, requestOptions);
         assertEquals(invoiceWithItems.getItems().size(), originalNumberOfItemsForInvoice + 1);
         assertNull(invoiceWithItems.getItems().get(originalNumberOfItemsForInvoice).getBundleId());
 
         // Verify the new invoice balance
-        final Invoice adjustedInvoice = killBillClient.getInvoice(invoiceId);
+        final Invoice adjustedInvoice = killBillClient.getInvoice(invoiceId, requestOptions);
         assertEquals(adjustedInvoice.getBalance().compareTo(BigDecimal.ZERO), 0);
     }
 
@@ -654,7 +655,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false);
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false, requestOptions);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
         final UUID invoiceId = invoices.get(1).getInvoiceId();
@@ -670,13 +671,13 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge.setCurrency(accountJson.getCurrency());
         externalCharge.setInvoiceId(invoiceId);
         externalCharge.setBundleId(bundleId);
-        final InvoiceItem createdExternalCharge = killBillClient.createExternalCharge(externalCharge, clock.getUTCToday(), false, true, createdBy, reason, comment);
-        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharge.getInvoiceId(), true);
+        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(ImmutableList.<InvoiceItem>of(externalCharge), clock.getUTCToday(), false, true, requestOptions);
+        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true,false, requestOptions);
         assertEquals(invoiceWithItems.getItems().size(), originalNumberOfItemsForInvoice + 1);
         assertEquals(invoiceWithItems.getItems().get(originalNumberOfItemsForInvoice).getBundleId(), bundleId);
 
         // Verify the new invoice balance
-        final Invoice adjustedInvoice = killBillClient.getInvoice(invoiceId);
+        final Invoice adjustedInvoice = killBillClient.getInvoice(invoiceId, requestOptions);
         final BigDecimal adjustedInvoiceBalance = originalInvoiceAmount.add(chargeAmount.setScale(2, RoundingMode.HALF_UP));
         assertEquals(adjustedInvoice.getBalance().compareTo(adjustedInvoiceBalance), 0);
     }
@@ -690,17 +691,17 @@ public class TestInvoice extends TestJaxrsBase {
             crappyWaitForLackOfProperSynchonization();
         }
 
-        final Invoices allInvoices = killBillClient.getInvoices();
+        final Invoices allInvoices = killBillClient.getInvoices(requestOptions);
         Assert.assertEquals(allInvoices.size(), 5);
 
         for (final Invoice invoice : allInvoices) {
-            Assert.assertEquals(killBillClient.searchInvoices(invoice.getInvoiceId().toString()).size(), 1);
-            Assert.assertEquals(killBillClient.searchInvoices(invoice.getAccountId().toString()).size(), 5);
-            Assert.assertEquals(killBillClient.searchInvoices(invoice.getInvoiceNumber().toString()).size(), 1);
-            Assert.assertEquals(killBillClient.searchInvoices(invoice.getCurrency().toString()).size(), 5);
+            Assert.assertEquals(killBillClient.searchInvoices(invoice.getInvoiceId().toString(), requestOptions).size(), 1);
+            Assert.assertEquals(killBillClient.searchInvoices(invoice.getAccountId().toString(), requestOptions).size(), 5);
+            Assert.assertEquals(killBillClient.searchInvoices(invoice.getInvoiceNumber().toString(), requestOptions).size(), 1);
+            Assert.assertEquals(killBillClient.searchInvoices(invoice.getCurrency().toString(), requestOptions).size(), 5);
         }
 
-        Invoices page = killBillClient.getInvoices(0L, 1L);
+        Invoices page = killBillClient.getInvoices(0L, 1L, requestOptions);
         for (int i = 0; i < 5; i++) {
             Assert.assertNotNull(page);
             Assert.assertEquals(page.size(), 1);
@@ -715,20 +716,19 @@ public class TestInvoice extends TestJaxrsBase {
 
         final Account account = createAccountWithDefaultPaymentMethod();
 
-        final DateTime effectiveDate = clock.getUTCNow();
         final BigDecimal creditAmount = BigDecimal.TEN;
         final Credit credit = new Credit();
         credit.setAccountId(account.getAccountId());
         credit.setInvoiceId(null);
         credit.setCreditAmount(creditAmount);
-        final Credit creditJson = killBillClient.createCredit(credit, false, createdBy, reason, comment);
+        final Credit creditJson = killBillClient.createCredit(credit, false, requestOptions);
 
         Invoice invoice = killBillClient.getInvoice(creditJson.getInvoiceId());
         Assert.assertEquals(invoice.getStatus(), InvoiceStatus.DRAFT.toString());
 
-        killBillClient.commitInvoice(invoice.getInvoiceId(), createdBy, reason, comment);
+        killBillClient.commitInvoice(invoice.getInvoiceId(), requestOptions);
 
-        invoice = killBillClient.getInvoice(creditJson.getInvoiceId());
+        invoice = killBillClient.getInvoice(creditJson.getInvoiceId(), requestOptions);
         Assert.assertEquals(invoice.getStatus(), InvoiceStatus.COMMITTED.toString());
     }
 
@@ -737,7 +737,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, true);
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, true, requestOptions);
         assertEquals(invoices.size(), 2);
 
         // Migrate an invoice with one external charge
@@ -749,7 +749,7 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge.setItemType(InvoiceItemType.EXTERNAL_CHARGE.toString());
         externalCharge.setCurrency(accountJson.getCurrency());
 
-        final Account accountWithBalance = killBillClient.getAccount(accountJson.getAccountId(), true, true);
+        final Account accountWithBalance = killBillClient.getAccount(accountJson.getAccountId(), true, true, requestOptions);
 
         final Invoice migrationInvoice = killBillClient.createMigrationInvoice(accountJson.getAccountId(), null, ImmutableList.<InvoiceItem>of(externalCharge), requestOptions);
         assertEquals(migrationInvoice.getBalance(), BigDecimal.ZERO);
@@ -757,10 +757,10 @@ public class TestInvoice extends TestJaxrsBase {
         assertEquals(migrationInvoice.getItems().get(0).getAmount().compareTo(chargeAmount), 0);
         assertEquals(migrationInvoice.getItems().get(0).getCurrency(), accountJson.getCurrency());
 
-        final List<Invoice> invoicesWithMigration = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, true);
+        final List<Invoice> invoicesWithMigration = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, true, requestOptions);
         assertEquals(invoicesWithMigration.size(), 3);
 
-        final Account accountWithBalanceAfterMigration = killBillClient.getAccount(accountJson.getAccountId(), true, true);
+        final Account accountWithBalanceAfterMigration = killBillClient.getAccount(accountJson.getAccountId(), true, true, requestOptions);
         assertEquals(accountWithBalanceAfterMigration.getAccountBalance().compareTo(accountWithBalance.getAccountBalance()), 0);
     }
 
@@ -778,21 +778,21 @@ public class TestInvoice extends TestJaxrsBase {
         // insert credit to child account
         final Credit creditJson = killBillClient.createCredit(credit, true, requestOptions);
 
-        Invoices childInvoices = killBillClient.getInvoicesForAccount(childAccount.getAccountId(), true, false);
+        Invoices childInvoices = killBillClient.getInvoicesForAccount(childAccount.getAccountId(), true, false, requestOptions);
         Assert.assertEquals(childInvoices.size(), 1);
         Assert.assertEquals(childInvoices.get(0).getCreditAdj().compareTo(BigDecimal.TEN), 0);
 
-        Invoices parentInvoices = killBillClient.getInvoicesForAccount(parentAccount.getAccountId(), true, false);
+        Invoices parentInvoices = killBillClient.getInvoicesForAccount(parentAccount.getAccountId(), true, false, requestOptions);
         Assert.assertEquals(parentInvoices.size(), 0);
 
         // transfer credit to parent account
         killBillClient.transferChildCreditToParent(childAccount.getAccountId(), requestOptions);
 
-        childInvoices = killBillClient.getInvoicesForAccount(childAccount.getAccountId(), true, false);
+        childInvoices = killBillClient.getInvoicesForAccount(childAccount.getAccountId(), true, false, requestOptions);
         Assert.assertEquals(childInvoices.size(), 2);
         Assert.assertEquals(childInvoices.get(1).getCreditAdj().compareTo(BigDecimal.TEN.negate()), 0);
 
-        parentInvoices = killBillClient.getInvoicesForAccount(parentAccount.getAccountId(), true, false);
+        parentInvoices = killBillClient.getInvoicesForAccount(parentAccount.getAccountId(), true, false, requestOptions);
         Assert.assertEquals(parentInvoices.size(), 1);
         Assert.assertEquals(parentInvoices.get(0).getCreditAdj().compareTo(BigDecimal.TEN), 0);
     }
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestUsage.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestUsage.java
index dfc49e3..5d909f1 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestUsage.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestUsage.java
@@ -19,6 +19,8 @@ package org.killbill.billing.jaxrs;
 
 import java.util.UUID;
 
+import javax.annotation.Nullable;
+
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.PriceListSet;
@@ -26,11 +28,15 @@ import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.client.KillBillClientException;
 import org.killbill.billing.client.model.Account;
 import org.killbill.billing.client.model.Bundle;
+import org.killbill.billing.client.model.InvoiceItem;
+import org.killbill.billing.client.model.Invoices;
 import org.killbill.billing.client.model.RolledUpUsage;
 import org.killbill.billing.client.model.Subscription;
 import org.killbill.billing.client.model.SubscriptionUsageRecord;
 import org.killbill.billing.client.model.UnitUsageRecord;
 import org.killbill.billing.client.model.UsageRecord;
+import org.killbill.billing.invoice.api.InvoiceItemType;
+import org.killbill.billing.util.api.AuditLevel;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -61,9 +67,7 @@ public class TestUsage extends TestJaxrsBase {
         final Bundle bundle = killBillClient.createSubscriptionWithAddOns(ImmutableList.<Subscription>of(base, addOn),
                                                                           null,
                                                                           DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC,
-                                                                          createdBy,
-                                                                          reason,
-                                                                          comment);
+                                                                          requestOptions);
         final UUID addOnSubscriptionId = Iterables.<Subscription>find(bundle.getSubscriptions(),
                                                                       new Predicate<Subscription>() {
                                                                           @Override
@@ -90,32 +94,51 @@ public class TestUsage extends TestJaxrsBase {
         usage.setSubscriptionId(addOnSubscriptionId);
         usage.setUnitUsageRecords(ImmutableList.<UnitUsageRecord>of(unitUsageRecord));
 
-        killBillClient.createSubscriptionUsageRecord(usage, createdBy, reason, comment);
+        killBillClient.createSubscriptionUsageRecord(usage, requestOptions);
 
-        final RolledUpUsage retrievedUsage1 = killBillClient.getRolledUpUsage(addOnSubscriptionId, unitUsageRecord.getUnitType(), clock.getUTCToday().minusDays(1), clock.getUTCToday());
+        final RolledUpUsage retrievedUsage1 = killBillClient.getRolledUpUsage(addOnSubscriptionId, unitUsageRecord.getUnitType(), clock.getUTCToday().minusDays(1), clock.getUTCToday(), requestOptions);
         Assert.assertEquals(retrievedUsage1.getSubscriptionId(), usage.getSubscriptionId());
         Assert.assertEquals(retrievedUsage1.getRolledUpUnits().size(), 1);
         Assert.assertEquals(retrievedUsage1.getRolledUpUnits().get(0).getUnitType(), unitUsageRecord.getUnitType());
         // endDate is excluded
         Assert.assertEquals((long) retrievedUsage1.getRolledUpUnits().get(0).getAmount(), 10);
 
-        final RolledUpUsage retrievedUsage2 = killBillClient.getRolledUpUsage(addOnSubscriptionId, unitUsageRecord.getUnitType(), clock.getUTCToday().minusDays(1), clock.getUTCToday().plusDays(1));
+        final RolledUpUsage retrievedUsage2 = killBillClient.getRolledUpUsage(addOnSubscriptionId, unitUsageRecord.getUnitType(), clock.getUTCToday().minusDays(1), clock.getUTCToday().plusDays(1), requestOptions);
         Assert.assertEquals(retrievedUsage2.getSubscriptionId(), usage.getSubscriptionId());
         Assert.assertEquals(retrievedUsage2.getRolledUpUnits().size(), 1);
         Assert.assertEquals(retrievedUsage2.getRolledUpUnits().get(0).getUnitType(), unitUsageRecord.getUnitType());
         Assert.assertEquals((long) retrievedUsage2.getRolledUpUnits().get(0).getAmount(), 15);
 
-        final RolledUpUsage retrievedUsage3 = killBillClient.getRolledUpUsage(addOnSubscriptionId, unitUsageRecord.getUnitType(), clock.getUTCToday(), clock.getUTCToday().plusDays(1));
+        final RolledUpUsage retrievedUsage3 = killBillClient.getRolledUpUsage(addOnSubscriptionId, unitUsageRecord.getUnitType(), clock.getUTCToday(), clock.getUTCToday().plusDays(1), requestOptions);
         Assert.assertEquals(retrievedUsage3.getSubscriptionId(), usage.getSubscriptionId());
         Assert.assertEquals(retrievedUsage3.getRolledUpUnits().size(), 1);
         Assert.assertEquals(retrievedUsage3.getRolledUpUnits().get(0).getUnitType(), unitUsageRecord.getUnitType());
         Assert.assertEquals((long) retrievedUsage3.getRolledUpUnits().get(0).getAmount(), 5);
 
-        final RolledUpUsage retrievedUsage4 = killBillClient.getRolledUpUsage(addOnSubscriptionId, null, clock.getUTCToday(), clock.getUTCToday().plusDays(1));
+        final RolledUpUsage retrievedUsage4 = killBillClient.getRolledUpUsage(addOnSubscriptionId, null, clock.getUTCToday(), clock.getUTCToday().plusDays(1), requestOptions);
         Assert.assertEquals(retrievedUsage4.getSubscriptionId(), usage.getSubscriptionId());
         Assert.assertEquals(retrievedUsage4.getRolledUpUnits().size(), 1);
         Assert.assertEquals(retrievedUsage4.getRolledUpUnits().get(0).getUnitType(), "bullets");
         Assert.assertEquals((long) retrievedUsage4.getRolledUpUnits().get(0).getAmount(), 5);
+
+        clock.addMonths(1);
+        crappyWaitForLackOfProperSynchonization();
+
+
+        final Invoices invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false, false, AuditLevel.MINIMAL, requestOptions);
+        Assert.assertEquals(invoices.size(), 2);
+
+        final InvoiceItem usageItem =  Iterables.tryFind(invoices.get(1).getItems(), new Predicate<InvoiceItem>() {
+            @Override
+            public boolean apply(final InvoiceItem input) {
+                return InvoiceItemType.valueOf(input.getItemType()) == InvoiceItemType.USAGE;
+            }
+        }).orNull();
+        Assert.assertNotNull(usageItem);
+
+        Assert.assertEquals(usageItem.getPrettyPlanName(), "Bullet Monthly Plan");
+        Assert.assertEquals(usageItem.getPrettyPhaseName(), "Bullet Monthly Plan Evergreen");
+        Assert.assertEquals(usageItem.getPrettyUsageName(), "Bullet Usage In Arrear");
     }
 
     @Test(groups = "slow", description = "Test tracking ID already exists")
@@ -139,10 +162,7 @@ public class TestUsage extends TestJaxrsBase {
 
         final Bundle bundle = killBillClient.createSubscriptionWithAddOns(ImmutableList.<Subscription>of(base, addOn),
                                                                           null,
-                                                                          DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC,
-                                                                          createdBy,
-                                                                          reason,
-                                                                          comment);
+                                                                          DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC, requestOptions);
         final UUID addOnSubscriptionId = Iterables.<Subscription>find(bundle.getSubscriptions(),
                                                                       new Predicate<Subscription>() {
                                                                           @Override
@@ -164,10 +184,10 @@ public class TestUsage extends TestJaxrsBase {
         usage.setTrackingId(UUID.randomUUID().toString());
         usage.setUnitUsageRecords(ImmutableList.<UnitUsageRecord>of(unitUsageRecord));
 
-        killBillClient.createSubscriptionUsageRecord(usage, createdBy, reason, comment);
+        killBillClient.createSubscriptionUsageRecord(usage, requestOptions);
 
         try {
-            killBillClient.createSubscriptionUsageRecord(usage, createdBy, reason, comment);
+            killBillClient.createSubscriptionUsageRecord(usage, requestOptions );
             Assert.fail();
         }
         catch (final KillBillClientException e) {
diff --git a/util/src/test/java/org/killbill/billing/mock/MockPlan.java b/util/src/test/java/org/killbill/billing/mock/MockPlan.java
index 09b4e88..dc78dea 100644
--- a/util/src/test/java/org/killbill/billing/mock/MockPlan.java
+++ b/util/src/test/java/org/killbill/billing/mock/MockPlan.java
@@ -63,6 +63,11 @@ public class MockPlan implements Plan {
     }
 
     @Override
+    public String getPrettyName() {
+        return name;
+    }
+
+    @Override
     public Date getEffectiveDateForExistingSubscriptions() {
         return new Date();
     }
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 9722cb2..0d2398c 100644
--- a/util/src/test/java/org/killbill/billing/mock/MockPriceList.java
+++ b/util/src/test/java/org/killbill/billing/mock/MockPriceList.java
@@ -45,6 +45,11 @@ public class MockPriceList implements PriceList {
     }
 
     @Override
+    public String getPrettyName() {
+        return name;
+    }
+
+    @Override
     public Collection<Plan> findPlans(final Product product, final BillingPeriod period) {
         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 3e3ad3e..19eb407 100644
--- a/util/src/test/java/org/killbill/billing/mock/MockProduct.java
+++ b/util/src/test/java/org/killbill/billing/mock/MockProduct.java
@@ -64,6 +64,11 @@ public class MockProduct implements Product {
     }
 
     @Override
+    public String getPrettyName() {
+        return name;
+    }
+
+    @Override
     public Collection<Product> getAvailable() {
         return available;
     }