killbill-memoizeit

Details

diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java
index ffdbd07..00d6f38 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java
@@ -28,25 +28,56 @@ import org.killbill.billing.GuicyKillbillTestSuiteWithEmbeddedDB;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.PriceListSet;
 import org.killbill.billing.catalog.api.ProductCategory;
-import org.killbill.billing.client.KillBillClient;
 import org.killbill.billing.client.KillBillClientException;
 import org.killbill.billing.client.KillBillHttpClient;
 import org.killbill.billing.client.RequestOptions;
-import org.killbill.billing.client.model.Account;
-import org.killbill.billing.client.model.PaymentMethod;
-import org.killbill.billing.client.model.PaymentMethodPluginDetail;
-import org.killbill.billing.client.model.PluginProperty;
-import org.killbill.billing.client.model.Subscription;
+import org.killbill.billing.client.api.gen.AccountApi;
+import org.killbill.billing.client.api.gen.AdminApi;
+import org.killbill.billing.client.api.gen.BundleApi;
+import org.killbill.billing.client.api.gen.CatalogApi;
+import org.killbill.billing.client.api.gen.CreditApi;
+import org.killbill.billing.client.api.gen.CustomFieldApi;
+import org.killbill.billing.client.api.gen.ExportApi;
+import org.killbill.billing.client.api.gen.InvoiceApi;
+import org.killbill.billing.client.api.gen.InvoiceItemApi;
+import org.killbill.billing.client.api.gen.InvoicePaymentApi;
+import org.killbill.billing.client.api.gen.NodesInfoApi;
+import org.killbill.billing.client.api.gen.OverdueApi;
+import org.killbill.billing.client.api.gen.PaymentApi;
+import org.killbill.billing.client.api.gen.PaymentGatewayApi;
+import org.killbill.billing.client.api.gen.PaymentMethodApi;
+import org.killbill.billing.client.api.gen.PaymentTransactionApi;
+import org.killbill.billing.client.api.gen.PluginInfoApi;
+import org.killbill.billing.client.api.gen.SecurityApi;
+import org.killbill.billing.client.api.gen.SubscriptionApi;
+import org.killbill.billing.client.api.gen.TagApi;
+import org.killbill.billing.client.api.gen.TagDefinitionApi;
+import org.killbill.billing.client.api.gen.TenantApi;
+import org.killbill.billing.client.api.gen.UsageApi;
 import org.killbill.billing.client.model.Tags;
+import org.killbill.billing.client.model.gen.Account;
+import org.killbill.billing.client.model.gen.AuditLog;
+import org.killbill.billing.client.model.gen.PaymentMethod;
+import org.killbill.billing.client.model.gen.PaymentMethodPluginDetail;
+import org.killbill.billing.client.model.gen.PluginProperty;
+import org.killbill.billing.client.model.gen.Subscription;
 import org.killbill.billing.payment.provider.ExternalPaymentProviderPlugin;
 import org.killbill.billing.util.UUIDs;
 import org.killbill.billing.util.tag.ControlTagType;
 
+import com.google.common.collect.ImmutableList;
+
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
 public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedDB {
 
+    protected static final ImmutableList<String> NULL_PLUGIN_NAMES = null;
+    protected static final ImmutableList<String> NULL_PLUGIN_PROPERTIES = null;
+    protected static final ImmutableList<AuditLog> EMPTY_AUDIT_LOGS = ImmutableList.<AuditLog>of();
+
+
+
     protected final int DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC = 10;
 
     protected static final String PLUGIN_NAME = "noop";
@@ -72,9 +103,32 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
                                                                    .withComment(comment)
                                                                    .build();
 
-    protected KillBillClient killBillClient;
     protected KillBillHttpClient killBillHttpClient;
 
+    protected AccountApi accountApi;
+    protected AdminApi adminApi;
+    protected BundleApi bundleApi;
+    protected CatalogApi catalogApi;
+    protected CreditApi creditApi;
+    protected CustomFieldApi customFieldApi;
+    protected ExportApi exportApi;
+    protected InvoiceApi invoiceApi;
+    protected InvoiceItemApi invoiceItemApi;
+    protected InvoicePaymentApi invoicePaymentApi;
+    protected NodesInfoApi nodesInfoApi;
+    protected OverdueApi overdueApi;
+    protected PaymentApi paymentApi;
+    protected PaymentGatewayApi paymentGatewayApi;
+    protected PaymentMethodApi paymentMethodApi;
+    protected PaymentTransactionApi paymentTransactionApi;
+    protected PluginInfoApi pluginInfoApi;
+    protected SecurityApi securityApi;
+    protected SubscriptionApi subscriptionApi;
+    protected TagApi tagApi;
+    protected TagDefinitionApi tagDefinitionApi;
+    protected TenantApi tenantApi;
+    protected UsageApi usageApi;
+
     protected List<PluginProperty> getPaymentMethodCCProperties() {
         final List<PluginProperty> properties = new ArrayList<PluginProperty>();
         properties.add(new PluginProperty("type", "CreditCard", false));
@@ -100,11 +154,11 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
     }
 
     protected Account createAccountWithDefaultPaymentMethod(final String externalkey) throws Exception {
-        return  createAccountWithDefaultPaymentMethod(externalkey, null);
+        return createAccountWithDefaultPaymentMethod(externalkey, null);
     }
 
     protected Account createAccountWithDefaultPaymentMethod() throws Exception {
-        return  createAccountWithDefaultPaymentMethod(UUID.randomUUID().toString(), null);
+        return createAccountWithDefaultPaymentMethod(UUID.randomUUID().toString(), null);
     }
 
     protected Account createAccountWithDefaultPaymentMethod(final String externalkey, @Nullable final List<PluginProperty> pmProperties) throws Exception {
@@ -112,24 +166,22 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
 
         final PaymentMethodPluginDetail info = new PaymentMethodPluginDetail();
         info.setProperties(pmProperties);
-        final PaymentMethod paymentMethodJson = new PaymentMethod(null, externalkey, input.getAccountId(), true, PLUGIN_NAME, info);
-        killBillClient.createPaymentMethod(paymentMethodJson, createdBy, reason, comment);
-        return killBillClient.getAccount(input.getExternalKey());
+        final PaymentMethod paymentMethodJson = new PaymentMethod(null, externalkey, input.getAccountId(), true, PLUGIN_NAME, info, EMPTY_AUDIT_LOGS);
+        accountApi.createPaymentMethod(paymentMethodJson, input.getAccountId(), true, false, NULL_PLUGIN_NAMES, NULL_PLUGIN_PROPERTIES, requestOptions);
+        return accountApi.getAccount(input.getAccountId(), requestOptions);
     }
 
     protected Account createAccountWithExternalPaymentMethod() throws Exception {
         final Account input = createAccount();
-
         createPaymentMethod(input, true);
-
-        return killBillClient.getAccount(input.getExternalKey(), requestOptions);
+        return accountApi.getAccount(input.getAccountId(), requestOptions);
     }
 
     protected PaymentMethod createPaymentMethod(final Account input, final boolean isDefault) throws KillBillClientException {
         final PaymentMethodPluginDetail info = new PaymentMethodPluginDetail();
         final PaymentMethod paymentMethodJson = new PaymentMethod(null, UUIDs.randomUUID().toString(), input.getAccountId(),
-                                                                  isDefault, ExternalPaymentProviderPlugin.PLUGIN_NAME, info);
-        return killBillClient.createPaymentMethod(paymentMethodJson, requestOptions);
+                                                                  isDefault, ExternalPaymentProviderPlugin.PLUGIN_NAME, info, EMPTY_AUDIT_LOGS);
+        return accountApi.createPaymentMethod(paymentMethodJson, input.getAccountId(), NULL_PLUGIN_NAMES, NULL_PLUGIN_PROPERTIES, requestOptions);
     }
 
     protected Account createAccount() throws Exception {
@@ -138,7 +190,7 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
 
     protected Account createAccount(final UUID parentAccountId) throws Exception {
         final Account input = getAccount(parentAccountId);
-        return killBillClient.createAccount(input, createdBy, reason, comment);
+        return accountApi.createAccount(input, requestOptions);
     }
 
     protected Subscription createEntitlement(final UUID accountId, final String bundleExternalKey, final String productName,
@@ -150,8 +202,7 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
         input.setProductCategory(productCategory);
         input.setBillingPeriod(billingPeriod);
         input.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
-
-        return killBillClient.createSubscription(input, null, null,  waitCompletion ? DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC : -1, false, requestOptions);
+        return subscriptionApi.createEntitlement(input, null, null, true, false, null, waitCompletion, waitCompletion ? DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC : -1L, NULL_PLUGIN_PROPERTIES, requestOptions);
     }
 
     protected Account createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
@@ -172,7 +223,7 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
         final Account accountJson = createAccountWithExternalPaymentMethod();
         assertNotNull(accountJson);
 
-        final Tags accountTag = killBillClient.createAccountTag(accountJson.getAccountId(), ControlTagType.MANUAL_PAY.getId(), requestOptions);
+        final Tags accountTag = accountApi.createTags(accountJson.getAccountId(), ControlTagType.MANUAL_PAY.getId().toString(), requestOptions);
         assertNotNull(accountTag);
         assertEquals(accountTag.get(0).getTagDefinitionId(), ControlTagType.MANUAL_PAY.getId());
 
@@ -247,7 +298,7 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
 
         // Note: the accountId payload is ignored on account creation
         return new Account(accountId, name, length, externalKey, email, null, currency, parentAccountId, isPaymentDelegatedToParent, null, null, timeZone,
-                           address1, address2, postalCode, company, city, state, country, locale, phone, notes, false, false, null, null);
+                           address1, address2, postalCode, company, city, state, country, locale, phone, notes, false, false, null, null, EMPTY_AUDIT_LOGS);
     }
 
     /**
@@ -258,7 +309,6 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
         crappyWaitForLackOfProperSynchonization(5000);
     }
 
-
     protected void crappyWaitForLackOfProperSynchonization(int sleepValueMSec) throws Exception {
         Thread.sleep(sleepValueMSec);
     }
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
index b315d8d..22b0d02 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
@@ -19,8 +19,6 @@
 package org.killbill.billing.jaxrs;
 
 import java.math.BigDecimal;
-import java.util.Collection;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
@@ -29,15 +27,16 @@ import javax.annotation.Nullable;
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.client.KillBillClientException;
-import org.killbill.billing.client.model.Account;
 import org.killbill.billing.client.model.Accounts;
-import org.killbill.billing.client.model.AuditLog;
-import org.killbill.billing.client.model.CustomField;
+import org.killbill.billing.client.model.CustomFields;
 import org.killbill.billing.client.model.InvoicePayments;
-import org.killbill.billing.client.model.PaymentMethod;
-import org.killbill.billing.client.model.PaymentMethodPluginDetail;
 import org.killbill.billing.client.model.PaymentMethods;
-import org.killbill.billing.client.model.Tag;
+import org.killbill.billing.client.model.gen.Account;
+import org.killbill.billing.client.model.gen.AuditLog;
+import org.killbill.billing.client.model.gen.CustomField;
+import org.killbill.billing.client.model.gen.PaymentMethod;
+import org.killbill.billing.client.model.gen.PaymentMethodPluginDetail;
+import org.killbill.billing.client.model.gen.Tag;
 import org.killbill.billing.osgi.api.OSGIServiceRegistration;
 import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
 import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
@@ -47,7 +46,7 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 
 import static org.testng.Assert.assertEquals;
@@ -78,7 +77,7 @@ public class TestAccount extends TestJaxrsBase {
     public void testEmptyAccount() throws Exception {
         final Account emptyAccount = new Account();
 
-        final Account account = killBillClient.createAccount(emptyAccount, requestOptions);
+        final Account account = accountApi.createAccount(emptyAccount, requestOptions);
         Assert.assertNotNull(account.getExternalKey());
         Assert.assertNull(account.getName());
         Assert.assertNull(account.getEmail());
@@ -90,12 +89,12 @@ public class TestAccount extends TestJaxrsBase {
         final Account inputWithNoExternalKey = getAccount(UUID.randomUUID().toString(), null, UUID.randomUUID().toString());
         Assert.assertNull(inputWithNoExternalKey.getExternalKey());
 
-        final Account account = killBillClient.createAccount(inputWithNoExternalKey, requestOptions);
+        final Account account = accountApi.createAccount(inputWithNoExternalKey, requestOptions);
         Assert.assertNotNull(account.getExternalKey());
 
         final Account inputWithSameExternalKey = getAccount(UUID.randomUUID().toString(), account.getExternalKey(), UUID.randomUUID().toString());
         try {
-            killBillClient.createAccount(inputWithSameExternalKey, requestOptions);
+            accountApi.createAccount(inputWithSameExternalKey, requestOptions);
             Assert.fail();
         } catch (final KillBillClientException e) {
             Assert.assertEquals(e.getBillingException().getCode(), (Integer) ErrorCode.ACCOUNT_ALREADY_EXISTS.getCode());
@@ -107,7 +106,7 @@ public class TestAccount extends TestJaxrsBase {
         final Account input = createAccount();
 
         // Retrieves by external key
-        final Account retrievedAccount = killBillClient.getAccount(input.getExternalKey(), requestOptions);
+        final Account retrievedAccount = accountApi.getAccountByKey(input.getExternalKey(), requestOptions);
         Assert.assertTrue(retrievedAccount.equals(input));
 
         // Try search endpoint
@@ -118,9 +117,10 @@ public class TestAccount extends TestJaxrsBase {
                                              "zozo", 4, input.getExternalKey(), "rr@google.com", 18,
                                              "USD", null, false, null, null, "UTC",
                                              "bl1", "bh2", "", "", "ca", "San Francisco", "usa", "en", "415-255-2991",
-                                             "notes", false, false, null, null);
+                                             "notes", false, false, null, null, EMPTY_AUDIT_LOGS);
 
-        final Account updatedAccount = killBillClient.updateAccount(newInput, requestOptions);
+        accountApi.updateAccount(newInput, input.getAccountId(), requestOptions);
+        final Account updatedAccount = accountApi.getAccount(input.getAccountId(), requestOptions);
         // referenceTime is set automatically by system, no way to guess it
         newInput.setReferenceTime(updatedAccount.getReferenceTime());
         Assert.assertTrue(updatedAccount.equals(newInput));
@@ -144,7 +144,6 @@ public class TestAccount extends TestJaxrsBase {
         Assert.assertEquals(input.getCountry(), "France");
         Assert.assertEquals(input.getLocale(), "fr");
 
-
         // Set notes to something else
         final Account newInput = new Account(input.getAccountId(),
                                              null,
@@ -171,11 +170,12 @@ public class TestAccount extends TestJaxrsBase {
                                              null,
                                              null,
                                              null,
-                                             null);
-
+                                             null,
+                                             EMPTY_AUDIT_LOGS);
 
         // Update notes, all other fields remaining the same (value set to null but treatNullAsReset defaults to false)
-        Account updatedAccount = killBillClient.updateAccount(newInput, requestOptions);
+        accountApi.updateAccount(newInput, newInput.getAccountId(), requestOptions);
+        Account updatedAccount = accountApi.getAccount(input.getAccountId(), requestOptions);
 
         Assert.assertNotNull(updatedAccount.getExternalKey());
         Assert.assertNotNull(updatedAccount.getNotes());
@@ -190,7 +190,8 @@ public class TestAccount extends TestJaxrsBase {
 
         // Reset notes, all other fields remaining the same
         updatedAccount.setNotes(null);
-        updatedAccount = killBillClient.updateAccount(updatedAccount, true, requestOptions);
+        accountApi.updateAccount(updatedAccount, updatedAccount.getAccountId(), true, requestOptions);
+        updatedAccount = accountApi.getAccount(input.getAccountId(), requestOptions);
 
         Assert.assertNotNull(updatedAccount.getExternalKey());
         Assert.assertNull(updatedAccount.getNotes());
@@ -203,12 +204,11 @@ public class TestAccount extends TestJaxrsBase {
         Assert.assertEquals(updatedAccount.getLocale(), "fr");
     }
 
-
     @Test(groups = "slow", description = "Can retrieve the account balance")
     public void testAccountWithBalance() throws Exception {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final Account accountWithBalance = killBillClient.getAccount(accountJson.getAccountId(), true, false, requestOptions);
+        final Account accountWithBalance = accountApi.getAccount(accountJson.getAccountId(), true, false, AuditLevel.NONE, requestOptions);
         final BigDecimal accountBalance = accountWithBalance.getAccountBalance();
         Assert.assertTrue(accountBalance.compareTo(BigDecimal.ZERO) > 0);
     }
@@ -216,14 +216,14 @@ public class TestAccount extends TestJaxrsBase {
     @Test(groups = "slow", description = "Cannot update a non-existent account")
     public void testUpdateNonExistentAccount() throws Exception {
         final Account input = getAccount();
-
-        Assert.assertNull(killBillClient.updateAccount(input, requestOptions));
+        accountApi.updateAccount(input, input.getAccountId(), requestOptions);
+        // TODO
+        //Assert.assertNull();
     }
 
     @Test(groups = "slow", description = "Cannot retrieve non-existent account")
     public void testAccountNonExistent() throws Exception {
-        Assert.assertNull(killBillClient.getAccount(UUID.randomUUID(), requestOptions));
-        Assert.assertNull(killBillClient.getAccount(UUID.randomUUID().toString(), requestOptions));
+        Assert.assertNull(accountApi.getAccount(UUID.randomUUID(), requestOptions));
     }
 
     @Test(groups = "slow", description = "Can CRUD payment methods")
@@ -233,50 +233,50 @@ public class TestAccount extends TestJaxrsBase {
 
         final PaymentMethodPluginDetail info = new PaymentMethodPluginDetail();
         info.setProperties(getPaymentMethodCCProperties());
-        PaymentMethod paymentMethodJson = new PaymentMethod(null, UUID.randomUUID().toString(), accountJson.getAccountId(), true, PLUGIN_NAME, info);
-        final PaymentMethod paymentMethodCC = killBillClient.createPaymentMethod(paymentMethodJson, requestOptions);
-        assertTrue(paymentMethodCC.getIsDefault());
+        PaymentMethod paymentMethodJson = new PaymentMethod(null, UUID.randomUUID().toString(), accountJson.getAccountId(), true, PLUGIN_NAME, info, EMPTY_AUDIT_LOGS);
+        final PaymentMethod paymentMethodCC = accountApi.createPaymentMethod(paymentMethodJson, accountJson.getAccountId(), true, false, NULL_PLUGIN_NAMES, NULL_PLUGIN_PROPERTIES, requestOptions);
+        assertTrue(paymentMethodCC.isIsDefault());
 
         //
         // Add another payment method
         //
         final PaymentMethodPluginDetail info2 = new PaymentMethodPluginDetail();
         info2.setProperties(getPaymentMethodPaypalProperties());
-        paymentMethodJson = new PaymentMethod(null, UUID.randomUUID().toString(), accountJson.getAccountId(), false, PLUGIN_NAME, info2);
-        final PaymentMethod paymentMethodPP = killBillClient.createPaymentMethod(paymentMethodJson, requestOptions);
-        assertFalse(paymentMethodPP.getIsDefault());
+        paymentMethodJson = new PaymentMethod(null, UUID.randomUUID().toString(), accountJson.getAccountId(), false, PLUGIN_NAME, info2, EMPTY_AUDIT_LOGS);
+        final PaymentMethod paymentMethodPP = accountApi.createPaymentMethod(paymentMethodJson, accountJson.getAccountId(), NULL_PLUGIN_NAMES, NULL_PLUGIN_PROPERTIES, requestOptions);
+        assertFalse(paymentMethodPP.isIsDefault());
 
         //
         // FETCH ALL PAYMENT METHODS
         //
-        List<PaymentMethod> paymentMethods = killBillClient.getPaymentMethodsForAccount(accountJson.getAccountId(), requestOptions);
+        List<PaymentMethod> paymentMethods = accountApi.getPaymentMethods(accountJson.getAccountId(), NULL_PLUGIN_PROPERTIES, requestOptions);
         assertEquals(paymentMethods.size(), 2);
 
         //
         // CHANGE DEFAULT
         //
-        assertTrue(killBillClient.getPaymentMethod(paymentMethodCC.getPaymentMethodId(), requestOptions).getIsDefault());
-        assertFalse(killBillClient.getPaymentMethod(paymentMethodPP.getPaymentMethodId(), requestOptions).getIsDefault());
-        killBillClient.updateDefaultPaymentMethod(accountJson.getAccountId(), paymentMethodPP.getPaymentMethodId(), requestOptions);
-        assertTrue(killBillClient.getPaymentMethod(paymentMethodPP.getPaymentMethodId(), requestOptions).getIsDefault());
-        assertFalse(killBillClient.getPaymentMethod(paymentMethodCC.getPaymentMethodId(), requestOptions).getIsDefault());
+        assertTrue(paymentMethodApi.getPaymentMethod(paymentMethodCC.getPaymentMethodId(), NULL_PLUGIN_PROPERTIES, requestOptions).isIsDefault());
+        assertFalse(paymentMethodApi.getPaymentMethod(paymentMethodPP.getPaymentMethodId(), NULL_PLUGIN_PROPERTIES, requestOptions).isIsDefault());
+        accountApi.setDefaultPaymentMethod(accountJson.getAccountId(), paymentMethodPP.getPaymentMethodId(), NULL_PLUGIN_PROPERTIES, requestOptions);
+        assertTrue(paymentMethodApi.getPaymentMethod(paymentMethodPP.getPaymentMethodId(), NULL_PLUGIN_PROPERTIES, requestOptions).isIsDefault());
+        assertFalse(paymentMethodApi.getPaymentMethod(paymentMethodCC.getPaymentMethodId(), NULL_PLUGIN_PROPERTIES, requestOptions).isIsDefault());
 
         //
         // DELETE NON DEFAULT PM
         //
-        killBillClient.deletePaymentMethod(paymentMethodCC.getPaymentMethodId(), false, false, requestOptions);
+        paymentMethodApi.deletePaymentMethod(paymentMethodCC.getPaymentMethodId(), false, false, NULL_PLUGIN_PROPERTIES, requestOptions);
 
         //
         // FETCH ALL PAYMENT METHODS
         //
-        paymentMethods = killBillClient.getPaymentMethodsForAccount(accountJson.getAccountId(), requestOptions);
+        paymentMethods = accountApi.getPaymentMethods(accountJson.getAccountId(), NULL_PLUGIN_PROPERTIES, requestOptions);
         assertEquals(paymentMethods.size(), 1);
 
         //
         // DELETE DEFAULT PAYMENT METHOD (without special flag first)
         //
         try {
-            killBillClient.deletePaymentMethod(paymentMethodPP.getPaymentMethodId(), false, false, requestOptions);
+            paymentMethodApi.deletePaymentMethod(paymentMethodPP.getPaymentMethodId(), false, false, NULL_PLUGIN_PROPERTIES, requestOptions);
             fail();
         } catch (final KillBillClientException e) {
         }
@@ -284,17 +284,17 @@ public class TestAccount extends TestJaxrsBase {
         //
         // RETRY TO DELETE DEFAULT PAYMENT METHOD (with special flag this time)
         //
-        killBillClient.deletePaymentMethod(paymentMethodPP.getPaymentMethodId(), true, false, requestOptions);
+        paymentMethodApi.deletePaymentMethod(paymentMethodPP.getPaymentMethodId(), true, false, NULL_PLUGIN_PROPERTIES, requestOptions);
 
         // CHECK ACCOUNT IS NOW AUTO_PAY_OFF
-        final List<Tag> tagsJson = killBillClient.getAccountTags(accountJson.getAccountId(), requestOptions);
+        final List<Tag> tagsJson = accountApi.getTags(accountJson.getAccountId(), requestOptions);
         Assert.assertEquals(tagsJson.size(), 1);
         final Tag tagJson = tagsJson.get(0);
         Assert.assertEquals(tagJson.getTagDefinitionName(), "AUTO_PAY_OFF");
         Assert.assertEquals(tagJson.getTagDefinitionId(), new UUID(0, 1));
 
         // FETCH ACCOUNT AGAIN AND CHECK THERE IS NO DEFAULT PAYMENT METHOD SET
-        final Account updatedAccount = killBillClient.getAccount(accountJson.getAccountId(), requestOptions);
+        final Account updatedAccount = accountApi.getAccount(accountJson.getAccountId(), requestOptions);
         Assert.assertEquals(updatedAccount.getAccountId(), accountJson.getAccountId());
         Assert.assertNull(updatedAccount.getPaymentMethodId());
 
@@ -302,7 +302,7 @@ public class TestAccount extends TestJaxrsBase {
         // FINALLY TRY TO REMOVE AUTO_PAY_OFF WITH NO DEFAULT PAYMENT METHOD ON ACCOUNT
         //
         try {
-            killBillClient.deleteAccountTag(accountJson.getAccountId(), new UUID(0, 1), requestOptions);
+            accountApi.deleteTags(accountJson.getAccountId(), new UUID(0, 1).toString(), requestOptions);
         } catch (final KillBillClientException e) {
         }
     }
@@ -312,7 +312,7 @@ public class TestAccount extends TestJaxrsBase {
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Verify payments
-        final InvoicePayments objFromJson = killBillClient.getInvoicePaymentsForAccount(accountJson.getAccountId(), requestOptions);
+        final InvoicePayments objFromJson = accountApi.getInvoicePayments(accountJson.getAccountId(), NULL_PLUGIN_PROPERTIES, requestOptions);
         Assert.assertEquals(objFromJson.size(), 1);
     }
 
@@ -323,19 +323,19 @@ public class TestAccount extends TestJaxrsBase {
         final UUID autoPayOffId = new UUID(0, 1);
 
         // Add a tag
-        killBillClient.createAccountTag(input.getAccountId(), autoPayOffId, requestOptions);
+        accountApi.createTags(input.getAccountId(), autoPayOffId.toString(), requestOptions);
 
         // Retrieves all tags
-        final List<Tag> tags1 = killBillClient.getAccountTags(input.getAccountId(), AuditLevel.FULL, requestOptions);
+        final List<Tag> tags1 = accountApi.getTags(input.getAccountId(), AuditLevel.FULL, false, requestOptions);
         Assert.assertEquals(tags1.size(), 1);
         Assert.assertEquals(tags1.get(0).getTagDefinitionId(), autoPayOffId);
 
         // Verify adding the same tag a second time doesn't do anything
-        killBillClient.createAccountTag(input.getAccountId(), autoPayOffId, requestOptions);
+        accountApi.createTags(input.getAccountId(), autoPayOffId.toString(), requestOptions);
 
         // Retrieves all tags again
-        killBillClient.createAccountTag(input.getAccountId(), autoPayOffId, requestOptions);
-        final List<Tag> tags2 = killBillClient.getAccountTags(input.getAccountId(), AuditLevel.FULL, requestOptions);
+        accountApi.createTags(input.getAccountId(), autoPayOffId.toString(), requestOptions);
+        final List<Tag> tags2 = accountApi.getTags(input.getAccountId(), AuditLevel.FULL, true, requestOptions);
         Assert.assertEquals(tags2, tags1);
 
         // Verify audit logs
@@ -354,20 +354,20 @@ public class TestAccount extends TestJaxrsBase {
         final Account accountJson = createAccount();
         assertNotNull(accountJson);
 
-        final Collection<CustomField> customFields = new LinkedList<CustomField>();
-        customFields.add(new CustomField(null, accountJson.getAccountId(), ObjectType.ACCOUNT, "1", "value1", null));
-        customFields.add(new CustomField(null, accountJson.getAccountId(), ObjectType.ACCOUNT, "2", "value2", null));
-        customFields.add(new CustomField(null, accountJson.getAccountId(), ObjectType.ACCOUNT, "3", "value3", null));
+        final CustomFields customFields = new CustomFields();
+        customFields.add(new CustomField(null, accountJson.getAccountId(), ObjectType.ACCOUNT, "1", "value1", EMPTY_AUDIT_LOGS));
+        customFields.add(new CustomField(null, accountJson.getAccountId(), ObjectType.ACCOUNT, "2", "value2", EMPTY_AUDIT_LOGS));
+        customFields.add(new CustomField(null, accountJson.getAccountId(), ObjectType.ACCOUNT, "3", "value3", EMPTY_AUDIT_LOGS));
 
-        killBillClient.createAccountCustomFields(accountJson.getAccountId(), customFields, requestOptions);
+        accountApi.createCustomFields(accountJson.getAccountId(), customFields, requestOptions);
 
-        final List<CustomField> accountCustomFields = killBillClient.getAccountCustomFields(accountJson.getAccountId(), requestOptions);
+        final List<CustomField> accountCustomFields = accountApi.getCustomFields(accountJson.getAccountId(), requestOptions);
         assertEquals(accountCustomFields.size(), 3);
 
         // Delete all custom fields for account
-        killBillClient.deleteAccountCustomFields(accountJson.getAccountId(), requestOptions);
+        accountApi.deleteCustomFields(accountJson.getAccountId(), null, requestOptions);
 
-        final List<CustomField> remainingCustomFields = killBillClient.getAccountCustomFields(accountJson.getAccountId(), requestOptions);
+        final List<CustomField> remainingCustomFields = accountApi.getCustomFields(accountJson.getAccountId(), requestOptions);
         assertEquals(remainingCustomFields.size(), 0);
     }
 
@@ -375,28 +375,28 @@ public class TestAccount extends TestJaxrsBase {
     public void testRefreshPaymentMethods() throws Exception {
         final Account account = createAccountWithDefaultPaymentMethod("someExternalKey");
 
-        final PaymentMethods paymentMethodsBeforeRefreshing = killBillClient.getPaymentMethodsForAccount(account.getAccountId(), requestOptions);
+        final PaymentMethods paymentMethodsBeforeRefreshing = accountApi.getPaymentMethods(account.getAccountId(), NULL_PLUGIN_PROPERTIES, requestOptions);
         assertEquals(paymentMethodsBeforeRefreshing.size(), 1);
         assertEquals(paymentMethodsBeforeRefreshing.get(0).getExternalKey(), "someExternalKey");
 
         // WITH NAME OF AN EXISTING PLUGIN
-        killBillClient.refreshPaymentMethods(account.getAccountId(), PLUGIN_NAME, ImmutableMap.<String, String>of(), requestOptions);
+        accountApi.refreshPaymentMethods(account.getAccountId(), PLUGIN_NAME, NULL_PLUGIN_PROPERTIES, requestOptions);
 
-        final PaymentMethods paymentMethodsAfterExistingPluginCall = killBillClient.getPaymentMethodsForAccount(account.getAccountId(), requestOptions);
+        final PaymentMethods paymentMethodsAfterExistingPluginCall = accountApi.getPaymentMethods(account.getAccountId(), NULL_PLUGIN_PROPERTIES, requestOptions);
 
         assertEquals(paymentMethodsAfterExistingPluginCall.size(), 1);
         assertEquals(paymentMethodsAfterExistingPluginCall.get(0).getExternalKey(), "someExternalKey");
 
         // WITHOUT PLUGIN NAME
-        killBillClient.refreshPaymentMethods(account.getAccountId(), ImmutableMap.<String, String>of(), requestOptions);
+        accountApi.refreshPaymentMethods(account.getAccountId(), PLUGIN_NAME, NULL_PLUGIN_PROPERTIES, requestOptions);
 
-        final PaymentMethods paymentMethodsAfterNoPluginNameCall = killBillClient.getPaymentMethodsForAccount(account.getAccountId(), requestOptions);
+        final PaymentMethods paymentMethodsAfterNoPluginNameCall = accountApi.getPaymentMethods(account.getAccountId(), NULL_PLUGIN_PROPERTIES, requestOptions);
         assertEquals(paymentMethodsAfterNoPluginNameCall.size(), 1);
         assertEquals(paymentMethodsAfterNoPluginNameCall.get(0).getExternalKey(), "someExternalKey");
 
         // WITH WRONG PLUGIN NAME
         try {
-            killBillClient.refreshPaymentMethods(account.getAccountId(), "GreatestPluginEver", ImmutableMap.<String, String>of(), requestOptions);
+            accountApi.refreshPaymentMethods(account.getAccountId(), "GreatestPluginEver", NULL_PLUGIN_PROPERTIES, requestOptions);
             Assert.fail();
         } catch (final KillBillClientException e) {
             Assert.assertEquals(e.getBillingException().getCode(), (Integer) ErrorCode.PAYMENT_NO_SUCH_PAYMENT_PLUGIN.getCode());
@@ -409,10 +409,10 @@ public class TestAccount extends TestJaxrsBase {
             createAccount();
         }
 
-        final Accounts allAccounts = killBillClient.getAccounts(requestOptions);
+        final Accounts allAccounts = accountApi.getAccounts(requestOptions);
         Assert.assertEquals(allAccounts.size(), 5);
 
-        Accounts page = killBillClient.getAccounts(0L, 1L, requestOptions);
+        Accounts page = accountApi.getAccounts(0L, 1L, false, false, AuditLevel.NONE, requestOptions);
         for (int i = 0; i < 5; i++) {
             Assert.assertNotNull(page);
             Assert.assertEquals(page.size(), 1);
@@ -439,14 +439,14 @@ public class TestAccount extends TestJaxrsBase {
 
         // Search by external key.
         // Note: we will always find a match since we don't update it
-        final List<Account> accountsByExternalKey = killBillClient.searchAccounts(input.getExternalKey(), requestOptions);
+        final List<Account> accountsByExternalKey = accountApi.searchAccounts(input.getExternalKey(), requestOptions);
         Assert.assertEquals(accountsByExternalKey.size(), 1);
         Assert.assertEquals(accountsByExternalKey.get(0).getAccountId(), input.getAccountId());
         Assert.assertEquals(accountsByExternalKey.get(0).getExternalKey(), input.getExternalKey());
     }
 
     private void doSearchAccount(final String key, @Nullable final Account output) throws Exception {
-        final List<Account> accountsByKey = killBillClient.searchAccounts(key, requestOptions);
+        final List<Account> accountsByKey = accountApi.searchAccounts(key, requestOptions);
         if (output == null) {
             Assert.assertEquals(accountsByKey.size(), 0);
         } else {
@@ -463,13 +463,13 @@ public class TestAccount extends TestJaxrsBase {
         final Account childInput = getAccount();
         childInput.setParentAccountId(parentAccount.getAccountId());
         childInput.setIsPaymentDelegatedToParent(true);
-        final Account childAccount = killBillClient.createAccount(childInput, requestOptions);
+        final Account childAccount = accountApi.createAccount(childInput, requestOptions);
 
         // Retrieves child account by external key
-        final Account retrievedAccount = killBillClient.getAccount(childAccount.getExternalKey(), requestOptions);
+        final Account retrievedAccount = accountApi.getAccountByKey(childAccount.getExternalKey(), requestOptions);
         Assert.assertTrue(retrievedAccount.equals(childAccount));
         Assert.assertEquals(retrievedAccount.getParentAccountId(), parentAccount.getAccountId());
-        Assert.assertTrue(retrievedAccount.getIsPaymentDelegatedToParent());
+        Assert.assertTrue(retrievedAccount.isIsPaymentDelegatedToParent());
     }
 
     @Test(groups = "slow", description = "retrieve children accounts by parent account id")
@@ -480,17 +480,17 @@ public class TestAccount extends TestJaxrsBase {
         final Account childInput = getAccount();
         childInput.setParentAccountId(parentAccount.getAccountId());
         childInput.setIsPaymentDelegatedToParent(true);
-        Account childAccount = killBillClient.createAccount(childInput, requestOptions);
-        childAccount = killBillClient.getAccount(childAccount.getAccountId(), true, true, requestOptions);
+        Account childAccount = accountApi.createAccount(childInput, requestOptions);
+        childAccount = accountApi.getAccount(childAccount.getAccountId(), true, true, AuditLevel.NONE, requestOptions);
 
         final Account childInput2 = getAccount();
         childInput2.setParentAccountId(parentAccount.getAccountId());
         childInput2.setIsPaymentDelegatedToParent(true);
-        Account childAccount2 = killBillClient.createAccount(childInput2, requestOptions);
-        childAccount2 = killBillClient.getAccount(childAccount2.getAccountId(), true, true, requestOptions);
+        Account childAccount2 = accountApi.createAccount(childInput2, requestOptions);
+        childAccount2 = accountApi.getAccount(childAccount2.getAccountId(), true, true, AuditLevel.NONE, requestOptions);
 
         // Retrieves children accounts by parent account id
-        final Accounts childrenAccounts = killBillClient.getChildrenAccounts(parentAccount.getAccountId(), true, true, requestOptions);
+        final Accounts childrenAccounts = accountApi.getChildrenAccounts(parentAccount.getAccountId(), true, true, AuditLevel.NONE, requestOptions);
         Assert.assertEquals(childrenAccounts.size(), 2);
 
         Assert.assertTrue(childrenAccounts.get(0).equals(childAccount));
@@ -501,16 +501,7 @@ public class TestAccount extends TestJaxrsBase {
     public void testEmptyGetChildrenAccounts() throws Exception {
 
         // Retrieves children accounts by parent account id
-        final Accounts childrenAccounts = killBillClient.getChildrenAccounts(UUID.randomUUID(), false, false, requestOptions);
-        Assert.assertEquals(childrenAccounts.size(), 0);
-
-    }
-
-    @Test(groups = "slow", description = "retrieve an empty children accounts list by a null id")
-    public void testGetChildrenAccountsByNullId() throws Exception {
-
-        // Retrieves children accounts by parent account id
-        final Accounts childrenAccounts = killBillClient.getChildrenAccounts(null, true, true, requestOptions);
+        final Accounts childrenAccounts = accountApi.getChildrenAccounts(UUID.randomUUID(), false, false, AuditLevel.NONE, requestOptions);
         Assert.assertEquals(childrenAccounts.size(), 0);
 
     }
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 4b93ff5..e143279 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
@@ -19,30 +19,28 @@
 package org.killbill.billing.jaxrs;
 
 import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
-import org.killbill.billing.api.FlakyRetryAnalyzer;
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.ProductCategory;
+import org.killbill.billing.client.JaxrsResource;
 import org.killbill.billing.client.KillBillClientException;
-import org.killbill.billing.client.RequestOptions;
-import org.killbill.billing.client.model.Account;
-import org.killbill.billing.client.model.AuditLog;
-import org.killbill.billing.client.model.Credit;
-import org.killbill.billing.client.model.Invoice;
-import org.killbill.billing.client.model.InvoiceDryRun;
-import org.killbill.billing.client.model.InvoiceItem;
-import org.killbill.billing.client.model.InvoicePayment;
+import org.killbill.billing.client.model.InvoiceItems;
 import org.killbill.billing.client.model.InvoicePayments;
 import org.killbill.billing.client.model.Invoices;
-import org.killbill.billing.client.model.PaymentMethod;
 import org.killbill.billing.client.model.Payments;
+import org.killbill.billing.client.model.gen.Account;
+import org.killbill.billing.client.model.gen.AuditLog;
+import org.killbill.billing.client.model.gen.Credit;
+import org.killbill.billing.client.model.gen.Invoice;
+import org.killbill.billing.client.model.gen.InvoiceDryRun;
+import org.killbill.billing.client.model.gen.InvoiceItem;
+import org.killbill.billing.client.model.gen.InvoicePayment;
+import org.killbill.billing.client.model.gen.PaymentMethod;
 import org.killbill.billing.entitlement.api.SubscriptionEventType;
 import org.killbill.billing.invoice.api.DryRunType;
 import org.killbill.billing.invoice.api.InvoiceItemType;
@@ -53,8 +51,9 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -70,7 +69,7 @@ public class TestInvoice extends TestJaxrsBase {
 
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false, false, false, AuditLevel.FULL, requestOptions);
+        final Invoices invoices = accountApi.getInvoices(accountJson.getAccountId(), true, false, false, false, AuditLevel.FULL, requestOptions);
         assertEquals(invoices.size(), 2);
         for (final Invoice invoiceJson : invoices) {
             Assert.assertEquals(invoiceJson.getAuditLogs().size(), 1);
@@ -86,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, 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());
+        assertTrue(invoiceApi.getInvoice(invoiceJson.getInvoiceId(), Boolean.FALSE, Boolean.FALSE, AuditLevel.NONE, requestOptions).getItems().isEmpty());
+        assertTrue(invoiceApi.getInvoiceByNumber(Integer.valueOf(invoiceJson.getInvoiceNumber()), Boolean.FALSE, Boolean.FALSE, AuditLevel.NONE, requestOptions).getItems().isEmpty());
+        assertEquals(invoiceApi.getInvoice(invoiceJson.getInvoiceId(), Boolean.TRUE, Boolean.FALSE, AuditLevel.NONE, requestOptions).getItems().size(), invoiceJson.getItems().size());
+        assertEquals(invoiceApi.getInvoiceByNumber(Integer.valueOf(invoiceJson.getInvoiceNumber()), Boolean.TRUE, Boolean.FALSE, AuditLevel.NONE, requestOptions).getItems().size(), invoiceJson.getItems().size());
 
         // Check we can retrieve an individual invoice
-        final Invoice firstInvoice = killBillClient.getInvoice(invoiceJson.getInvoiceId(), requestOptions);
+        final Invoice firstInvoice = invoiceApi.getInvoice(invoiceJson.getInvoiceId(), true, false, AuditLevel.FULL, requestOptions);
         assertEquals(firstInvoice, invoiceJson);
 
         // Check we can retrieve the invoice by number
-        final Invoice firstInvoiceByNumberJson = killBillClient.getInvoice(invoiceJson.getInvoiceNumber(), requestOptions);
+        final Invoice firstInvoiceByNumberJson = invoiceApi.getInvoiceByNumber(Integer.valueOf(invoiceJson.getInvoiceNumber()), true, false, AuditLevel.FULL, requestOptions);
         assertEquals(firstInvoiceByNumberJson, invoiceJson);
 
         // Check we can retrieve the HTML version
-        final String htmlInvoice = killBillClient.getInvoiceAsHtml(invoiceJson.getInvoiceId(), requestOptions);
+        final String htmlInvoice = invoiceApi.getInvoiceAsHTML(invoiceJson.getInvoiceId(), requestOptions);
         assertEquals(htmlInvoice, "<html>\n" +
                                   "    <head>\n" +
                                   "        <style type=\"text/css\">\n" +
@@ -199,10 +198,9 @@ public class TestInvoice extends TestJaxrsBase {
                                   "\n");
 
         // Then create a dryRun for next upcoming invoice
-        final InvoiceDryRun dryRunArg = new InvoiceDryRun(DryRunType.UPCOMING_INVOICE, null,
-                                                          null, null, null, null, null, null, null, null, null, null);
+        final InvoiceDryRun dryRunArg = new InvoiceDryRun().setDryRunType(DryRunType.UPCOMING_INVOICE);
 
-        final Invoice dryRunInvoice = killBillClient.createDryRunInvoice(accountJson.getAccountId(), null, dryRunArg, requestOptions);
+        final Invoice dryRunInvoice = invoiceApi.generateDryRunInvoice(dryRunArg, accountJson.getAccountId(), null, requestOptions.extend().withFollowLocation(false).build());
         assertEquals(dryRunInvoice.getBalance(), new BigDecimal("249.95"));
         assertEquals(dryRunInvoice.getTargetDate(), new LocalDate(2012, 6, 25));
         assertEquals(dryRunInvoice.getItems().size(), 1);
@@ -212,10 +210,10 @@ public class TestInvoice extends TestJaxrsBase {
 
         final LocalDate futureDate = dryRunInvoice.getTargetDate();
         // The one more time with no DryRun
-        killBillClient.createInvoice(accountJson.getAccountId(), futureDate, requestOptions);
+        invoiceApi.createFutureInvoice(accountJson.getAccountId(), futureDate.toString(), requestOptions);
 
         // Check again # invoices, should be 3 this time
-        final List<Invoice> newInvoiceList = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
+        final List<Invoice> newInvoiceList = accountApi.getInvoices(accountJson.getAccountId(), requestOptions);
         assertEquals(newInvoiceList.size(), 3);
     }
 
@@ -226,9 +224,10 @@ public class TestInvoice extends TestJaxrsBase {
 
         // "Assault-Rifle", BillingPeriod.ANNUAL, "rescue", BillingActionPolicy.IMMEDIATE,
         final Account accountJson = createAccountWithDefaultPaymentMethod();
-        final InvoiceDryRun dryRunArg = new InvoiceDryRun(DryRunType.TARGET_DATE, SubscriptionEventType.START_BILLING,
+        final InvoiceDryRun dryRunArg = new InvoiceDryRun(DryRunType.SUBSCRIPTION_ACTION, 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, requestOptions);
+
+        final Invoice dryRunInvoice = invoiceApi.generateDryRunInvoice(dryRunArg, accountJson.getAccountId(), new LocalDate(initialDate, DateTimeZone.forID(accountJson.getTimeZone())).toString(), requestOptions.extend().withFollowLocation(false).build());
         assertEquals(dryRunInvoice.getItems().size(), 1);
 
     }
@@ -239,7 +238,7 @@ public class TestInvoice extends TestJaxrsBase {
 
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
+        final List<Invoice> invoices = accountApi.getInvoices(accountJson.getAccountId(), requestOptions);
         assertEquals(invoices.size(), 2);
 
         final Invoice invoiceWithPositiveAmount = Iterables.tryFind(invoices, new Predicate<Invoice>() {
@@ -250,7 +249,7 @@ public class TestInvoice extends TestJaxrsBase {
         }).orNull();
         Assert.assertNotNull(invoiceWithPositiveAmount);
 
-        final InvoicePayments objFromJson = killBillClient.getInvoicePayment(invoiceWithPositiveAmount.getInvoiceId(), requestOptions);
+        final InvoicePayments objFromJson = invoiceApi.getPayments(invoiceWithPositiveAmount.getInvoiceId(), requestOptions);
         assertEquals(objFromJson.size(), 1);
         assertEquals(invoiceWithPositiveAmount.getAmount().compareTo(objFromJson.get(0).getPurchasedAmount()), 0);
     }
@@ -263,20 +262,20 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Check there was no payment made
-        assertEquals(killBillClient.getPaymentsForAccount(accountJson.getAccountId(), requestOptions).size(), 0);
+        assertEquals(accountApi.getPayments(accountJson.getAccountId(), null, requestOptions).size(), 0);
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
+        final List<Invoice> invoices = accountApi.getInvoices(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, requestOptions);
-        for (final Invoice invoice : killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions)) {
+        accountApi.payAllInvoices(accountJson.getAccountId(), true, null, null, requestOptions);
+        for (final Invoice invoice : accountApi.getInvoices(accountJson.getAccountId(), requestOptions)) {
             assertEquals(invoice.getBalance().compareTo(BigDecimal.ZERO), 0);
         }
-        assertEquals(killBillClient.getPaymentsForAccount(accountJson.getAccountId(), requestOptions).size(), 1);
+        assertEquals(accountApi.getPayments(accountJson.getAccountId(), null, requestOptions).size(), 1);
     }
 
     @Test(groups = "slow", description = "Can create an insta-payment")
@@ -287,7 +286,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
+        final List<Invoice> invoices = accountApi.getInvoices(accountJson.getAccountId(), requestOptions);
         assertEquals(invoices.size(), 2);
 
         for (final Invoice cur : invoices) {
@@ -300,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, requestOptions);
+            final InvoicePayment objFromJson = invoiceApi.createInstantPayment(invoicePayment, cur.getInvoiceId(), true, null, requestOptions);
             assertEquals(cur.getBalance().compareTo(objFromJson.getPurchasedAmount()), 0);
         }
     }
@@ -310,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(), requestOptions);
+        final List<InvoicePayment> noPaymentsFromJson = accountApi.getInvoicePayments(accountJson.getAccountId(), null, requestOptions);
         assertEquals(noPaymentsFromJson.size(), 0);
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
+        final List<Invoice> invoices = accountApi.getInvoices(accountJson.getAccountId(), requestOptions);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
         final UUID invoiceId = invoices.get(1).getInvoiceId();
@@ -324,17 +323,17 @@ public class TestInvoice extends TestJaxrsBase {
         invoicePayment.setPurchasedAmount(BigDecimal.TEN);
         invoicePayment.setAccountId(accountJson.getAccountId());
         invoicePayment.setTargetInvoiceId(invoiceId);
-        killBillClient.createInvoicePayment(invoicePayment, true, requestOptions);
+        invoiceApi.createInstantPayment(invoicePayment, invoiceId, true, null, requestOptions);
 
         // Verify we indeed got the invoicePayment
-        final List<InvoicePayment> paymentsFromJson = killBillClient.getInvoicePaymentsForAccount(accountJson.getAccountId(), requestOptions);
+        final List<InvoicePayment> paymentsFromJson = accountApi.getInvoicePayments(accountJson.getAccountId(), null, 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, requestOptions);
+        final PaymentMethod paymentMethodJson = paymentMethodApi.getPaymentMethod(paymentMethodId, null, requestOptions);
         assertEquals(paymentMethodJson.getPaymentMethodId(), paymentMethodId);
         assertEquals(paymentMethodJson.getAccountId(), accountJson.getAccountId());
         assertEquals(paymentMethodJson.getPluginName(), ExternalPaymentProviderPlugin.PLUGIN_NAME);
@@ -346,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, requestOptions);
+        final List<Invoice> invoices = accountApi.getInvoices(accountJson.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
         final Invoice invoice = invoices.get(1);
@@ -361,10 +360,10 @@ public class TestInvoice extends TestJaxrsBase {
         adjustmentInvoiceItem.setAccountId(accountJson.getAccountId());
         adjustmentInvoiceItem.setInvoiceId(invoice.getInvoiceId());
         adjustmentInvoiceItem.setInvoiceItemId(invoiceItem.getInvoiceItemId());
-        killBillClient.adjustInvoiceItem(invoiceItem, requestOptions);
+        invoiceApi.adjustInvoiceItem(invoiceItem, invoice.getInvoiceId(), null, requestOptions);
 
         // Verify the new invoice balance is zero
-        final Invoice adjustedInvoice = killBillClient.getInvoice(invoice.getInvoiceId(), true, false, AuditLevel.FULL, requestOptions);
+        final Invoice adjustedInvoice = invoiceApi.getInvoice(invoice.getInvoiceId(), true, false, AuditLevel.FULL, requestOptions);
         assertEquals(adjustedInvoice.getAmount().compareTo(BigDecimal.ZERO), 0);
 
         // Verify invoice audit logs
@@ -407,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, requestOptions);
+        final List<Invoice> invoices = accountApi.getInvoices(accountJson.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
         final Invoice invoice = invoices.get(1);
@@ -424,11 +423,11 @@ public class TestInvoice extends TestJaxrsBase {
         adjustmentInvoiceItem.setInvoiceId(invoice.getInvoiceId());
         adjustmentInvoiceItem.setInvoiceItemId(invoiceItem.getInvoiceItemId());
         adjustmentInvoiceItem.setAmount(adjustedAmount);
-        adjustmentInvoiceItem.setCurrency(invoice.getCurrency().name());
-        killBillClient.adjustInvoiceItem(adjustmentInvoiceItem, requestOptions);
+        adjustmentInvoiceItem.setCurrency(invoice.getCurrency());
+        invoiceApi.adjustInvoiceItem(adjustmentInvoiceItem, invoice.getInvoiceId(), null, requestOptions);
 
         // Verify the new invoice balance
-        final Invoice adjustedInvoice = killBillClient.getInvoice(invoice.getInvoiceId(), requestOptions);
+        final Invoice adjustedInvoice = invoiceApi.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));
     }
@@ -438,7 +437,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final Invoices originalInvoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions);
+        final Invoices originalInvoices = accountApi.getInvoices(accountJson.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
         assertEquals(originalInvoices.size(), 2);
 
         final UUID firstInvoiceItemId = originalInvoices.get(0).getItems().get(0).getInvoiceItemId();
@@ -458,9 +457,12 @@ public class TestInvoice extends TestJaxrsBase {
         final LocalDate endDate = startDate.plusDays(10);
         externalCharge.setEndDate(endDate);
 
-        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(ImmutableList.of(externalCharge), clock.getUTCToday(), false, true, requestOptions);
+        final InvoiceItems itemsForCharge = new InvoiceItems();
+        itemsForCharge.add(externalCharge);
+
+        final List<InvoiceItem> createdExternalCharges = invoiceApi.createExternalCharges(itemsForCharge, accountJson.getAccountId(), clock.getUTCToday().toString(), false, null, true, null, null, requestOptions.extend().withFollowLocation(false).build());
         assertEquals(createdExternalCharges.size(), 1);
-        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true, false, requestOptions);
+        final Invoice invoiceWithItems = invoiceApi.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true, false, AuditLevel.NONE, requestOptions);
         assertEquals(invoiceWithItems.getBalance().compareTo(chargeAmount), 0);
         assertEquals(invoiceWithItems.getItems().size(), 1);
         assertEquals(invoiceWithItems.getItems().get(0).getDescription(), externalCharge.getDescription());
@@ -471,7 +473,7 @@ public class TestInvoice extends TestJaxrsBase {
         assertEquals(invoiceWithItems.getItems().get(0).getLinkedInvoiceItemId(), firstInvoiceItemId);
 
         // Verify the total number of invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 3);
+        assertEquals(accountApi.getInvoices(accountJson.getAccountId(), requestOptions).size(), 3);
     }
 
     @Test(groups = "slow", description = "Can create multiple external charges")
@@ -479,12 +481,12 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 2);
+        assertEquals(accountApi.getInvoices(accountJson.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
 
-        final List<InvoiceItem> externalCharges = new ArrayList<InvoiceItem>();
+        final InvoiceItems externalCharges = new InvoiceItems();
 
         // Does not pass currency to test on purpose that we will default to account currency
         final InvoiceItem externalCharge1 = new InvoiceItem();
@@ -500,27 +502,28 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge2.setDescription(UUID.randomUUID().toString());
         externalCharges.add(externalCharge2);
 
-        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(externalCharges, clock.getUTCToday(), false, true, requestOptions);
+        final List<InvoiceItem> createdExternalCharges = invoiceApi.createExternalCharges(externalCharges, accountJson.getAccountId(), clock.getUTCToday().toString(), false, null, true, null, null, requestOptions.extend().withFollowLocation(false).build());
         assertEquals(createdExternalCharges.size(), 2);
         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(), requestOptions).size(), 3);
+        assertEquals(accountApi.getInvoices(accountJson.getAccountId(), requestOptions).size(), 3);
     }
 
     // Flaky, see https://github.com/killbill/killbill/issues/801
-    @Test(groups = "slow", description = "Can create multiple external charges with same invoice and external keys", retryAnalyzer = FlakyRetryAnalyzer.class)
+    @Test(groups = "slow", description = "Can create multiple external charges with same invoice and external keys")
+    // , retryAnalyzer = FlakyRetryAnalyzer.class
     public void testExternalChargesWithSameInvoiceAndExternalKeys() throws Exception {
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 2);
+        assertEquals(accountApi.getInvoices(accountJson.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
 
-        final List<InvoiceItem> externalCharges = new ArrayList<InvoiceItem>();
+        final InvoiceItems externalCharges = new InvoiceItems();
 
         // Does not pass currency to test on purpose that we will default to account currency
         final InvoiceItem externalCharge1 = new InvoiceItem();
@@ -539,17 +542,15 @@ public class TestInvoice extends TestJaxrsBase {
         final String paymentExternalKey = "anyPaymentExternalKey";
         final String transactionExternalKey = "anyTransactionExternalKey";
 
-        final List<InvoiceItem> createdExternalCharges =
-                killBillClient.createExternalCharges(externalCharges, clock.getUTCToday(), true, true,
-                                                     paymentExternalKey, transactionExternalKey, requestOptions);
+        final List<InvoiceItem> createdExternalCharges = invoiceApi.createExternalCharges(externalCharges, accountJson.getAccountId(), clock.getUTCToday().toString(), true, null, true, paymentExternalKey, transactionExternalKey, requestOptions.extend().withFollowLocation(false).build());
         assertEquals(createdExternalCharges.size(), 2);
         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(), requestOptions).size(), 3);
+        assertEquals(accountApi.getInvoices(accountJson.getAccountId(), requestOptions).size(), 3);
 
-        final Payments payments = killBillClient.getPaymentsForAccount(accountJson.getAccountId(), AuditLevel.NONE, requestOptions);
+        final Payments payments = accountApi.getPayments(accountJson.getAccountId(), null, requestOptions);
         assertNotNull(payments);
         // Verify payment with paymentExternalKey provided
         assertEquals(payments.get(payments.size() - 1).getPaymentExternalKey(), paymentExternalKey);
@@ -562,7 +563,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 2);
+        assertEquals(accountApi.getInvoices(accountJson.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
@@ -570,15 +571,18 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge.setAccountId(accountJson.getAccountId());
         externalCharge.setAmount(chargeAmount);
         externalCharge.setCurrency(accountJson.getCurrency());
-        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(ImmutableList.<InvoiceItem>of(externalCharge), clock.getUTCToday(), true, true, requestOptions);
+        final InvoiceItems inputExternalCharges = new InvoiceItems();
+        inputExternalCharges.add(externalCharge);
+
+        final List<InvoiceItem> createdExternalCharges = invoiceApi.createExternalCharges(inputExternalCharges, accountJson.getAccountId(), clock.getUTCToday().toString(), true, null, true, null, null, requestOptions.extend().withFollowLocation(false).build());
         assertEquals(createdExternalCharges.size(), 1);
-        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true);
+        final Invoice invoiceWithItems = invoiceApi.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true, false, AuditLevel.NONE, requestOptions);
         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(), requestOptions).size(), 3);
+        assertEquals(accountApi.getInvoices(accountJson.getAccountId(), requestOptions).size(), 3);
     }
 
     @Test(groups = "slow", description = "Can create an external charge for a bundle")
@@ -586,7 +590,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId(), requestOptions).size(), 2);
+        assertEquals(accountApi.getInvoices(accountJson.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
@@ -596,15 +600,17 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge.setAmount(chargeAmount);
         externalCharge.setCurrency(accountJson.getCurrency());
         externalCharge.setBundleId(bundleId);
-        final List<InvoiceItem> createdExternalCharges = killBillClient.createExternalCharges(ImmutableList.<InvoiceItem>of(externalCharge), clock.getUTCToday(), false, true, requestOptions);
+        final InvoiceItems input = new InvoiceItems();
+        input.add(externalCharge);
+        final List<InvoiceItem> createdExternalCharges = invoiceApi.createExternalCharges(input, accountJson.getAccountId(), clock.getUTCToday().toString(), false, null, true, null, null, requestOptions.extend().withFollowLocation(false).build());
         assertEquals(createdExternalCharges.size(), 1);
-        final Invoice invoiceWithItems = killBillClient.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true);
+        final Invoice invoiceWithItems = invoiceApi.getInvoice(createdExternalCharges.get(0).getInvoiceId(), true, null, AuditLevel.NONE, requestOptions);
         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(), requestOptions).size(), 3);
+        assertEquals(accountApi.getInvoices(accountJson.getAccountId(), requestOptions).size(), 3);
     }
 
     @Test(groups = "slow", description = "Can paginate and search through all invoices")
@@ -616,17 +622,17 @@ public class TestInvoice extends TestJaxrsBase {
             crappyWaitForLackOfProperSynchonization();
         }
 
-        final Invoices allInvoices = killBillClient.getInvoices(requestOptions);
+        final Invoices allInvoices = invoiceApi.getInvoices(requestOptions);
         Assert.assertEquals(allInvoices.size(), 5);
 
         for (final Invoice invoice : allInvoices) {
-            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);
+            Assert.assertEquals(invoiceApi.searchInvoices(invoice.getInvoiceId().toString(), requestOptions).size(), 1);
+            Assert.assertEquals(invoiceApi.searchInvoices(invoice.getAccountId().toString(), requestOptions).size(), 5);
+            Assert.assertEquals(invoiceApi.searchInvoices(invoice.getInvoiceNumber().toString(), requestOptions).size(), 1);
+            Assert.assertEquals(invoiceApi.searchInvoices(invoice.getCurrency().toString(), requestOptions).size(), 5);
         }
 
-        Invoices page = killBillClient.getInvoices(0L, 1L, requestOptions);
+        Invoices page = invoiceApi.getInvoices(0L, 1L, false, AuditLevel.NONE, requestOptions);
         for (int i = 0; i < 5; i++) {
             Assert.assertNotNull(page);
             Assert.assertEquals(page.size(), 1);
@@ -646,14 +652,14 @@ public class TestInvoice extends TestJaxrsBase {
         credit.setAccountId(account.getAccountId());
         credit.setInvoiceId(null);
         credit.setCreditAmount(creditAmount);
-        final Credit creditJson = killBillClient.createCredit(credit, false, requestOptions);
+        final Credit creditJson = creditApi.createCredit(credit, false, requestOptions);
 
-        Invoice invoice = killBillClient.getInvoice(creditJson.getInvoiceId());
+        Invoice invoice = invoiceApi.getInvoice(creditJson.getInvoiceId(), requestOptions);
         Assert.assertEquals(invoice.getStatus(), InvoiceStatus.DRAFT.toString());
 
-        killBillClient.commitInvoice(invoice.getInvoiceId(), requestOptions);
+        invoiceApi.commitInvoice(invoice.getInvoiceId(), requestOptions);
 
-        invoice = killBillClient.getInvoice(creditJson.getInvoiceId(), requestOptions);
+        invoice = invoiceApi.getInvoice(creditJson.getInvoiceId(), requestOptions);
         Assert.assertEquals(invoice.getStatus(), InvoiceStatus.COMMITTED.toString());
     }
 
@@ -662,7 +668,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, true, requestOptions);
+        final List<Invoice> invoices = accountApi.getInvoices(accountJson.getAccountId(), true, true, false, false, AuditLevel.NONE, requestOptions);
         assertEquals(invoices.size(), 2);
 
         // Migrate an invoice with one external charge
@@ -673,19 +679,23 @@ public class TestInvoice extends TestJaxrsBase {
         externalCharge.setAmount(chargeAmount);
         externalCharge.setItemType(InvoiceItemType.EXTERNAL_CHARGE.toString());
         externalCharge.setCurrency(accountJson.getCurrency());
+        final InvoiceItems inputInvoice = new InvoiceItems();
+        inputInvoice.add(externalCharge);
+        final Account accountWithBalance = accountApi.getAccount(accountJson.getAccountId(), true, true, AuditLevel.NONE, requestOptions);
 
-        final Account accountWithBalance = killBillClient.getAccount(accountJson.getAccountId(), true, true, requestOptions);
+        final Multimap<String, String> queryFollowParams = HashMultimap.<String, String>create(requestOptions.getQueryParamsForFollow());
+        queryFollowParams.put(JaxrsResource.QUERY_INVOICE_WITH_ITEMS, "true");
 
-        final Invoice migrationInvoice = killBillClient.createMigrationInvoice(accountJson.getAccountId(), null, ImmutableList.<InvoiceItem>of(externalCharge), requestOptions);
+        final Invoice migrationInvoice = invoiceApi.createMigrationInvoice(inputInvoice, accountJson.getAccountId(), null, requestOptions.extend().withQueryParamsForFollow(queryFollowParams).build());
         assertEquals(migrationInvoice.getBalance(), BigDecimal.ZERO);
         assertEquals(migrationInvoice.getItems().size(), 1);
         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, requestOptions);
+        final List<Invoice> invoicesWithMigration = accountApi.getInvoices(accountJson.getAccountId(), true, true, false, false, AuditLevel.NONE, requestOptions);
         assertEquals(invoicesWithMigration.size(), 3);
 
-        final Account accountWithBalanceAfterMigration = killBillClient.getAccount(accountJson.getAccountId(), true, true, requestOptions);
+        final Account accountWithBalanceAfterMigration = accountApi.getAccount(accountJson.getAccountId(), true, true, AuditLevel.NONE, requestOptions);
         assertEquals(accountWithBalanceAfterMigration.getAccountBalance().compareTo(accountWithBalance.getAccountBalance()), 0);
     }
 
@@ -701,23 +711,23 @@ public class TestInvoice extends TestJaxrsBase {
         credit.setCreditAmount(creditAmount);
 
         // insert credit to child account
-        final Credit creditJson = killBillClient.createCredit(credit, true, requestOptions);
+        final Credit creditJson = creditApi.createCredit(credit, true, requestOptions);
 
-        Invoices childInvoices = killBillClient.getInvoicesForAccount(childAccount.getAccountId(), true, false, requestOptions);
+        Invoices childInvoices = accountApi.getInvoices(childAccount.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
         Assert.assertEquals(childInvoices.size(), 1);
         Assert.assertEquals(childInvoices.get(0).getCreditAdj().compareTo(BigDecimal.TEN), 0);
 
-        Invoices parentInvoices = killBillClient.getInvoicesForAccount(parentAccount.getAccountId(), true, false, requestOptions);
+        Invoices parentInvoices = accountApi.getInvoices(parentAccount.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
         Assert.assertEquals(parentInvoices.size(), 0);
 
         // transfer credit to parent account
-        killBillClient.transferChildCreditToParent(childAccount.getAccountId(), requestOptions);
+        accountApi.transferChildCreditToParent(childAccount.getAccountId(), requestOptions);
 
-        childInvoices = killBillClient.getInvoicesForAccount(childAccount.getAccountId(), true, false, requestOptions);
+        childInvoices = accountApi.getInvoices(childAccount.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
         Assert.assertEquals(childInvoices.size(), 2);
         Assert.assertEquals(childInvoices.get(1).getCreditAdj().compareTo(BigDecimal.TEN.negate()), 0);
 
-        parentInvoices = killBillClient.getInvoicesForAccount(parentAccount.getAccountId(), true, false, requestOptions);
+        parentInvoices = accountApi.getInvoices(parentAccount.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
         Assert.assertEquals(parentInvoices.size(), 1);
         Assert.assertEquals(parentInvoices.get(0).getCreditAdj().compareTo(BigDecimal.TEN), 0);
     }
@@ -728,7 +738,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account account = createAccount();
 
         // transfer credit to parent account
-        killBillClient.transferChildCreditToParent(account.getAccountId(), requestOptions);
+        accountApi.transferChildCreditToParent(account.getAccountId(), requestOptions);
 
     }
 
@@ -739,7 +749,7 @@ public class TestInvoice extends TestJaxrsBase {
         final Account childAccount = createAccount(parentAccount.getAccountId());
 
         // transfer credit to parent account
-        killBillClient.transferChildCreditToParent(childAccount.getAccountId(), requestOptions);
+        accountApi.transferChildCreditToParent(childAccount.getAccountId(), requestOptions);
 
     }
 
@@ -761,13 +771,12 @@ public class TestInvoice extends TestJaxrsBase {
         createEntitlement(childAccount3.getAccountId(), UUID.randomUUID().toString(), "Shotgun",
                           ProductCategory.BASE, BillingPeriod.MONTHLY, true);
 
-
         clock.addDays(32);
         crappyWaitForLackOfProperSynchonization();
 
-        final List<Invoice> child1Invoices = killBillClient.getInvoicesForAccount(childAccount1.getAccountId(), true, false, requestOptions);
-        final List<Invoice> child2Invoices = killBillClient.getInvoicesForAccount(childAccount2.getAccountId(), true, false, requestOptions);
-        final List<Invoice> child3Invoices = killBillClient.getInvoicesForAccount(childAccount3.getAccountId(), true, false, requestOptions);
+        final List<Invoice> child1Invoices = accountApi.getInvoices(childAccount1.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
+        final List<Invoice> child2Invoices = accountApi.getInvoices(childAccount2.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
+        final List<Invoice> child3Invoices = accountApi.getInvoices(childAccount3.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
 
         assertEquals(child1Invoices.size(), 2);
         final Invoice child1RecurringInvoice = child1Invoices.get(1);
@@ -775,12 +784,12 @@ public class TestInvoice extends TestJaxrsBase {
         final InvoiceItem child2RecurringInvoiceItem = child2Invoices.get(1).getItems().get(0);
         final InvoiceItem child3RecurringInvoiceItem = child3Invoices.get(1).getItems().get(0);
 
-        final List<Invoice> parentInvoices = killBillClient.getInvoicesForAccount(parentAccount.getAccountId(), true, false, requestOptions);
+        final List<Invoice> parentInvoices = accountApi.getInvoices(parentAccount.getAccountId(), true, false, false, false, AuditLevel.NONE, requestOptions);
         assertEquals(parentInvoices.size(), 2);
 
         // check parent invoice with child invoice items and no adjustments
         // parameters: withItems = true, withChildrenItems = true
-        Invoice parentInvoiceWithChildItems = killBillClient.getInvoice(parentInvoices.get(1).getInvoiceId(), true, true, requestOptions);
+        Invoice parentInvoiceWithChildItems = invoiceApi.getInvoice(parentInvoices.get(1).getInvoiceId(), true, true, AuditLevel.NONE, requestOptions);
         assertEquals(parentInvoiceWithChildItems.getItems().size(), 3);
         assertEquals(parentInvoiceWithChildItems.getItems().get(0).getChildItems().size(), 1);
         assertEquals(parentInvoiceWithChildItems.getItems().get(1).getChildItems().size(), 1);
@@ -793,12 +802,12 @@ public class TestInvoice extends TestJaxrsBase {
         adjustmentInvoiceItem.setInvoiceItemId(child1RecurringInvoiceItem.getInvoiceItemId());
         adjustmentInvoiceItem.setAmount(BigDecimal.TEN);
         adjustmentInvoiceItem.setCurrency(child1RecurringInvoiceItem.getCurrency());
-        final Invoice invoiceAdjustment = killBillClient.adjustInvoiceItem(adjustmentInvoiceItem, requestOptions);
-        final InvoiceItem child1AdjInvoiceItem = killBillClient.getInvoice(invoiceAdjustment.getInvoiceId(), requestOptions).getItems().get(1);
+        final Invoice invoiceAdjustment = invoiceApi.adjustInvoiceItem(adjustmentInvoiceItem, child1RecurringInvoice.getInvoiceId(), null, requestOptions);
+        final InvoiceItem child1AdjInvoiceItem = invoiceApi.getInvoice(invoiceAdjustment.getInvoiceId(), true, true, AuditLevel.NONE, requestOptions).getItems().get(1);
 
         // check parent invoice with child invoice items and adjustments
         // parameters: withItems = true, withChildrenItems = true
-        parentInvoiceWithChildItems = killBillClient.getInvoice(parentInvoices.get(1).getInvoiceId(), true, true, requestOptions);
+        parentInvoiceWithChildItems = invoiceApi.getInvoice(parentInvoices.get(1).getInvoiceId(), true, true, AuditLevel.NONE, requestOptions);
         assertEquals(parentInvoiceWithChildItems.getItems().size(), 3);
         assertEquals(parentInvoiceWithChildItems.getItems().get(0).getChildItems().size(), 2);
         assertEquals(parentInvoiceWithChildItems.getItems().get(1).getChildItems().size(), 1);
@@ -816,7 +825,7 @@ public class TestInvoice extends TestJaxrsBase {
         assertTrue(child3InvoiceItemFromParent.equals(child3RecurringInvoiceItem));
 
         // check parent invoice without child invoice items
-        parentInvoiceWithChildItems = killBillClient.getInvoice(parentInvoices.get(1).getInvoiceId(), true, false, requestOptions);
+        parentInvoiceWithChildItems = invoiceApi.getInvoice(parentInvoices.get(1).getInvoiceId(), true, false, AuditLevel.NONE, requestOptions);
         assertEquals(parentInvoiceWithChildItems.getItems().size(), 3);
         assertNull(parentInvoiceWithChildItems.getItems().get(0).getChildItems());
         assertNull(parentInvoiceWithChildItems.getItems().get(1).getChildItems());
@@ -824,7 +833,7 @@ public class TestInvoice extends TestJaxrsBase {
 
         // check parent invoice without items but with child invoice items and adjustment. Should return items anyway.
         // parameters: withItems = false, withChildrenItems = true
-        parentInvoiceWithChildItems = killBillClient.getInvoice(parentInvoices.get(1).getInvoiceId(), false, true, requestOptions);
+        parentInvoiceWithChildItems = invoiceApi.getInvoice(parentInvoices.get(1).getInvoiceId(), false, true, AuditLevel.NONE, requestOptions);
         assertEquals(parentInvoiceWithChildItems.getItems().size(), 3);
         assertEquals(parentInvoiceWithChildItems.getItems().get(0).getChildItems().size(), 2);
         assertEquals(parentInvoiceWithChildItems.getItems().get(1).getChildItems().size(), 1);
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestJaxrsBase.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestJaxrsBase.java
index 83e3d47..6d31b0c 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestJaxrsBase.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestJaxrsBase.java
@@ -38,11 +38,33 @@ import org.eclipse.jetty.servlet.FilterHolder;
 import org.joda.time.LocalDate;
 import org.killbill.billing.GuicyKillbillTestWithEmbeddedDBModule;
 import org.killbill.billing.api.TestApiListener;
-import org.killbill.billing.client.KillBillClient;
 import org.killbill.billing.client.KillBillHttpClient;
-import org.killbill.billing.client.model.Payment;
-import org.killbill.billing.client.model.PaymentTransaction;
-import org.killbill.billing.client.model.Tenant;
+import org.killbill.billing.client.api.gen.AccountApi;
+import org.killbill.billing.client.api.gen.AdminApi;
+import org.killbill.billing.client.api.gen.BundleApi;
+import org.killbill.billing.client.api.gen.CatalogApi;
+import org.killbill.billing.client.api.gen.CreditApi;
+import org.killbill.billing.client.api.gen.CustomFieldApi;
+import org.killbill.billing.client.api.gen.ExportApi;
+import org.killbill.billing.client.api.gen.InvoiceApi;
+import org.killbill.billing.client.api.gen.InvoiceItemApi;
+import org.killbill.billing.client.api.gen.InvoicePaymentApi;
+import org.killbill.billing.client.api.gen.NodesInfoApi;
+import org.killbill.billing.client.api.gen.OverdueApi;
+import org.killbill.billing.client.api.gen.PaymentApi;
+import org.killbill.billing.client.api.gen.PaymentGatewayApi;
+import org.killbill.billing.client.api.gen.PaymentMethodApi;
+import org.killbill.billing.client.api.gen.PaymentTransactionApi;
+import org.killbill.billing.client.api.gen.PluginInfoApi;
+import org.killbill.billing.client.api.gen.SecurityApi;
+import org.killbill.billing.client.api.gen.SubscriptionApi;
+import org.killbill.billing.client.api.gen.TagApi;
+import org.killbill.billing.client.api.gen.TagDefinitionApi;
+import org.killbill.billing.client.api.gen.TenantApi;
+import org.killbill.billing.client.api.gen.UsageApi;
+import org.killbill.billing.client.model.gen.Payment;
+import org.killbill.billing.client.model.gen.PaymentTransaction;
+import org.killbill.billing.client.model.gen.Tenant;
 import org.killbill.billing.invoice.glue.DefaultInvoiceModule;
 import org.killbill.billing.jetty.HttpServer;
 import org.killbill.billing.jetty.HttpServerConfig;
@@ -182,7 +204,29 @@ public class TestJaxrsBase extends KillbillClient {
                                                     DEFAULT_CONNECT_TIMEOUT_SEC * 1000,
                                                     DEFAULT_READ_TIMEOUT_SEC * 1000,
                                                     DEFAULT_REQUEST_TIMEOUT_SEC * 1000);
-        killBillClient = new KillBillClient(killBillHttpClient);
+        accountApi = new AccountApi(killBillHttpClient);
+        adminApi = new AdminApi(killBillHttpClient);
+        bundleApi = new BundleApi(killBillHttpClient);
+        catalogApi = new CatalogApi(killBillHttpClient);
+        creditApi = new CreditApi(killBillHttpClient);
+        customFieldApi = new CustomFieldApi(killBillHttpClient);
+        exportApi = new ExportApi(killBillHttpClient);
+        invoiceApi = new InvoiceApi(killBillHttpClient);
+        invoiceItemApi = new InvoiceItemApi(killBillHttpClient);
+        invoicePaymentApi = new InvoicePaymentApi(killBillHttpClient);
+        nodesInfoApi = new NodesInfoApi(killBillHttpClient);
+        overdueApi = new OverdueApi(killBillHttpClient);
+        paymentApi = new PaymentApi(killBillHttpClient);
+        paymentGatewayApi = new PaymentGatewayApi(killBillHttpClient);
+        paymentMethodApi = new PaymentMethodApi(killBillHttpClient);
+        paymentTransactionApi = new PaymentTransactionApi(killBillHttpClient);
+        pluginInfoApi = new PluginInfoApi(killBillHttpClient);
+        securityApi = new SecurityApi(killBillHttpClient);
+        subscriptionApi = new SubscriptionApi(killBillHttpClient);
+        tagApi = new TagApi(killBillHttpClient);
+        tagDefinitionApi = new TagDefinitionApi(killBillHttpClient);
+        tenantApi = new TenantApi(killBillHttpClient);
+        usageApi = new UsageApi(killBillHttpClient);
     }
 
     protected void loginTenant(final String apiKey, final String apiSecret) {
@@ -228,12 +272,13 @@ public class TestJaxrsBase extends KillbillClient {
         final Tenant tenant = new Tenant();
         tenant.setApiKey(DEFAULT_API_KEY);
         tenant.setApiSecret(DEFAULT_API_SECRET);
-        killBillClient.createTenant(tenant, createdBy, reason, comment);
+        tenantApi.createTenant(tenant, true, requestOptions);
     }
 
     @AfterMethod(groups = "slow")
     public void afterMethod() throws Exception {
-        killBillClient.close();
+
+        killBillHttpClient.close();
         externalBus.stop();
         internalBus.stop();
     }