killbill-memoizeit

server: make tests use com.ning.billing:killbill-client-java Signed-off-by:

1/18/2014 7:02:40 PM

Changes

pom.xml 2(+1 -1)

server/pom.xml 4(+4 -0)

Details

diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountEmailJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountEmailJson.java
index 9d8c0f1..60dedde 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountEmailJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountEmailJson.java
@@ -25,7 +25,7 @@ import com.ning.billing.account.api.AccountEmail;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class AccountEmailJson {
+public class AccountEmailJson extends JsonBase {
 
     private final String accountId;
     private final String email;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceEmailJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceEmailJson.java
index 1b03412..168ef07 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceEmailJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceEmailJson.java
@@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonGetter;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class InvoiceEmailJson {
+public class InvoiceEmailJson extends JsonBase {
 
     private final String accountId;
     private final boolean isNotifiedForInvoices;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java
index b3ed9d8..ba0549f 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJson.java
@@ -104,7 +104,7 @@ public class InvoiceJson extends JsonBase {
         this.invoiceId = input.getId().toString();
         this.invoiceDate = input.getInvoiceDate();
         this.targetDate = input.getTargetDate();
-        this.invoiceNumber = String.valueOf(input.getInvoiceNumber());
+        this.invoiceNumber = input.getInvoiceNumber() == null ? null : String.valueOf(input.getInvoiceNumber());
         this.balance = input.getBalance();
         this.accountId = input.getAccountId().toString();
         this.bundleKeys = null;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java
index 788b423..b955b1b 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/TagDefinitionJson.java
@@ -29,7 +29,7 @@ import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
 
-public class TagDefinitionJson {
+public class TagDefinitionJson extends JsonBase {
 
     private final String id;
     private final Boolean isControlTag;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
index 87c8abc..b922017 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
@@ -93,9 +93,11 @@ import com.ning.billing.util.entity.Pagination;
 import com.ning.billing.util.tag.ControlTagType;
 
 import com.google.common.base.Function;
+import com.google.common.base.Predicate;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Multimap;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -738,7 +740,18 @@ public class AccountResource extends JaxRsResourceBase {
         // Make sure the account exist or we will confuse the history and auditing code
         accountUserApi.getAccountById(accountId, callContext);
 
-        accountUserApi.addEmail(accountId, json.toAccountEmail(UUID.randomUUID()), callContext);
+        // Make sure the email doesn't exist
+        final AccountEmail existingEmail = Iterables.<AccountEmail>tryFind(accountUserApi.getEmails(accountId, callContext),
+                                                                           new Predicate<AccountEmail>() {
+                                                                               @Override
+                                                                               public boolean apply(final AccountEmail input) {
+                                                                                   return input.getEmail().equals(json.getEmail());
+                                                                               }
+                                                                           })
+                                                    .orNull();
+        if (existingEmail == null) {
+            accountUserApi.addEmail(accountId, json.toAccountEmail(UUID.randomUUID()), callContext);
+        }
 
         return uriBuilder.buildResponse(AccountResource.class, "getEmails", json.getAccountId());
     }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountEmailJson.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountEmailJson.java
index 94906a5..b1ca7f7 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountEmailJson.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestAccountEmailJson.java
@@ -37,7 +37,8 @@ public class TestAccountEmailJson extends JaxrsTestSuiteNoDB {
 
         final String asJson = mapper.writeValueAsString(accountEmailJson);
         Assert.assertEquals(asJson, "{\"accountId\":\"" + accountId + "\"," +
-                                    "\"email\":\"" + email + "\"}");
+                                    "\"email\":\"" + email + "\"," +
+                                    "\"auditLogs\":null}");
 
         final AccountEmailJson fromJson = mapper.readValue(asJson, AccountEmailJson.class);
         Assert.assertEquals(fromJson, accountEmailJson);
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceEmailJson.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceEmailJson.java
index 82dfd6b..6640c43 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceEmailJson.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestInvoiceEmailJson.java
@@ -36,7 +36,8 @@ public class TestInvoiceEmailJson extends JaxrsTestSuiteNoDB {
 
         final String asJson = mapper.writeValueAsString(invoiceEmailJson);
         Assert.assertEquals(asJson, "{\"accountId\":\"" + accountId + "\"," +
-                                    "\"isNotifiedForInvoices\":" + isNotifiedForInvoices + "}");
+                                    "\"isNotifiedForInvoices\":" + isNotifiedForInvoices + "," +
+                                    "\"auditLogs\":null}");
 
         final InvoiceEmailJson fromJson = mapper.readValue(asJson, InvoiceEmailJson.class);
         Assert.assertEquals(fromJson, invoiceEmailJson);

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index e73a51d..8bd1bad 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.5.17</version>
+        <version>0.5.18-SNAPSHOT</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.8.8-SNAPSHOT</version>

server/pom.xml 4(+4 -0)

diff --git a/server/pom.xml b/server/pom.xml
index 9ba7701..1838ab3 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -99,6 +99,10 @@
         </dependency>
         <dependency>
             <groupId>com.ning.billing</groupId>
+            <artifactId>killbill-client-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ning.billing</groupId>
             <artifactId>killbill-currency</artifactId>
         </dependency>
         <dependency>
diff --git a/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java b/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
index 5782bd8..5842bed 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
@@ -16,107 +16,46 @@
 
 package com.ning.billing.jaxrs;
 
-import java.io.IOException;
-import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
 import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nullable;
-import javax.ws.rs.core.Response.Status;
-
-import org.joda.time.DateTime;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
 
 import com.ning.billing.GuicyKillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.jaxrs.json.AccountEmailJson;
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.AccountTimelineJson;
-import com.ning.billing.jaxrs.json.CatalogJsonSimple;
-import com.ning.billing.jaxrs.json.ChargebackJson;
-import com.ning.billing.jaxrs.json.CreditJson;
-import com.ning.billing.jaxrs.json.InvoiceItemJson;
-import com.ning.billing.jaxrs.json.InvoiceJson;
-import com.ning.billing.jaxrs.json.OverdueStateJson;
-import com.ning.billing.jaxrs.json.PaymentJson;
-import com.ning.billing.jaxrs.json.PaymentMethodJson;
-import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodPluginDetailJson;
-import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodProperties;
-import com.ning.billing.jaxrs.json.PlanDetailJson;
-import com.ning.billing.jaxrs.json.RefundJson;
-import com.ning.billing.jaxrs.json.SubscriptionJson;
-import com.ning.billing.jaxrs.json.TenantJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.billing.payment.api.RefundStatus;
-import com.ning.billing.util.api.AuditLevel;
-import com.ning.http.client.AsyncCompletionHandler;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
-import com.ning.http.client.ListenableFuture;
-import com.ning.http.client.Realm;
-import com.ning.http.client.Realm.AuthScheme;
-import com.ning.http.client.Response;
-import com.ning.jetty.core.CoreConfig;
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableMap;
+import com.ning.billing.client.KillBillClient;
+import com.ning.billing.client.KillBillHttpClient;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.PaymentMethod;
+import com.ning.billing.client.model.PaymentMethodPluginDetail;
+import com.ning.billing.client.model.PaymentMethodProperties;
+import com.ning.billing.client.model.Subscription;
 
-import static com.ning.billing.jaxrs.resources.JaxrsResource.HDR_API_KEY;
-import static com.ning.billing.jaxrs.resources.JaxrsResource.HDR_API_SECRET;
-import static com.ning.billing.jaxrs.resources.JaxrsResource.OVERDUE;
-import static com.ning.billing.jaxrs.resources.JaxrsResource.QUERY_DELETE_DEFAULT_PM_WITH_AUTO_PAY_OFF;
-import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
 public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedDB {
 
     protected static final String PLUGIN_NAME = "noop";
 
-    protected static final int DEFAULT_HTTP_TIMEOUT_SEC = 20;
-
-    protected static final Map<String, String> DEFAULT_EMPTY_QUERY = new HashMap<String, String>();
-
-    private static final Logger log = LoggerFactory.getLogger(TestJaxrsBase.class);
-
-    public static final String HEADER_CONTENT_TYPE = "Content-type";
-    public static final String CONTENT_TYPE = "application/json";
-
     protected static final String DEFAULT_CURRENCY = "USD";
 
-    protected CoreConfig config;
-    protected AsyncHttpClient httpClient;
-    protected ObjectMapper mapper;
-
     // Multi-Tenancy information, if enabled
     protected String DEFAULT_API_KEY = UUID.randomUUID().toString();
     protected String DEFAULT_API_SECRET = UUID.randomUUID().toString();
-    protected String apiKey = DEFAULT_API_KEY;
-    protected String apiSecret = DEFAULT_API_SECRET;
 
     // RBAC information, if enabled
-    protected String username = null;
-    protected String password = null;
+    protected String USERNAME = "tester";
+    protected String PASSWORD = "tester";
 
     // Context information to be passed around
     protected static final String createdBy = "Toto";
     protected static final String reason = "i am god";
     protected static final String comment = "no comment";
 
+    protected KillBillClient killBillClient;
+    protected KillBillHttpClient killBillHttpClient;
+
     protected List<PaymentMethodProperties> getPaymentMethodCCProperties() {
         final List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodProperties>();
         properties.add(new PaymentMethodProperties("type", "CreditCard", false));
@@ -134,277 +73,48 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
     }
 
     protected List<PaymentMethodProperties> getPaymentMethodPaypalProperties() {
-        final List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>();
+        final List<PaymentMethodProperties> properties = new ArrayList<PaymentMethodProperties>();
         properties.add(new PaymentMethodProperties("type", "CreditCard", false));
         properties.add(new PaymentMethodProperties("email", "zouzou@laposte.fr", false));
         properties.add(new PaymentMethodProperties("baid", "23-8787d-R", false));
         return properties;
     }
 
-    protected PaymentMethodJson getPaymentMethodJson(final String accountId, final List<PaymentMethodProperties> properties) {
-        final PaymentMethodPluginDetailJson info = new PaymentMethodPluginDetailJson(null, null, null, null, null, null, null, null, null, null, null, null, null, null, properties);
-        return new PaymentMethodJson(null, accountId, true, PLUGIN_NAME, info);
-    }
-
-    //
-    // TENANT UTILITIES
-    //
-
-    protected String createTenant(final String apiKey, final String apiSecret) throws Exception {
-        final String baseJson = mapper.writeValueAsString(new TenantJson(null, null, apiKey, apiSecret));
-        final Response response = doPost(JaxrsResource.TENANTS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-        return response.getHeader("Location");
-    }
-
-    protected String registerCallbackNotificationForTenant(final String callback) throws Exception {
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_NOTIFICATION_CALLBACK, callback);
-        final String uri = JaxrsResource.TENANTS_PATH + "/" + JaxrsResource.REGISTER_NOTIFICATION_CALLBACK;
-        final Response response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-        return response.getHeader("Location");
-    }
-
-    //
-    // SECURITY UTILITIES
-    //
-
-    protected void loginAsAdmin() {
-        loginAs("tester", "tester");
-    }
-
-    protected void loginAs(final String username, final String password) {
-        this.username = username;
-        this.password = password;
-    }
-
-    protected void logout() {
-        this.username = null;
-        this.password = null;
-    }
-
-    protected List<String> getPermissions(@Nullable final String username, @Nullable final String password) throws Exception {
-        final String oldUsername = this.username;
-        final String oldPassword = this.password;
-
-        this.username = username;
-        this.password = password;
-
-        final Response response = doGet(JaxrsResource.SECURITY_PATH + "/permissions", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        this.username = oldUsername;
-        this.password = oldPassword;
-
-        final String baseJson = response.getResponseBody();
-        final List<String> objFromJson = mapper.readValue(baseJson, new TypeReference<List<String>>() {});
-        Assert.assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    //
-    // ACCOUNT UTILITIES
-    //
-
-    protected AccountJson getAccountById(final String id) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + id;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String baseJson = response.getResponseBody();
-        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
-        Assert.assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected AccountJson getAccountByExternalKey(final String externalKey) throws Exception {
-        final Response response = getAccountByExternalKeyNoValidation(externalKey);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String baseJson = response.getResponseBody();
-        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
-        Assert.assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected List<AccountJson> searchAccountsByKey(final String key) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + JaxrsResource.SEARCH + "/" + key;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String baseJson = response.getResponseBody();
-        final List<AccountJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<AccountJson>>() {});
-        Assert.assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected Response getAccountByExternalKeyNoValidation(final String externalKey) {
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, externalKey);
-        return doGet(JaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-    }
-
-    protected AccountTimelineJson getAccountTimeline(final String accountId) throws Exception {
-        return doGetAccountTimeline(accountId, AuditLevel.NONE);
-    }
-
-    protected AccountTimelineJson getAccountTimelineWithAudits(final String accountId, final AuditLevel auditLevel) throws Exception {
-        return doGetAccountTimeline(accountId, auditLevel);
-    }
-
-    private AccountTimelineJson doGetAccountTimeline(final String accountId, final AuditLevel auditLevel) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.TIMELINE;
-
-        final Response response = doGet(uri, ImmutableMap.<String, String>of(JaxrsResource.QUERY_AUDIT, auditLevel.toString()), DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String baseJson = response.getResponseBody();
-        final AccountTimelineJson objFromJson = mapper.readValue(baseJson, AccountTimelineJson.class);
-        assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected AccountJson createAccountWithDefaultPaymentMethod() throws Exception {
-        final AccountJson input = createAccount();
-        return doCreateAccountWithDefaultPaymentMethod(input);
-    }
-
-    protected AccountJson createAccountWithDefaultPaymentMethod(final String name, final String key, final String email) throws Exception {
-        final AccountJson input = createAccount(name, key, email);
-        return doCreateAccountWithDefaultPaymentMethod(input);
-    }
-
-    protected AccountJson doCreateAccountWithDefaultPaymentMethod(final AccountJson input) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
-        final PaymentMethodJson paymentMethodJson = getPaymentMethodJson(input.getAccountId(), null);
-        String baseJson = mapper.writeValueAsString(paymentMethodJson);
-        Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_PAYMENT_METHOD_IS_DEFAULT, "true");
+    protected Account createAccountWithDefaultPaymentMethod() throws Exception {
+        final Account input = createAccount();
 
-        Response response = doPost(uri, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+        final PaymentMethodPluginDetail info = new PaymentMethodPluginDetail();
+        final PaymentMethod paymentMethodJson = new PaymentMethod(null, input.getAccountId(), true, PLUGIN_NAME, info);
+        killBillClient.createPaymentMethod(paymentMethodJson, createdBy, reason, comment);
 
-        queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, input.getExternalKey());
-        response = doGet(JaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
-        Assert.assertNotNull(objFromJson);
-        Assert.assertNotNull(objFromJson.getPaymentMethodId());
-        return objFromJson;
+        return killBillClient.getAccount(input.getExternalKey());
     }
 
-    protected AccountJson createAccount() throws Exception {
-        return createAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString().substring(0, 5) + '@' + UUID.randomUUID().toString().substring(0, 5));
-    }
-
-    protected AccountJson createAccount(final String name, final String key, final String email) throws Exception {
-        Response response = createAccountNoValidation(name, key, email);
-        final String baseJson;
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        Assert.assertNotNull(location);
-
-        // Retrieves by Id based on Location returned
-        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        baseJson = response.getResponseBody();
-        final AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
-        Assert.assertNotNull(objFromJson);
-        return objFromJson;
+    protected Account createAccount() throws Exception {
+        final Account input = getAccount();
+        return killBillClient.createAccount(input, createdBy, reason, comment);
     }
 
-    protected Response createAccountNoValidation() throws IOException {
-        return createAccountNoValidation(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString().substring(0, 5) + '@' + UUID.randomUUID().toString().substring(0, 5));
-    }
+    protected Subscription createEntitlement(final UUID accountId, final String bundleExternalKey, final String productName,
+                                             final ProductCategory productCategory, final BillingPeriod billingPeriod, final boolean waitCompletion) throws Exception {
+        final Subscription input = new Subscription();
+        input.setAccountId(accountId);
+        input.setExternalKey(bundleExternalKey);
+        input.setProductName(productName);
+        input.setProductCategory(productCategory);
+        input.setBillingPeriod(billingPeriod);
+        input.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-    protected Response createAccountNoValidation(final String name, final String key, final String email) throws IOException {
-        final AccountJson input = getAccountJson(name, key, email);
-        final String baseJson = mapper.writeValueAsString(input);
-        return doPost(JaxrsResource.ACCOUNTS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        return killBillClient.createSubscription(input, waitCompletion ? 5 : -1, createdBy, reason, comment);
     }
 
-    protected AccountJson updateAccount(final String accountId, final AccountJson newInput) throws Exception {
-        final String baseJson = mapper.writeValueAsString(newInput);
-
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId;
-        final Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String retrievedJson = response.getResponseBody();
-        final AccountJson objFromJson = mapper.readValue(retrievedJson, AccountJson.class);
-        assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected List<AccountEmailJson> getEmailsForAccount(final String accountId) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
-
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        return mapper.readValue(response.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
-    }
-
-    protected void addEmailToAccount(final String accountId, final AccountEmailJson email) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
-
-        final String emailString = mapper.writeValueAsString(email);
-        final Response response = doPost(uri, emailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-    }
-
-    protected void removeEmailFromAccount(final String accountId, final String email) throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
-
-        final Response fifthResponse = doDelete(uri + "/" + email, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(fifthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-    }
-
-    protected SubscriptionJson createEntitlement(final String accountId, final String bundleExternalKey, final String productName, final String productCategory, final String billingPeriod, final boolean waitCompletion) throws Exception {
-
-        final SubscriptionJson input = new SubscriptionJson(accountId, null, null, bundleExternalKey, null, productName, productCategory,
-                                                            billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null, null, null, null, null,
-                                                            null, null, null);
-        String baseJson = mapper.writeValueAsString(input);
-
-        final Map<String, String> queryParams = waitCompletion ? getQueryParamsForCallCompletion("5") : DEFAULT_EMPTY_QUERY;
-        Response response = doPost(JaxrsResource.SUBSCRIPTIONS_PATH, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC * 1000);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        Assert.assertNotNull(location);
-
-        // Retrieves by Id based on Location returned
-
-        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        baseJson = response.getResponseBody();
-        final SubscriptionJson objFromJson = mapper.readValue(baseJson, SubscriptionJson.class);
-        return objFromJson;
-    }
-
-    //
-    // INVOICE UTILITIES
-    //
-
-    protected AccountJson createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod();
+    protected Account createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
+        final Account accountJson = createAccountWithDefaultPaymentMethod();
         assertNotNull(accountJson);
 
         // Add a bundle, subscription and move the clock to get the first invoice
-        final SubscriptionJson subscriptionJson = createEntitlement(accountJson.getAccountId(), UUID.randomUUID().toString(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        final Subscription subscriptionJson = createEntitlement(accountJson.getAccountId(), UUID.randomUUID().toString(), "Shotgun",
+                                                                ProductCategory.BASE, BillingPeriod.MONTHLY, true);
         assertNotNull(subscriptionJson);
         clock.addDays(32);
         crappyWaitForLackOfProperSynchonization();
@@ -412,13 +122,14 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
         return accountJson;
     }
 
-    protected AccountJson createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
+    protected Account createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
         // Create an account with no payment method
-        final AccountJson accountJson = createAccount();
+        final Account accountJson = createAccount();
         assertNotNull(accountJson);
 
         // Add a bundle, subscription and move the clock to get the first invoice
-        final SubscriptionJson subscriptionJson = createEntitlement(accountJson.getAccountId(), UUID.randomUUID().toString(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        final Subscription subscriptionJson = createEntitlement(accountJson.getAccountId(), UUID.randomUUID().toString(), "Shotgun",
+                                                                ProductCategory.BASE, BillingPeriod.MONTHLY, true);
         assertNotNull(subscriptionJson);
         clock.addMonths(1);
         crappyWaitForLackOfProperSynchonization();
@@ -428,675 +139,12 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
         return accountJson;
     }
 
-    protected InvoiceJson getInvoice(final String invoiceId) throws IOException {
-        return getInvoiceWithAudits(invoiceId, AuditLevel.NONE);
-    }
-
-    protected InvoiceJson getInvoice(final String invoiceId, final Boolean withItems) throws IOException {
-        return doGetInvoice(invoiceId, withItems, InvoiceJson.class, AuditLevel.NONE);
-    }
-
-    protected InvoiceJson getInvoiceWithAudits(final String invoiceId, final AuditLevel auditLevel) throws IOException {
-        return doGetInvoice(invoiceId, Boolean.TRUE, InvoiceJson.class, auditLevel);
-    }
-
-    protected InvoiceJson getInvoice(final Integer invoiceNumber) throws IOException {
-        return getInvoice(invoiceNumber.toString());
-    }
-
-    protected InvoiceJson getInvoice(final Integer invoiceNumber, final Boolean withItems) throws IOException {
-        return doGetInvoice(invoiceNumber.toString(), withItems, InvoiceJson.class, AuditLevel.NONE);
-    }
-
-    protected InvoiceJson getInvoiceWithItems(final String invoiceId) throws IOException {
-        return getInvoiceWithItemsWithAudits(invoiceId, AuditLevel.NONE);
-    }
-
-    protected InvoiceJson getInvoiceWithItemsWithAudits(final String invoiceId, final AuditLevel auditLevel) throws IOException {
-        return doGetInvoice(invoiceId, Boolean.TRUE, InvoiceJson.class, auditLevel);
-    }
-
-    private <T> T doGetInvoice(final String invoiceId, final Boolean withItems, final Class<T> clazz, final AuditLevel auditLevel) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId;
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_INVOICE_WITH_ITEMS, withItems.toString());
-        queryParams.put(JaxrsResource.QUERY_AUDIT, auditLevel.toString());
-
-        final Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-
-        final T firstInvoiceJson = mapper.readValue(baseJson, clazz);
-        assertNotNull(firstInvoiceJson);
-
-        return firstInvoiceJson;
-    }
-
-    protected List<InvoiceJson> getInvoicesForAccount(final String accountId) throws IOException {
-        return getInvoicesForAccountWithAudits(accountId, AuditLevel.NONE);
-    }
-
-    protected List<InvoiceJson> getInvoicesForAccountWithAudits(final String accountId, final AuditLevel auditLevel) throws IOException {
-        return doGetInvoicesForAccount(accountId, Boolean.TRUE, new TypeReference<List<InvoiceJson>>() {}, auditLevel);
-    }
-
-    protected List<InvoiceJson> getInvoicesWithItemsForAccount(final String accountId) throws IOException {
-        return getInvoicesWithItemsForAccountWithAudits(accountId, AuditLevel.NONE);
-    }
-
-    protected List<InvoiceJson> getInvoicesWithItemsForAccountWithAudits(final String accountId, final AuditLevel auditLevel) throws IOException {
-        return doGetInvoicesForAccount(accountId, Boolean.TRUE, new TypeReference<List<InvoiceJson>>() {}, auditLevel);
-    }
-
-    private <T> List<T> doGetInvoicesForAccount(final String accountId, final Boolean withItems, final TypeReference<List<T>> clazz, final AuditLevel auditLevel) throws IOException {
-
-        final String invoicesURI = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.INVOICES;
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_INVOICE_WITH_ITEMS, withItems.toString());
-        queryParams.put(JaxrsResource.QUERY_AUDIT, auditLevel.toString());
-
-        final Response invoicesResponse = doGet(invoicesURI, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(invoicesResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final String invoicesBaseJson = invoicesResponse.getResponseBody();
-        final List<T> invoices = mapper.readValue(invoicesBaseJson, clazz);
-        assertNotNull(invoices);
-
-        return invoices;
-    }
-
-    protected InvoiceJson createDryRunInvoice(final String accountId, final DateTime futureDate) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH;
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
-        queryParams.put(JaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
-        queryParams.put(JaxrsResource.QUERY_DRY_RUN, "true");
-
-        final Response response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String baseJson = response.getResponseBody();
-        final InvoiceJson futureInvoice = mapper.readValue(baseJson, InvoiceJson.class);
-        assertNotNull(futureInvoice);
-
-        return futureInvoice;
-    }
-
-    protected void createInvoice(final String accountId, final DateTime futureDate) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH;
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
-        queryParams.put(JaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
-
-        final Response response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        Assert.assertNotNull(location);
-    }
-
-    protected void adjustInvoiceItem(final String accountId, final String invoiceId, final String invoiceItemId,
-                                     @Nullable final DateTime requestedDate, @Nullable final BigDecimal amount, @Nullable final Currency currency) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId;
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        if (requestedDate != null) {
-            queryParams.put(JaxrsResource.QUERY_REQUESTED_DT, requestedDate.toDateTimeISO().toString());
-        }
-
-        final InvoiceItemJson adjustment = new InvoiceItemJson(invoiceItemId, null, null, accountId, null, null, null, null,
-                                                               null, null, null, null, amount, currency, null);
-        final String adjustmentJson = mapper.writeValueAsString(adjustment);
-        final Response response = doPost(uri, adjustmentJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-    }
-
-    protected InvoiceJson createExternalCharge(final String accountId, final BigDecimal amount, @Nullable final String bundleId,
-                                               @Nullable final Currency currency, @Nullable final DateTime requestedDate, final Boolean autoPay) throws Exception {
-        return doCreateExternalCharge(accountId, null, bundleId, amount, currency, requestedDate, autoPay, JaxrsResource.CHARGES_PATH);
-    }
-
-    protected InvoiceJson createExternalChargeForInvoice(final String accountId, final String invoiceId, @Nullable final String bundleId, final BigDecimal amount,
-                                                         @Nullable final Currency currency, @Nullable final DateTime requestedDate, final Boolean autoPay) throws Exception {
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.CHARGES;
-        return doCreateExternalCharge(accountId, invoiceId, bundleId, amount, currency, requestedDate, autoPay, uri);
-    }
-
-    private InvoiceJson doCreateExternalCharge(final String accountId, @Nullable final String invoiceId, @Nullable final String bundleId, @Nullable final BigDecimal amount,
-                                               @Nullable final Currency currency, final DateTime requestedDate, final Boolean autoPay, final String uri) throws IOException {
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        if (requestedDate != null) {
-            queryParams.put(JaxrsResource.QUERY_REQUESTED_DT, requestedDate.toDateTimeISO().toString());
-        }
-        if (autoPay) {
-            queryParams.put(JaxrsResource.QUERY_PAY_INVOICE, "true");
-        }
-
-        final InvoiceItemJson externalCharge = new InvoiceItemJson(null, invoiceId, null, accountId, bundleId, null, null, null,
-                                                                   null, null, null, null, amount, currency, null);
-        final String externalChargeJson = mapper.writeValueAsString(externalCharge);
-        final Response response = doPost(uri, externalChargeJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        Assert.assertNotNull(location);
-
-        final Map<String, String> queryParamsForInvoice = new HashMap<String, String>();
-        queryParamsForInvoice.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
-        queryParamsForInvoice.put(JaxrsResource.QUERY_INVOICE_WITH_ITEMS, "true");
-        final Response invoiceResponse = doGetWithUrl(location, queryParamsForInvoice, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(invoiceResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final String invoicesBaseJson = invoiceResponse.getResponseBody();
-        final InvoiceJson invoice = mapper.readValue(invoicesBaseJson, new TypeReference<InvoiceJson>() {});
-        assertNotNull(invoice);
-
-        return invoice;
-    }
-
-    //
-    // PAYMENT UTILITIES
-    //
-
-    protected PaymentJson getPayment(final String paymentId) throws IOException {
-        return doGetPayment(paymentId, DEFAULT_EMPTY_QUERY, PaymentJson.class);
-    }
-
-    protected PaymentJson getPaymentWithRefundsAndChargebacks(final String paymentId) throws IOException {
-        return doGetPayment(paymentId, ImmutableMap.<String, String>of(JaxrsResource.QUERY_PAYMENT_WITH_REFUNDS_AND_CHARGEBACKS, "true"), PaymentJson.class);
-    }
-
-    protected <T extends PaymentJson> T doGetPayment(final String paymentId, final Map<String, String> queryParams, final Class<T> clazz) throws IOException {
-        final String paymentURI = JaxrsResource.PAYMENTS_PATH + "/" + paymentId;
-
-        final Response paymentResponse = doGet(paymentURI, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final T paymentJsonSimple = mapper.readValue(paymentResponse.getResponseBody(), clazz);
-        assertNotNull(paymentJsonSimple);
-
-        return paymentJsonSimple;
-    }
-
-    protected PaymentMethodJson getPaymentMethod(final String paymentMethodId) throws IOException {
-        final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
-        final Response paymentMethodResponse = doGet(paymentMethodURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentMethodResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final PaymentMethodJson paymentMethodJson = mapper.readValue(paymentMethodResponse.getResponseBody(), PaymentMethodJson.class);
-        assertNotNull(paymentMethodJson);
-
-        return paymentMethodJson;
-    }
-
-    protected PaymentMethodJson getPaymentMethodWithPluginInfo(final String paymentMethodId) throws IOException {
-        final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
-
-        final Response paymentMethodResponse = doGet(paymentMethodURI,
-                                                     ImmutableMap.<String, String>of(JaxrsResource.QUERY_PAYMENT_METHOD_PLUGIN_INFO, "true"),
-                                                     DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentMethodResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final PaymentMethodJson paymentMethodJson = mapper.readValue(paymentMethodResponse.getResponseBody(), PaymentMethodJson.class);
-        assertNotNull(paymentMethodJson);
-
-        return paymentMethodJson;
-    }
-
-    protected List<PaymentMethodJson> searchPaymentMethodsByKey(final String key) throws Exception {
-        return searchPaymentMethodsByKeyAndPlugin(key, null);
-    }
-
-    protected List<PaymentMethodJson> searchPaymentMethodsByKeyAndPlugin(final String key, @Nullable final String pluginName) throws Exception {
-        final String uri = JaxrsResource.PAYMENT_METHODS_PATH + "/" + JaxrsResource.SEARCH + "/" + key;
-        final Response response = doGet(uri,
-                                        pluginName == null ? DEFAULT_EMPTY_QUERY : ImmutableMap.<String, String>of(JaxrsResource.QUERY_PAYMENT_METHOD_PLUGIN_NAME, pluginName),
-                                        DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        final String baseJson = response.getResponseBody();
-        final List<PaymentMethodJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentMethodJson>>() {});
-        Assert.assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected void deletePaymentMethod(final String paymentMethodId, final Boolean deleteDefault) throws IOException {
-        final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
-
-        final Response response = doDelete(paymentMethodURI, ImmutableMap.<String, String>of(QUERY_DELETE_DEFAULT_PM_WITH_AUTO_PAY_OFF, deleteDefault.toString()), DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-    }
-
-    protected List<PaymentJson> getPaymentsForAccount(final String accountId) throws IOException {
-        final String paymentsURI = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.PAYMENTS;
-        final Response paymentsResponse = doGet(paymentsURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentsResponse.getStatusCode(), Status.OK.getStatusCode());
-        final String paymentsBaseJson = paymentsResponse.getResponseBody();
-
-        final List<PaymentJson> paymentJsons = mapper.readValue(paymentsBaseJson, new TypeReference<List<PaymentJson>>() {});
-        assertNotNull(paymentJsons);
-
-        return paymentJsons;
-    }
-
-    protected List<PaymentJson> getPaymentsForInvoice(final String invoiceId) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.PAYMENTS;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<PaymentJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJson>>() {});
-        assertNotNull(objFromJson);
-
-        return objFromJson;
-    }
-
-    protected void payAllInvoices(final AccountJson accountJson, final Boolean externalPayment) throws IOException {
-        final PaymentJson payment = new PaymentJson(null, null, accountJson.getAccountId(), null, null, null, null,
-                                                    null, null, 0, null, null, null, null, null, null, null, null);
-        final String postJson = mapper.writeValueAsString(payment);
-
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENTS;
-        doPost(uri, postJson, ImmutableMap.<String, String>of("externalPayment", externalPayment.toString()), DEFAULT_HTTP_TIMEOUT_SEC);
-    }
-
-    protected List<PaymentJson> createInstaPayment(final AccountJson accountJson, final InvoiceJson invoice) throws IOException {
-        final PaymentJson payment = new PaymentJson(invoice.getAmount(), BigDecimal.ZERO, accountJson.getAccountId(),
-                                                    invoice.getInvoiceId(), null, null, null, null, null, 0, null, null, null, null, null, null, null, null);
-        final String postJson = mapper.writeValueAsString(payment);
-
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoice.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
-        doPost(uri, postJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        return getPaymentsForInvoice(invoice.getInvoiceId());
-    }
-
-    protected List<PaymentJson> createExternalPayment(final AccountJson accountJson, final String invoiceId, final BigDecimal paidAmount) throws IOException {
-        final PaymentJson payment = new PaymentJson(paidAmount, BigDecimal.ZERO, accountJson.getAccountId(),
-                                                    invoiceId, null, null, null, null, null, 0,
-                                                    null, null, null, null, null, null, null, null);
-        final String postJson = mapper.writeValueAsString(payment);
-
-        final String paymentURI = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.PAYMENTS;
-        final Response paymentResponse = doPost(paymentURI, postJson, ImmutableMap.<String, String>of("externalPayment", "true"), DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentResponse.getStatusCode(), Status.CREATED.getStatusCode());
-
-        return getPaymentsForInvoice(invoiceId);
-    }
-
-    //
-    // CHARGEBACKS
-    //
-
-    protected ChargebackJson createChargeBack(final String paymentId, final BigDecimal chargebackAmount) throws IOException {
-        final ChargebackJson input = new ChargebackJson(null, null, null, null, chargebackAmount, paymentId, null, null);
-        final String jsonInput = mapper.writeValueAsString(input);
-
-        // Create the chargeback
-        final Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode(), response.getResponseBody());
-
-        // Find the chargeback by location
-        final String location = response.getHeader("Location");
-        assertNotNull(location);
-        final Response responseByLocation = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(responseByLocation.getStatusCode(), Status.OK.getStatusCode());
-
-        return mapper.readValue(responseByLocation.getResponseBody(), ChargebackJson.class);
-    }
-
-    //
-    // REFUNDS
-    //
-
-    protected List<RefundJson> getRefundsForAccount(final String accountId) throws IOException {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.REFUNDS;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<RefundJson> refunds = mapper.readValue(baseJson, new TypeReference<List<RefundJson>>() {});
-        assertNotNull(refunds);
-
-        return refunds;
-    }
-
-    protected List<RefundJson> getRefundsForPayment(final String paymentId) throws IOException {
-        final String uri = JaxrsResource.PAYMENTS_PATH + "/" + paymentId + "/" + JaxrsResource.REFUNDS;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<RefundJson> refunds = mapper.readValue(baseJson, new TypeReference<List<RefundJson>>() {});
-        assertNotNull(refunds);
-
-        return refunds;
-    }
-
-    protected RefundJson createRefund(final String paymentId, final BigDecimal amount) throws IOException {
-        return doCreateRefund(paymentId, amount, false, ImmutableMap.<String, BigDecimal>of());
-    }
-
-    protected RefundJson createRefundWithInvoiceAdjustment(final String paymentId, final BigDecimal amount) throws IOException {
-        return doCreateRefund(paymentId, amount, true, ImmutableMap.<String, BigDecimal>of());
-    }
-
-    protected RefundJson createRefundWithInvoiceItemAdjustment(final String paymentId, final String invoiceItemId, final BigDecimal amount) throws IOException {
-        final Map<String, BigDecimal> adjustments = new HashMap<String, BigDecimal>();
-        adjustments.put(invoiceItemId, amount);
-        return doCreateRefund(paymentId, amount, true, adjustments);
-    }
-
-    private RefundJson doCreateRefund(final String paymentId, final BigDecimal amount, final boolean adjusted, final Map<String, BigDecimal> itemAdjustments) throws IOException {
-        final String uri = JaxrsResource.PAYMENTS_PATH + "/" + paymentId + "/" + JaxrsResource.REFUNDS;
-
-        final List<InvoiceItemJson> adjustments = new ArrayList<InvoiceItemJson>();
-        for (final String itemId : itemAdjustments.keySet()) {
-            adjustments.add(new InvoiceItemJson(itemId, null, null, null, null, null, null, null, null, null, null, null,
-                                                itemAdjustments.get(itemId), null, null));
-        }
-        final RefundJson refundJson = new RefundJson(null, paymentId, amount, DEFAULT_CURRENCY, RefundStatus.COMPLETED.toString(), adjusted, null, null, adjustments, null);
-        final String baseJson = mapper.writeValueAsString(refundJson);
-        final Response response = doPost(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String locationCC = response.getHeader("Location");
-        Assert.assertNotNull(locationCC);
-
-        // Retrieves by Id based on Location returned
-        final Response retrievedResponse = doGetWithUrl(locationCC, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(retrievedResponse.getStatusCode(), Status.OK.getStatusCode());
-        final String retrievedBaseJson = retrievedResponse.getResponseBody();
-        final RefundJson retrievedRefundJson = mapper.readValue(retrievedBaseJson, RefundJson.class);
-        assertNotNull(retrievedRefundJson);
-        // Verify we have the adjusted items
-        if (retrievedRefundJson.getAdjustments() != null) {
-            final Set<String> allLinkedItemIds = new HashSet<String>(Collections2.transform(retrievedRefundJson.getAdjustments(), new Function<InvoiceItemJson, String>() {
-                @Override
-                public String apply(@Nullable final InvoiceItemJson input) {
-                    if (input != null) {
-                        return input.getLinkedInvoiceItemId();
-                    } else {
-                        return null;
-                    }
-                }
-            }));
-            assertEquals(allLinkedItemIds, itemAdjustments.keySet());
-        }
-
-        return retrievedRefundJson;
-    }
-
-    protected Map<String, String> getQueryParamsForCallCompletion(final String timeoutSec) {
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_CALL_COMPLETION, "true");
-        queryParams.put(JaxrsResource.QUERY_CALL_TIMEOUT, timeoutSec);
-        return queryParams;
-    }
-
-    //
-    // CREDITS
-    //
-
-    protected CreditJson createCreditForAccount(final String accountId, final BigDecimal creditAmount,
-                                                final DateTime requestedDate, final DateTime effectiveDate) throws IOException {
-        return createCreditForInvoice(accountId, null, creditAmount, requestedDate, effectiveDate);
-    }
-
-    protected CreditJson createCreditForInvoice(final String accountId, final String invoiceId, final BigDecimal creditAmount,
-                                                final DateTime requestedDate, final DateTime effectiveDate) throws IOException {
-        final CreditJson input = new CreditJson(creditAmount, invoiceId, UUID.randomUUID().toString(),
-                                                effectiveDate.toLocalDate(),
-                                                accountId,
-                                                null);
-        final String jsonInput = mapper.writeValueAsString(input);
-
-        // Create the credit
-        Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode(), response.getResponseBody());
-
-        final String location = response.getHeader("Location");
-        assertNotNull(location);
-
-        // Retrieves by Id based on Location returned
-        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        return mapper.readValue(response.getResponseBody(), CreditJson.class);
-    }
-
-    //
-    // OVERDUE
-    //
-
-    protected OverdueStateJson getOverdueStateForAccount(final String accountId) throws Exception {
-        final String overdueURI = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + OVERDUE;
-        final Response overdueResponse = doGet(overdueURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(overdueResponse.getStatusCode(), Status.OK.getStatusCode());
-
-        final OverdueStateJson overdueStateJson = mapper.readValue(overdueResponse.getResponseBody(), OverdueStateJson.class);
-        assertNotNull(overdueStateJson);
-
-        return overdueStateJson;
-    }
-
-    //
-    // PLUGINS
-    //
-
-    protected Response pluginGET(final String uri) throws Exception {
-        return pluginGET(uri, DEFAULT_EMPTY_QUERY);
-    }
-
-    protected Response pluginGET(final String uri, final Map<String, String> queryParams) throws Exception {
-        return doGet(JaxrsResource.PLUGINS_PATH + "/" + uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-    }
-
-    protected Response pluginHEAD(final String uri) throws Exception {
-        return pluginHEAD(uri, DEFAULT_EMPTY_QUERY);
-    }
-
-    protected Response pluginHEAD(final String uri, final Map<String, String> queryParams) throws Exception {
-        return doHead(JaxrsResource.PLUGINS_PATH + "/" + uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-    }
-
-    protected Response pluginPOST(final String uri, @Nullable final String body) throws Exception {
-        return pluginPOST(uri, body, DEFAULT_EMPTY_QUERY);
-    }
-
-    protected Response pluginPOST(final String uri, @Nullable final String body, final Map<String, String> queryParams) throws Exception {
-        return doPost(JaxrsResource.PLUGINS_PATH + "/" + uri, body, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-    }
-
-    protected Response pluginPUT(final String uri, @Nullable final String body) throws Exception {
-        return pluginPUT(uri, body, DEFAULT_EMPTY_QUERY);
-    }
-
-    protected Response pluginPUT(final String uri, @Nullable final String body, final Map<String, String> queryParams) throws Exception {
-        return doPut(JaxrsResource.PLUGINS_PATH + "/" + uri, body, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-    }
-
-    protected Response pluginDELETE(final String uri) throws Exception {
-        return pluginDELETE(uri, DEFAULT_EMPTY_QUERY);
-    }
-
-    protected Response pluginDELETE(final String uri, final Map<String, String> queryParams) throws Exception {
-        return doDelete(JaxrsResource.PLUGINS_PATH + "/" + uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-    }
-
-    protected Response pluginOPTIONS(final String uri) throws Exception {
-        return pluginOPTIONS(uri, DEFAULT_EMPTY_QUERY);
-    }
-
-    protected Response pluginOPTIONS(final String uri, final Map<String, String> queryParams) throws Exception {
-        return doOptions(JaxrsResource.PLUGINS_PATH + "/" + uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-    }
-
-    //
-    // CATALOG
-    //
-
-    public CatalogJsonSimple getSimpleCatalog() throws Exception {
-        final Response response = doGet(JaxrsResource.CATALOG_PATH + "/simpleCatalog", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String body = response.getResponseBody();
-        return mapper.readValue(body, CatalogJsonSimple.class);
-    }
-
-    public List<PlanDetailJson> getAvailableAddons(final String baseProductName) throws Exception {
-        final Response response = doGet(JaxrsResource.CATALOG_PATH + "/availableAddons",
-                                        ImmutableMap.<String, String>of("baseProductName", baseProductName),
-                                        DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String body = response.getResponseBody();
-        return mapper.readValue(body, new TypeReference<List<PlanDetailJson>>() {});
-    }
-
-    public List<PlanDetailJson> getBasePlans() throws Exception {
-        final Response response = doGet(JaxrsResource.CATALOG_PATH + "/availableBasePlans", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String body = response.getResponseBody();
-        return mapper.readValue(body, new TypeReference<List<PlanDetailJson>>() {});
-    }
-
-    //
-    // HTTP CLIENT HELPERS
-    //
-    protected Response doPost(final String uri, @Nullable final String body, final Map<String, String> queryParams, final int timeoutSec) {
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("POST", getUrlFromUri(uri), queryParams);
-        if (body != null) {
-            builder.setBody(body);
-        } else {
-            builder.setBody("{}");
-        }
-        return executeAndWait(builder, timeoutSec, true);
-    }
-
-    protected Response doPut(final String uri, final String body, final Map<String, String> queryParams, final int timeoutSec) {
-        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("PUT", url, queryParams);
-        if (body != null) {
-            builder.setBody(body);
-        } else {
-            builder.setBody("{}");
-        }
-        return executeAndWait(builder, timeoutSec, true);
-    }
-
-    protected Response doDelete(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
-        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("DELETE", url, queryParams);
-        return executeAndWait(builder, timeoutSec, true);
-    }
-
-    protected Response doGet(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
-        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-        return doGetWithUrl(url, queryParams, timeoutSec);
-    }
-
-    protected Response doHead(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
-        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-        return doHeadWithUrl(url, queryParams, timeoutSec);
-    }
-
-    protected Response doOptions(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
-        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-        return doOptionsWithUrl(url, queryParams, timeoutSec);
-    }
-
-    protected Response doGetWithUrl(final String url, final Map<String, String> queryParams, final int timeoutSec) {
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("GET", url, queryParams);
-        return executeAndWait(builder, timeoutSec, false);
-    }
-
-    protected Response doHeadWithUrl(final String url, final Map<String, String> queryParams, final int timeoutSec) {
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("HEAD", url, queryParams);
-        return executeAndWait(builder, timeoutSec, false);
-    }
-
-    protected Response doOptionsWithUrl(final String url, final Map<String, String> queryParams, final int timeoutSec) {
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("OPTIONS", url, queryParams);
-        return executeAndWait(builder, timeoutSec, false);
-    }
-
-    protected Response executeAndWait(final BoundRequestBuilder builder, final int timeoutSec, final boolean addContextHeader) {
-
-        if (addContextHeader) {
-            builder.addHeader(JaxrsResource.HDR_CREATED_BY, createdBy);
-            builder.addHeader(JaxrsResource.HDR_REASON, reason);
-            builder.addHeader(JaxrsResource.HDR_COMMENT, comment);
-        }
-
-        if (username != null && password != null) {
-            final Realm realm = new Realm.RealmBuilder()
-                    .setPrincipal(username)
-                    .setPassword(password)
-                    .setUsePreemptiveAuth(true)
-                    .setScheme(AuthScheme.BASIC)
-                    .build();
-            builder.setRealm(realm);
-        }
-
-        Response response = null;
-        try {
-            final ListenableFuture<Response> futureStatus =
-                    builder.execute(new AsyncCompletionHandler<Response>() {
-                        @Override
-                        public Response onCompleted(final Response response) throws Exception {
-                            return response;
-                        }
-                    });
-            response = futureStatus.get(timeoutSec, TimeUnit.SECONDS);
-        } catch (final Exception e) {
-            Assert.fail(e.getMessage());
-        }
-        Assert.assertNotNull(response);
-        return response;
-    }
-
-    protected String getUrlFromUri(final String uri) {
-        return String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
-    }
-
-    protected BoundRequestBuilder getBuilderWithHeaderAndQuery(final String verb, final String url, final Map<String, String> queryParams) {
-        BoundRequestBuilder builder = null;
-        if (verb.equals("GET")) {
-            builder = httpClient.prepareGet(url);
-        } else if (verb.equals("POST")) {
-            builder = httpClient.preparePost(url);
-        } else if (verb.equals("PUT")) {
-            builder = httpClient.preparePut(url);
-        } else if (verb.equals("DELETE")) {
-            builder = httpClient.prepareDelete(url);
-        } else if (verb.equals("HEAD")) {
-            builder = httpClient.prepareHead(url);
-        } else if (verb.equals("OPTIONS")) {
-            builder = httpClient.prepareOptions(url);
-        } else {
-            Assert.fail("Unknown verb " + verb);
-        }
-
-        builder.addHeader(HEADER_CONTENT_TYPE, CONTENT_TYPE);
-        builder.addHeader(HDR_API_KEY, apiKey);
-        builder.addHeader(HDR_API_SECRET, apiSecret);
-        for (final Entry<String, String> q : queryParams.entrySet()) {
-            builder.addQueryParameter(q.getKey(), q.getValue());
-        }
-
-        return builder;
-    }
-
-    protected AccountJson getAccountJson() {
-        return getAccountJson(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString().substring(0, 5) + '@' + UUID.randomUUID().toString().substring(0, 5));
+    protected Account getAccount() {
+        return getAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString().substring(0, 5) + '@' + UUID.randomUUID().toString().substring(0, 5));
     }
 
-    public AccountJson getAccountJson(final String name, final String externalKey, final String email) {
-        final String accountId = UUID.randomUUID().toString();
+    public Account getAccount(final String name, final String externalKey, final String email) {
+        final UUID accountId = UUID.randomUUID();
         final int length = 4;
         final String currency = DEFAULT_CURRENCY;
         final String timeZone = "UTC";
@@ -1111,8 +159,8 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
         final String phone = "81 53 26 56";
 
         // Note: the accountId payload is ignored on account creation
-        return new AccountJson(accountId, name, length, externalKey, email, null, currency, null, timeZone,
-                               address1, address2, postalCode, company, city, state, country, locale, phone, false, false, null, null);
+        return new Account(accountId, name, length, externalKey, email, null, currency, null, timeZone,
+                           address1, address2, postalCode, company, city, state, country, locale, phone, false, false, null, null);
     }
 
     /**
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
index 385745d..ccefafe 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
@@ -17,279 +17,199 @@
 package com.ning.billing.jaxrs;
 
 import java.math.BigDecimal;
-import java.util.HashMap;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
-import javax.ws.rs.core.Response.Status;
 
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.AuditLogJson;
-import com.ning.billing.jaxrs.json.CustomFieldJson;
-import com.ning.billing.jaxrs.json.PaymentJson;
-import com.ning.billing.jaxrs.json.PaymentMethodJson;
-import com.ning.billing.jaxrs.json.RefundJson;
-import com.ning.billing.jaxrs.json.TagJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.billing.client.KillBillClientException;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.AuditLog;
+import com.ning.billing.client.model.CustomField;
+import com.ning.billing.client.model.Payment;
+import com.ning.billing.client.model.PaymentMethod;
+import com.ning.billing.client.model.PaymentMethodPluginDetail;
+import com.ning.billing.client.model.Refund;
+import com.ning.billing.client.model.Tag;
 import com.ning.billing.util.api.AuditLevel;
-import com.ning.billing.util.customfield.dao.CustomFieldDao;
-import com.ning.http.client.Response;
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.google.common.collect.ImmutableMap;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 public class TestAccount extends TestJaxrsBase {
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create, retrieve, search and update accounts")
     public void testAccountOk() throws Exception {
-        final AccountJson input = createAccount();
+        final Account input = createAccount();
 
         // Retrieves by external key
-        final AccountJson retrievedAccount = getAccountByExternalKey(input.getExternalKey());
+        final Account retrievedAccount = killBillClient.getAccount(input.getExternalKey());
         Assert.assertTrue(retrievedAccount.equals(input));
 
         // Try search endpoint
         searchAccount(input, retrievedAccount);
 
         // Update Account
-        final AccountJson newInput = new AccountJson(input.getAccountId(),
-                                                     "zozo", 4, input.getExternalKey(), "rr@google.com", 18,
-                                                     "USD", null, "UTC", "bl1", "bh2", "", "", "ca", "San Francisco", "usa", "en", "415-255-2991",
-                                                     false, false, null, null);
-        final AccountJson updatedAccount = updateAccount(input.getAccountId(), newInput);
+        final Account newInput = new Account(input.getAccountId(),
+                                             "zozo", 4, input.getExternalKey(), "rr@google.com", 18,
+                                             "USD", null, "UTC", "bl1", "bh2", "", "", "ca", "San Francisco", "usa", "en", "415-255-2991",
+                                             false, false, null, null);
+        final Account updatedAccount = killBillClient.updateAccount(newInput, createdBy, reason, comment);
         Assert.assertTrue(updatedAccount.equals(newInput));
 
         // Try search endpoint
         searchAccount(input, null);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can retrieve the account balance")
     public void testAccountWithBalance() throws Exception {
-        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
-
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId();
-        final Map<String, String> queryParams = ImmutableMap.<String, String>of(JaxrsResource.QUERY_ACCOUNT_WITH_BALANCE, "true");
-        final Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final AccountJson accountWithBalance = mapper.readValue(baseJson, AccountJson.class);
+        final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+
+        final Account accountWithBalance = killBillClient.getAccount(accountJson.getAccountId(), true, false);
         final BigDecimal accountBalance = accountWithBalance.getAccountBalance();
         Assert.assertTrue(accountBalance.compareTo(BigDecimal.ZERO) > 0);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Cannot update a non-existent account")
     public void testUpdateNonExistentAccount() throws Exception {
-        final AccountJson input = getAccountJson();
+        final Account input = getAccount();
 
-        final String baseJson = mapper.writeValueAsString(input);
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId();
-        final Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
+        Assert.assertNull(killBillClient.updateAccount(input, createdBy, reason, comment));
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Cannot retrieve non-existent account")
     public void testAccountNonExistent() throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
+        Assert.assertNull(killBillClient.getAccount(UUID.randomUUID()));
+        Assert.assertNull(killBillClient.getAccount(UUID.randomUUID().toString()));
     }
 
-    @Test(groups = "slow")
-    public void testAccountBadAccountId() throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/yo";
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
-    }
-
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can CRUD payment methods")
     public void testAccountPaymentMethods() throws Exception {
-
-        final AccountJson accountJson = createAccount("qwerty", "ytrewq", "qwerty@yahoo.com");
+        final Account accountJson = createAccount();
         assertNotNull(accountJson);
 
-        String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
-        PaymentMethodJson paymentMethodJson = getPaymentMethodJson(accountJson.getAccountId(), getPaymentMethodCCProperties());
-        String baseJson = mapper.writeValueAsString(paymentMethodJson);
-        Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_PAYMENT_METHOD_IS_DEFAULT, "true");
-
-        Response response = doPost(uri, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String locationCC = response.getHeader("Location");
-        Assert.assertNotNull(locationCC);
+        final PaymentMethodPluginDetail info = new PaymentMethodPluginDetail();
+        info.setProperties(getPaymentMethodCCProperties());
+        PaymentMethod paymentMethodJson = new PaymentMethod(null, accountJson.getAccountId(), true, PLUGIN_NAME, info);
+        final PaymentMethod paymentMethodCC = killBillClient.createPaymentMethod(paymentMethodJson, createdBy, reason, comment);
+        assertTrue(paymentMethodCC.getIsDefault());
 
-        // Retrieves by Id based on Location returned
-        response = doGetWithUrl(locationCC, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        final PaymentMethodJson paymentMethodCC = mapper.readValue(baseJson, PaymentMethodJson.class);
-        assertTrue(paymentMethodCC.isDefault());
         //
         // Add another payment method
         //
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
-        paymentMethodJson = getPaymentMethodJson(accountJson.getAccountId(), getPaymentMethodPaypalProperties());
-        baseJson = mapper.writeValueAsString(paymentMethodJson);
-
-        response = doPost(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String locationPP = response.getHeader("Location");
-        assertNotNull(locationPP);
-        response = doGetWithUrl(locationPP, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        final PaymentMethodJson paymentMethodPP = mapper.readValue(baseJson, PaymentMethodJson.class);
-        assertFalse(paymentMethodPP.isDefault());
+        final PaymentMethodPluginDetail info2 = new PaymentMethodPluginDetail();
+        info2.setProperties(getPaymentMethodPaypalProperties());
+        paymentMethodJson = new PaymentMethod(null, accountJson.getAccountId(), false, PLUGIN_NAME, info2);
+        final PaymentMethod paymentMethodPP = killBillClient.createPaymentMethod(paymentMethodJson, createdBy, reason, comment);
+        assertFalse(paymentMethodPP.getIsDefault());
 
         //
         // FETCH ALL PAYMENT METHODS
         //
-        queryParams = new HashMap<String, String>();
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        List<PaymentMethodJson> paymentMethods = mapper.readValue(baseJson, new TypeReference<List<PaymentMethodJson>>() {});
+        List<PaymentMethod> paymentMethods = killBillClient.getPaymentMethodsForAccount(accountJson.getAccountId());
         assertEquals(paymentMethods.size(), 2);
 
         //
         // CHANGE DEFAULT
         //
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS + "/" + paymentMethodPP.getPaymentMethodId() + "/" + JaxrsResource.PAYMENT_METHODS_DEFAULT_PATH_POSTFIX;
-        response = doPut(uri, "{}", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        response = doGetWithUrl(locationPP, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        final PaymentMethodJson paymentMethodPPDefault = mapper.readValue(baseJson, PaymentMethodJson.class);
-        assertTrue(paymentMethodPPDefault.isDefault());
+        assertTrue(killBillClient.getPaymentMethod(paymentMethodCC.getPaymentMethodId()).getIsDefault());
+        assertFalse(killBillClient.getPaymentMethod(paymentMethodPP.getPaymentMethodId()).getIsDefault());
+        killBillClient.updateDefaultPaymentMethod(accountJson.getAccountId(), paymentMethodPP.getPaymentMethodId(), createdBy, reason, comment);
+        assertTrue(killBillClient.getPaymentMethod(paymentMethodPP.getPaymentMethodId()).getIsDefault());
+        assertFalse(killBillClient.getPaymentMethod(paymentMethodCC.getPaymentMethodId()).getIsDefault());
 
         //
         // DELETE NON DEFAULT PM
         //
-        uri = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodCC.getPaymentMethodId();
-        response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        killBillClient.deletePaymentMethod(paymentMethodCC.getPaymentMethodId(), false, createdBy, reason, comment);
 
         //
         // FETCH ALL PAYMENT METHODS
         //
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
-        queryParams = new HashMap<String, String>();
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        paymentMethods = mapper.readValue(baseJson, new TypeReference<List<PaymentMethodJson>>() {});
+        paymentMethods = killBillClient.getPaymentMethodsForAccount(accountJson.getAccountId());
         assertEquals(paymentMethods.size(), 1);
 
         //
         // DELETE DEFAULT PAYMENT METHOD (without special flag first)
         //
-        uri = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodPP.getPaymentMethodId();
-        response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.BAD_REQUEST.getStatusCode());
+        try {
+            killBillClient.deletePaymentMethod(paymentMethodPP.getPaymentMethodId(), false, createdBy, reason, comment);
+            fail();
+        } catch (final KillBillClientException e) {
+        }
 
         //
         // RETRY TO DELETE DEFAULT PAYMENT METHOD (with special flag this time)
         //
-        uri = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodPP.getPaymentMethodId();
-        queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_DELETE_DEFAULT_PM_WITH_AUTO_PAY_OFF, "true");
-
-        response = doDelete(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        killBillClient.deletePaymentMethod(paymentMethodPP.getPaymentMethodId(), true, createdBy, reason, comment);
 
         // CHECK ACCOUNT IS NOW AUTO_PAY_OFF
-
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.TAGS;
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        baseJson = response.getResponseBody();
-        List<TagJson> tagsJson = mapper.readValue(baseJson, new TypeReference<List<TagJson>>() {});
+        final List<Tag> tagsJson = killBillClient.getAccountTags(accountJson.getAccountId());
         Assert.assertEquals(tagsJson.size(), 1);
-        TagJson tagJson = tagsJson.get(0);
+        final Tag tagJson = tagsJson.get(0);
         Assert.assertEquals(tagJson.getTagDefinitionName(), "AUTO_PAY_OFF");
-        Assert.assertEquals(tagJson.getTagDefinitionId(), new UUID(0, 1).toString());
+        Assert.assertEquals(tagJson.getTagDefinitionId(), new UUID(0, 1));
 
         // FETCH ACCOUNT AGAIN AND CHECK THERE IS NO DEFAULT PAYMENT METHOD SET
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId();
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        AccountJson updatedAccountJson = mapper.readValue(response.getResponseBody(), AccountJson.class);
-        Assert.assertEquals(updatedAccountJson.getAccountId(), accountJson.getAccountId());
-        Assert.assertNull(updatedAccountJson.getPaymentMethodId());
+        final Account updatedAccount = killBillClient.getAccount(accountJson.getAccountId());
+        Assert.assertEquals(updatedAccount.getAccountId(), accountJson.getAccountId());
+        Assert.assertNull(updatedAccount.getPaymentMethodId());
 
         //
         // FINALLY TRY TO REMOVE AUTO_PAY_OFF WITH NO DEFAULT PAYMENT METHOD ON ACCOUNT
         //
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.TAGS;
-        queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_TAGS, new UUID(0, 1).toString());
-        response = doDelete(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.BAD_REQUEST.getStatusCode());
-
+        try {
+            killBillClient.deleteAccountTag(accountJson.getAccountId(), new UUID(0, 1), createdBy, reason, comment);
+        } catch (final KillBillClientException e) {
+        }
     }
 
     @Test(groups = "slow")
     public void testAccountPaymentsWithRefund() throws Exception {
-        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Verify payments
-        final List<PaymentJson> objFromJson = getPaymentsForAccount(accountJson.getAccountId());
+        final List<Payment> objFromJson = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
         Assert.assertEquals(objFromJson.size(), 1);
 
         // Verify refunds
-        final List<RefundJson> objRefundFromJson = getRefundsForAccount(accountJson.getAccountId());
+        final List<Refund> objRefundFromJson = killBillClient.getRefundsForAccount(accountJson.getAccountId());
         Assert.assertEquals(objRefundFromJson.size(), 0);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Add tags to account")
     public void testTags() throws Exception {
-        final AccountJson input = createAccount();
-        final String accountId = input.getAccountId();
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.TAGS;
-        final String accountTagsUrl = getUrlFromUri(uri);
+        final Account input = createAccount();
         // Use tag definition for AUTO_PAY_OFF
-        final String autoPayOffId = new UUID(0, 1).toString();
+        final UUID autoPayOffId = new UUID(0, 1);
 
         // Add a tag
-        Response response = doPost(uri, null, ImmutableMap.<String, String>of(JaxrsResource.QUERY_TAGS, autoPayOffId), DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+        killBillClient.createAccountTag(input.getAccountId(), autoPayOffId, createdBy, reason, comment);
 
         // Retrieves all tags
-        response = doGetWithUrl(accountTagsUrl, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final List<TagJson> tags1 = mapper.readValue(response.getResponseBody(), new TypeReference<List<TagJson>>() {});
+        final List<Tag> tags1 = killBillClient.getAccountTags(input.getAccountId(), AuditLevel.FULL);
         Assert.assertEquals(tags1.size(), 1);
         Assert.assertEquals(tags1.get(0).getTagDefinitionId(), autoPayOffId);
 
         // Verify adding the same tag a second time doesn't do anything
-        response = doPost(uri, null, ImmutableMap.<String, String>of(JaxrsResource.QUERY_TAGS, autoPayOffId), DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+        killBillClient.createAccountTag(input.getAccountId(), autoPayOffId, createdBy, reason, comment);
 
         // Retrieves all tags again
-        response = doGetWithUrl(accountTagsUrl, ImmutableMap.<String, String>of(JaxrsResource.QUERY_AUDIT, AuditLevel.FULL.toString()), DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final List<TagJson> tags2 = mapper.readValue(response.getResponseBody(), new TypeReference<List<TagJson>>() {});
+        killBillClient.createAccountTag(input.getAccountId(), autoPayOffId, createdBy, reason, comment);
+        final List<Tag> tags2 = killBillClient.getAccountTags(input.getAccountId(), AuditLevel.FULL);
         Assert.assertEquals(tags2, tags1);
 
         // Verify audit logs
         Assert.assertEquals(tags2.get(0).getAuditLogs().size(), 1);
-        final AuditLogJson auditLogJson = tags2.get(0).getAuditLogs().get(0);
+        final AuditLog auditLogJson = tags2.get(0).getAuditLogs().get(0);
         Assert.assertEquals(auditLogJson.getChangeType(), "INSERT");
         Assert.assertEquals(auditLogJson.getChangedBy(), createdBy);
         Assert.assertEquals(auditLogJson.getReasonCode(), reason);
@@ -298,42 +218,32 @@ public class TestAccount extends TestJaxrsBase {
         Assert.assertNotNull(auditLogJson.getUserToken());
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Add custom fields to account")
     public void testCustomFields() throws Exception {
-        final AccountJson accountJson = createAccount("yoyoq", "gfgrqe", "yoyoq@yahoo.com");
+        final Account accountJson = createAccount();
         assertNotNull(accountJson);
 
-        final List<CustomFieldJson> customFields = new LinkedList<CustomFieldJson>();
-        customFields.add(new CustomFieldJson("1", "value1", null));
-        customFields.add(new CustomFieldJson("2", "value2", null));
-        customFields.add(new CustomFieldJson("3", "value3", null));
-        String baseJson = mapper.writeValueAsString(customFields);
+        final Collection<CustomField> customFields = new LinkedList<CustomField>();
+        customFields.add(new CustomField("1", "value1", null));
+        customFields.add(new CustomField("2", "value2", null));
+        customFields.add(new CustomField("3", "value3", null));
 
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.CUSTOM_FIELDS;
-        Response response = doPost(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+        killBillClient.createAccountCustomFields(accountJson.getAccountId(), customFields, createdBy, reason, comment);
 
-        // Retrieves by Id based on Location returned
-        final String url = getUrlFromUri(uri);
-        response = doGetWithUrl(url, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final List<CustomField> accountCustomFields = killBillClient.getAccountCustomFields(accountJson.getAccountId());
+        assertEquals(accountCustomFields.size(), 3);
 
         // Delete all custom fields for account
-        response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        killBillClient.deleteAccountCustomFields(accountJson.getAccountId(), createdBy, reason, comment);
 
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        final List<CustomFieldDao> remainingCustomFields = mapper.readValue(baseJson, new TypeReference<List<CustomFieldDao>>() {});
+        final List<CustomField> remainingCustomFields = killBillClient.getAccountCustomFields(accountJson.getAccountId());
         assertEquals(remainingCustomFields.size(), 0);
-
     }
 
-    private void searchAccount(final AccountJson input, @Nullable final AccountJson output) throws Exception {
+    private void searchAccount(final Account input, @Nullable final Account output) throws Exception {
         // Search by id
         if (output != null) {
-            doSearchAccount(input.getAccountId(), output);
+            doSearchAccount(input.getAccountId().toString(), output);
         }
 
         // Search by name
@@ -347,14 +257,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<AccountJson> accountsByExternalKey = searchAccountsByKey(input.getExternalKey());
+        final List<Account> accountsByExternalKey = killBillClient.searchAccounts(input.getExternalKey());
         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 AccountJson output) throws Exception {
-        final List<AccountJson> accountsByKey = searchAccountsByKey(key);
+    private void doSearchAccount(final String key, @Nullable final Account output) throws Exception {
+        final List<Account> accountsByKey = killBillClient.searchAccounts(key);
         if (output == null) {
             Assert.assertEquals(accountsByKey.size(), 0);
         } else {
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmail.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmail.java
index 30c98d0..7c808fd 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmail.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmail.java
@@ -22,39 +22,39 @@ import java.util.UUID;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.json.AccountEmailJson;
-import com.ning.billing.jaxrs.json.AccountJson;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.AccountEmail;
 
 public class TestAccountEmail extends TestJaxrsBase {
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create and delete account emails")
     public void testAddAndRemoveAccountEmail() throws Exception {
-        final AccountJson input = createAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString());
-        final String accountId = input.getAccountId();
+        final Account input = createAccount();
+        final UUID accountId = input.getAccountId();
 
         final String email1 = UUID.randomUUID().toString();
         final String email2 = UUID.randomUUID().toString();
-        final AccountEmailJson accountEmailJson1 = new AccountEmailJson(accountId, email1);
-        final AccountEmailJson accountEmailJson2 = new AccountEmailJson(accountId, email2);
+        final AccountEmail accountEmailJson1 = new AccountEmail(accountId, email1);
+        final AccountEmail accountEmailJson2 = new AccountEmail(accountId, email2);
 
         // Verify the initial state
-        final List<AccountEmailJson> firstEmails = getEmailsForAccount(accountId);
+        final List<AccountEmail> firstEmails = killBillClient.getEmailsForAccount(accountId);
         Assert.assertEquals(firstEmails.size(), 0);
 
         // Add an email
-        addEmailToAccount(accountId, accountEmailJson1);
+        killBillClient.addEmailToAccount(accountEmailJson1, createdBy, reason, comment);
 
         // Verify we can retrieve it
-        final List<AccountEmailJson> secondEmails = getEmailsForAccount(accountId);
+        final List<AccountEmail> secondEmails = killBillClient.getEmailsForAccount(accountId);
         Assert.assertEquals(secondEmails.size(), 1);
         Assert.assertEquals(secondEmails.get(0).getAccountId(), accountId);
         Assert.assertEquals(secondEmails.get(0).getEmail(), email1);
 
         // Add another email
-        addEmailToAccount(accountId, accountEmailJson2);
+        killBillClient.addEmailToAccount(accountEmailJson2, createdBy, reason, comment);
 
         // Verify we can retrieve both
-        final List<AccountEmailJson> thirdEmails = getEmailsForAccount(accountId);
+        final List<AccountEmail> thirdEmails = killBillClient.getEmailsForAccount(accountId);
         Assert.assertEquals(thirdEmails.size(), 2);
         Assert.assertEquals(thirdEmails.get(0).getAccountId(), accountId);
         Assert.assertEquals(thirdEmails.get(1).getAccountId(), accountId);
@@ -62,16 +62,16 @@ public class TestAccountEmail extends TestJaxrsBase {
         Assert.assertTrue(thirdEmails.get(1).getEmail().equals(email1) || thirdEmails.get(1).getEmail().equals(email2));
 
         // Delete the first email
-        removeEmailFromAccount(accountId, email1);
+        killBillClient.removeEmailFromAccount(accountEmailJson1, createdBy, reason, comment);
 
         // Verify it has been deleted
-        final List<AccountEmailJson> fourthEmails = getEmailsForAccount(accountId);
+        final List<AccountEmail> fourthEmails = killBillClient.getEmailsForAccount(accountId);
         Assert.assertEquals(fourthEmails.size(), 1);
         Assert.assertEquals(fourthEmails.get(0).getAccountId(), accountId);
         Assert.assertEquals(fourthEmails.get(0).getEmail(), email2);
 
-        // Try to add the same email -- that works because we removed the unique constraints for soft deletion.
-        // addEmailToAccount(accountId, accountEmailJson2);
-        Assert.assertEquals(getEmailsForAccount(accountId), fourthEmails);
+        // Try to add the same email
+        killBillClient.addEmailToAccount(accountEmailJson2, createdBy, reason, comment);
+        Assert.assertEquals(killBillClient.getEmailsForAccount(accountId), fourthEmails);
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmailNotifications.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmailNotifications.java
index 112891e..1b1dbad 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmailNotifications.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmailNotifications.java
@@ -21,53 +21,37 @@ import java.util.UUID;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.core.type.TypeReference;
-
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.InvoiceEmailJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.http.client.Response;
-
-import static org.testng.Assert.assertEquals;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.InvoiceEmail;
 
 public class TestAccountEmailNotifications extends TestJaxrsBase {
-    @Test(groups = "slow")
+
+    @Test(groups = "slow", description = "Can toggle email notifications")
     public void testSetAndUnsetEmailNotifications() throws Exception {
-        final AccountJson input = createAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString());
-        final String accountId = input.getAccountId();
+        final Account input = createAccount();
+        final UUID accountId = input.getAccountId();
 
-        final InvoiceEmailJson invoiceEmailJsonWithNotifications = new InvoiceEmailJson(accountId, true);
-        final InvoiceEmailJson invoiceEmailJsonWithoutNotifications = new InvoiceEmailJson(accountId, false);
-        final String baseUri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAIL_NOTIFICATIONS;
+        final InvoiceEmail invoiceEmailJsonWithNotifications = new InvoiceEmail(accountId, true);
+        final InvoiceEmail invoiceEmailJsonWithoutNotifications = new InvoiceEmail(accountId, false);
 
         // Verify the initial state
-        final Response firstResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(firstResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-        final InvoiceEmailJson firstInvoiceEmailJson = mapper.readValue(firstResponse.getResponseBody(), new TypeReference<InvoiceEmailJson>() {});
+        final InvoiceEmail firstInvoiceEmailJson = killBillClient.getEmailNotificationsForAccount(accountId);
         Assert.assertEquals(firstInvoiceEmailJson.getAccountId(), accountId);
         Assert.assertFalse(firstInvoiceEmailJson.isNotifiedForInvoices());
 
         // Enable email notifications
-        final String firstEmailString = mapper.writeValueAsString(invoiceEmailJsonWithNotifications);
-        final Response secondResponse = doPut(baseUri, firstEmailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(secondResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        killBillClient.updateEmailNotificationsForAccount(invoiceEmailJsonWithNotifications, createdBy, reason, comment);
 
         // Verify we can retrieve it
-        final Response thirdResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(thirdResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-        final InvoiceEmailJson secondInvoiceEmailJson = mapper.readValue(thirdResponse.getResponseBody(), new TypeReference<InvoiceEmailJson>() {});
+        final InvoiceEmail secondInvoiceEmailJson = killBillClient.getEmailNotificationsForAccount(accountId);
         Assert.assertEquals(secondInvoiceEmailJson.getAccountId(), accountId);
         Assert.assertTrue(secondInvoiceEmailJson.isNotifiedForInvoices());
 
         // Disable email notifications
-        final String secondEmailString = mapper.writeValueAsString(invoiceEmailJsonWithoutNotifications);
-        final Response fourthResponse = doPut(baseUri, secondEmailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(fourthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        killBillClient.updateEmailNotificationsForAccount(invoiceEmailJsonWithoutNotifications, createdBy, reason, comment);
 
         // Verify we can retrieve it
-        final Response fifthResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(fifthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-        final InvoiceEmailJson thirdInvoiceEmailJson = mapper.readValue(fifthResponse.getResponseBody(), new TypeReference<InvoiceEmailJson>() {});
+        final InvoiceEmail thirdInvoiceEmailJson = killBillClient.getEmailNotificationsForAccount(accountId);
         Assert.assertEquals(thirdInvoiceEmailJson.getAccountId(), accountId);
         Assert.assertFalse(thirdInvoiceEmailJson.isNotifiedForInvoices());
     }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccountTimeline.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccountTimeline.java
index 5d467ac..d4f031f 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccountTimeline.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccountTimeline.java
@@ -18,6 +18,7 @@ package com.ning.billing.jaxrs;
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.Nullable;
 
@@ -26,15 +27,15 @@ import org.joda.time.LocalDate;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.AccountTimelineJson;
-import com.ning.billing.jaxrs.json.AuditLogJson;
-import com.ning.billing.jaxrs.json.ChargebackJson;
-import com.ning.billing.jaxrs.json.CreditJson;
-import com.ning.billing.jaxrs.json.InvoiceJson;
-import com.ning.billing.jaxrs.json.PaymentJson;
-import com.ning.billing.jaxrs.json.RefundJson;
-import com.ning.billing.jaxrs.json.SubscriptionJson.EventSubscriptionJson;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.AccountTimeline;
+import com.ning.billing.client.model.AuditLog;
+import com.ning.billing.client.model.Chargeback;
+import com.ning.billing.client.model.Credit;
+import com.ning.billing.client.model.EventSubscription;
+import com.ning.billing.client.model.Invoice;
+import com.ning.billing.client.model.Payment;
+import com.ning.billing.client.model.Refund;
 import com.ning.billing.util.api.AuditLevel;
 import com.ning.billing.util.audit.ChangeType;
 
@@ -43,19 +44,19 @@ public class TestAccountTimeline extends TestJaxrsBase {
     private static final String PAYMENT_REQUEST_PROCESSOR = "PaymentRequestProcessor";
     private static final String TRANSITION = "SubscriptionBaseTransition";
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can retrieve the timeline without audits")
     public void testAccountTimeline() throws Exception {
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
-        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final AccountTimelineJson timeline = getAccountTimeline(accountJson.getAccountId());
+        final AccountTimeline timeline = killBillClient.getAccountTimeline(accountJson.getAccountId());
         Assert.assertEquals(timeline.getPayments().size(), 1);
         Assert.assertEquals(timeline.getInvoices().size(), 2);
         Assert.assertEquals(timeline.getBundles().size(), 1);
         Assert.assertEquals(timeline.getBundles().get(0).getSubscriptions().size(), 1);
         Assert.assertEquals(timeline.getBundles().get(0).getSubscriptions().get(0).getEvents().size(), 3);
-        final List<EventSubscriptionJson> events = timeline.getBundles().get(0).getSubscriptions().get(0).getEvents();
+        final List<EventSubscription> events = timeline.getBundles().get(0).getSubscriptions().get(0).getEvents();
         Assert.assertEquals(events.get(0).getEffectiveDate(), new LocalDate(2012, 4, 25));
         Assert.assertEquals(events.get(0).getEventType(), "START_ENTITLEMENT");
         Assert.assertEquals(events.get(1).getEffectiveDate(), new LocalDate(2012, 4, 25));
@@ -64,28 +65,35 @@ public class TestAccountTimeline extends TestJaxrsBase {
         Assert.assertEquals(events.get(2).getEventType(), "PHASE");
     }
 
-
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can retrieve the timeline with audits")
     public void testAccountTimelineWithAudits() throws Exception {
         final DateTime startTime = clock.getUTCNow();
-        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
         final DateTime endTime = clock.getUTCNow();
 
         // Add credit
-        final InvoiceJson invoice = getInvoicesForAccount(accountJson.getAccountId()).get(1);
-        final DateTime creditEffectiveDate = clock.getUTCNow();
+        final Invoice invoice = killBillClient.getInvoicesForAccount(accountJson.getAccountId()).get(1);
         final BigDecimal creditAmount = BigDecimal.ONE;
-        createCreditForInvoice(accountJson.getAccountId(), invoice.getInvoiceId(),
-                               creditAmount, clock.getUTCNow(), creditEffectiveDate);
+        final Credit credit = new Credit();
+        credit.setAccountId(accountJson.getAccountId());
+        credit.setInvoiceId(invoice.getInvoiceId());
+        credit.setCreditAmount(creditAmount);
+        killBillClient.createCredit(credit, createdBy, reason, comment);
 
         // Add refund
-        final PaymentJson postedPayment = getPaymentsForAccount(accountJson.getAccountId()).get(0);
+        final Payment postedPayment = killBillClient.getPaymentsForAccount(accountJson.getAccountId()).get(0);
         final BigDecimal refundAmount = BigDecimal.ONE;
-        createRefund(postedPayment.getPaymentId(), refundAmount);
+        final Refund refund = new Refund();
+        refund.setPaymentId(postedPayment.getPaymentId());
+        refund.setAmount(refundAmount);
+        killBillClient.createRefund(refund, createdBy, reason, comment);
 
         // Add chargeback
         final BigDecimal chargebackAmount = BigDecimal.ONE;
-        createChargeBack(postedPayment.getPaymentId(), chargebackAmount);
+        final Chargeback chargeback = new Chargeback();
+        chargeback.setPaymentId(postedPayment.getPaymentId());
+        chargeback.setAmount(chargebackAmount);
+        killBillClient.createChargeBack(chargeback, createdBy, reason, comment);
 
         // Verify payments
         verifyPayments(accountJson.getAccountId(), startTime, endTime, refundAmount, chargebackAmount);
@@ -100,31 +108,31 @@ public class TestAccountTimeline extends TestJaxrsBase {
         verifyBundles(accountJson.getAccountId(), startTime, endTime);
     }
 
-    private void verifyPayments(final String accountId, final DateTime startTime, final DateTime endTime,
+    private void verifyPayments(final UUID accountId, final DateTime startTime, final DateTime endTime,
                                 final BigDecimal refundAmount, final BigDecimal chargebackAmount) throws Exception {
         for (final AuditLevel auditLevel : AuditLevel.values()) {
-            final AccountTimelineJson timeline = getAccountTimelineWithAudits(accountId, auditLevel);
+            final AccountTimeline timeline = killBillClient.getAccountTimeline(accountId, auditLevel);
 
             // Verify payments
             Assert.assertEquals(timeline.getPayments().size(), 1);
-            final PaymentJson paymentJson = timeline.getPayments().get(0);
+            final Payment paymentJson = timeline.getPayments().get(0);
 
             // Verify refunds
             Assert.assertEquals(paymentJson.getRefunds().size(), 1);
-            final RefundJson refundJson = paymentJson.getRefunds().get(0);
+            final Refund refundJson = paymentJson.getRefunds().get(0);
             Assert.assertEquals(refundJson.getPaymentId(), paymentJson.getPaymentId());
             Assert.assertEquals(refundJson.getAmount().compareTo(refundAmount), 0);
 
             // Verify chargebacks
             Assert.assertEquals(paymentJson.getChargebacks().size(), 1);
-            final ChargebackJson chargebackJson = paymentJson.getChargebacks().get(0);
+            final Chargeback chargebackJson = paymentJson.getChargebacks().get(0);
             Assert.assertEquals(chargebackJson.getPaymentId(), paymentJson.getPaymentId());
             Assert.assertEquals(chargebackJson.getAmount().compareTo(chargebackAmount), 0);
 
             // Verify audits
-            final List<AuditLogJson> paymentAuditLogs = paymentJson.getAuditLogs();
-            final List<AuditLogJson> refundAuditLogs = refundJson.getAuditLogs();
-            final List<AuditLogJson> chargebackAuditLogs = chargebackJson.getAuditLogs();
+            final List<AuditLog> paymentAuditLogs = paymentJson.getAuditLogs();
+            final List<AuditLog> refundAuditLogs = refundJson.getAuditLogs();
+            final List<AuditLog> chargebackAuditLogs = chargebackJson.getAuditLogs();
             if (AuditLevel.NONE.equals(auditLevel)) {
                 // Audits for payments
                 Assert.assertEquals(paymentAuditLogs.size(), 0);
@@ -165,16 +173,16 @@ public class TestAccountTimeline extends TestJaxrsBase {
         }
     }
 
-    private void verifyInvoices(final String accountId, final DateTime startTime, final DateTime endTime) throws Exception {
+    private void verifyInvoices(final UUID accountId, final DateTime startTime, final DateTime endTime) throws Exception {
         for (final AuditLevel auditLevel : AuditLevel.values()) {
-            final AccountTimelineJson timeline = getAccountTimelineWithAudits(accountId, auditLevel);
+            final AccountTimeline timeline = killBillClient.getAccountTimeline(accountId, auditLevel);
 
             // Verify invoices
             Assert.assertEquals(timeline.getInvoices().size(), 2);
 
             // Verify audits
-            final List<AuditLogJson> firstInvoiceAuditLogs = timeline.getInvoices().get(0).getAuditLogs();
-            final List<AuditLogJson> secondInvoiceAuditLogs = timeline.getInvoices().get(1).getAuditLogs();
+            final List<AuditLog> firstInvoiceAuditLogs = timeline.getInvoices().get(0).getAuditLogs();
+            final List<AuditLog> secondInvoiceAuditLogs = timeline.getInvoices().get(1).getAuditLogs();
             if (AuditLevel.NONE.equals(auditLevel)) {
                 Assert.assertEquals(firstInvoiceAuditLogs.size(), 0);
                 Assert.assertEquals(secondInvoiceAuditLogs.size(), 0);
@@ -187,17 +195,17 @@ public class TestAccountTimeline extends TestJaxrsBase {
         }
     }
 
-    private void verifyCredits(final String accountId, final DateTime startTime, final DateTime endTime, final BigDecimal creditAmount) throws Exception {
+    private void verifyCredits(final UUID accountId, final DateTime startTime, final DateTime endTime, final BigDecimal creditAmount) throws Exception {
         for (final AuditLevel auditLevel : AuditLevel.values()) {
-            final AccountTimelineJson timeline = getAccountTimelineWithAudits(accountId, auditLevel);
+            final AccountTimeline timeline = killBillClient.getAccountTimeline(accountId, auditLevel);
 
             // Verify credits
-            final List<CreditJson> credits = timeline.getInvoices().get(1).getCredits();
+            final List<Credit> credits = timeline.getInvoices().get(1).getCredits();
             Assert.assertEquals(credits.size(), 1);
             Assert.assertEquals(credits.get(0).getCreditAmount().compareTo(creditAmount.negate()), 0);
 
             // Verify audits
-            final List<AuditLogJson> creditAuditLogs = credits.get(0).getAuditLogs();
+            final List<AuditLog> creditAuditLogs = credits.get(0).getAuditLogs();
             if (AuditLevel.NONE.equals(auditLevel)) {
                 Assert.assertEquals(creditAuditLogs.size(), 0);
             } else {
@@ -207,9 +215,9 @@ public class TestAccountTimeline extends TestJaxrsBase {
         }
     }
 
-    private void verifyBundles(final String accountId, final DateTime startTime, final DateTime endTime) throws Exception {
+    private void verifyBundles(final UUID accountId, final DateTime startTime, final DateTime endTime) throws Exception {
         for (final AuditLevel auditLevel : AuditLevel.values()) {
-            final AccountTimelineJson timeline = getAccountTimelineWithAudits(accountId, auditLevel);
+            final AccountTimeline timeline = killBillClient.getAccountTimeline(accountId, auditLevel);
 
             // Verify bundles
             Assert.assertEquals(timeline.getBundles().size(), 1);
@@ -217,10 +225,10 @@ public class TestAccountTimeline extends TestJaxrsBase {
             Assert.assertEquals(timeline.getBundles().get(0).getSubscriptions().get(0).getEvents().size(), 3);
 
             // Verify audits
-            final List<AuditLogJson> bundleAuditLogs = timeline.getBundles().get(0).getAuditLogs();
-            final List<AuditLogJson> subscriptionAuditLogs = timeline.getBundles().get(0).getSubscriptions().get(0).getAuditLogs();
-            final List<AuditLogJson> subscriptionEvent1AuditLogs = timeline.getBundles().get(0).getSubscriptions().get(0).getEvents().get(0).getAuditLogs();
-            final List<AuditLogJson> subscriptionEvent2AuditLogs = timeline.getBundles().get(0).getSubscriptions().get(0).getEvents().get(1).getAuditLogs();
+            final List<AuditLog> bundleAuditLogs = timeline.getBundles().get(0).getAuditLogs();
+            final List<AuditLog> subscriptionAuditLogs = timeline.getBundles().get(0).getSubscriptions().get(0).getAuditLogs();
+            final List<AuditLog> subscriptionEvent1AuditLogs = timeline.getBundles().get(0).getSubscriptions().get(0).getEvents().get(0).getAuditLogs();
+            final List<AuditLog> subscriptionEvent2AuditLogs = timeline.getBundles().get(0).getSubscriptions().get(0).getEvents().get(1).getAuditLogs();
             if (AuditLevel.NONE.equals(auditLevel)) {
                 // Audits for bundles
                 Assert.assertEquals(bundleAuditLogs.size(), 0);
@@ -267,7 +275,7 @@ public class TestAccountTimeline extends TestJaxrsBase {
         }
     }
 
-    private void verifyAuditLog(final AuditLogJson auditLogJson, final ChangeType changeType, @Nullable final String reasonCode,
+    private void verifyAuditLog(final AuditLog auditLogJson, final ChangeType changeType, @Nullable final String reasonCode,
                                 @Nullable final String comments, @Nullable final String changedBy,
                                 final DateTime startTime, final DateTime endTime) {
         Assert.assertEquals(auditLogJson.getChangeType(), changeType.toString());
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java b/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
index b99874d..5f90877 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestBundle.java
@@ -16,13 +16,8 @@
 
 package com.ning.billing.jaxrs;
 
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-
-import javax.ws.rs.core.Response.Status;
+import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.testng.Assert;
@@ -30,137 +25,78 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.BundleJson;
-import com.ning.billing.jaxrs.json.SubscriptionJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.http.client.Response;
-
-import com.fasterxml.jackson.core.type.TypeReference;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Bundle;
+import com.ning.billing.client.model.Subscription;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotEquals;
 
 public class TestBundle extends TestJaxrsBase {
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow", description = "Can retrieve bundles by external key")
     public void testBundleOk() throws Exception {
+        final Account accountJson = createAccount();
 
-        final AccountJson accountJson = createAccount("xlxl", "shdgfhkkl", "xlxl@yahoo.com");
+        createEntitlement(accountJson.getAccountId(), "123467", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, true);
 
-        createEntitlement(accountJson.getAccountId(), "123467", "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
         // Retrieves by external key
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "123467");
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.BUNDLES;
-        final Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<BundleJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<BundleJson>>() {});
+        final List<Bundle> objFromJson = killBillClient.getAccountBundles(accountJson.getAccountId(), "123467");
         Assert.assertEquals(objFromJson.size(), 1);
     }
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow", description = "Can retrieve account bundles")
     public void testBundleFromAccount() throws Exception {
+        final Account accountJson = createAccount();
+        createEntitlement(accountJson.getAccountId(), "156567", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, true);
+        createEntitlement(accountJson.getAccountId(), "265658", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, true);
 
-        final AccountJson accountJson = createAccount("xaxa", "saagfhkkl", "xaxa@yahoo.com");
-        createEntitlement(accountJson.getAccountId(), "156567", "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
-        createEntitlement(accountJson.getAccountId(), "265658", "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
-
-
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId().toString() + "/" + JaxrsResource.BUNDLES;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<BundleJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<BundleJson>>() {});
-
-        Collections.sort(objFromJson, new Comparator<BundleJson>() {
-            @Override
-            public int compare(final BundleJson o1, final BundleJson o2) {
-                return o1.getExternalKey().compareTo(o2.getExternalKey());
-            }
-        });
+        final List<Bundle> objFromJson = killBillClient.getAccountBundles(accountJson.getAccountId());
+        Assert.assertEquals(objFromJson.size(), 2);
     }
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow", description = "Can handle non existent bundle")
     public void testBundleNonExistent() throws Exception {
-        final AccountJson accountJson = createAccount("dfdf", "dfdfgfhkkl", "dfdf@yahoo.com");
-
-        String uri = JaxrsResource.BUNDLES_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
-        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
+        final Account accountJson = createAccount();
 
-        // Retrieves by external key
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "56566");
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.BUNDLES;
-        response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.BUNDLES;
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<BundleJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<BundleJson>>() {});
-        Assert.assertNotNull(objFromJson);
-        Assert.assertEquals(objFromJson.size(), 0);
+        Assert.assertNull(killBillClient.getBundle(UUID.randomUUID()));
+        Assert.assertTrue(killBillClient.getAccountBundles(accountJson.getAccountId(), "98374982743892").isEmpty());
+        Assert.assertTrue(killBillClient.getAccountBundles(accountJson.getAccountId()).isEmpty());
     }
 
-    @Test(groups = "slow", enabled = true)
-    public void testAppNonExistent() throws Exception {
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747/" + JaxrsResource.BUNDLES;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
+    @Test(groups = "slow", description = "Can handle non existent account")
+    public void testAccountNonExistent() throws Exception {
+        Assert.assertTrue(killBillClient.getAccountBundles(UUID.randomUUID()).isEmpty());
     }
 
-    @Test(groups = "slow", enabled = true)
+    @Test(groups = "slow", description = "Can transfer bundle")
     public void testBundleTransfer() throws Exception {
-
         final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
 
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("src", "src", "src@yahoo.com");
+        final Account accountJson = createAccountWithDefaultPaymentMethod();
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.MONTHLY;
+        final String bundleExternalKey = "93199";
 
-        final SubscriptionJson entitlementJsonNoEvents = createEntitlement(accountJson.getAccountId(), "93199", productName, ProductCategory.BASE.toString(), term.toString(), true);
-
+        final Subscription entitlementJsonNoEvents = createEntitlement(accountJson.getAccountId(), bundleExternalKey, productName,
+                                                                       ProductCategory.BASE, term, true);
 
-        Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "93199");
-        String uri = JaxrsResource.BUNDLES_PATH;
-        Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final BundleJson originalBundle = mapper.readValue(response.getResponseBody(), BundleJson.class);
+        final Bundle originalBundle = killBillClient.getBundle(bundleExternalKey);
         assertEquals(originalBundle.getAccountId(), accountJson.getAccountId());
-        assertEquals(originalBundle.getExternalKey(), "93199");
-
-
-        final AccountJson newAccount = createAccountWithDefaultPaymentMethod("dst", "dst", "dst@yahoo.com");
+        assertEquals(originalBundle.getExternalKey(), bundleExternalKey);
 
-        final BundleJson newBundleInput = new BundleJson(newAccount.getAccountId(), null, null, null, null);
-        final String newBundleInputJson = mapper.writeValueAsString(newBundleInput);
-        uri = JaxrsResource.BUNDLES_PATH + "/" + entitlementJsonNoEvents.getBundleId();
-        response = doPut(uri, newBundleInputJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+        final Account newAccount = createAccountWithDefaultPaymentMethod();
 
-        final String locationCC = response.getHeader("Location");
-        Assert.assertNotNull(locationCC);
-
-        response = doGetWithUrl(locationCC, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, "93199");
-        uri = JaxrsResource.BUNDLES_PATH;
-        response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final BundleJson newBundle = mapper.readValue(response.getResponseBody(), BundleJson.class);
+        final Bundle bundle = new Bundle();
+        bundle.setAccountId(newAccount.getAccountId());
+        bundle.setBundleId(entitlementJsonNoEvents.getBundleId());
+        assertEquals(killBillClient.transferBundle(bundle, createdBy, reason, comment).getAccountId(), newAccount.getAccountId());
 
+        final Bundle newBundle = killBillClient.getBundle(bundleExternalKey);
         assertNotEquals(newBundle.getBundleId(), originalBundle.getBundleId());
         assertEquals(newBundle.getExternalKey(), originalBundle.getExternalKey());
         assertEquals(newBundle.getAccountId(), newAccount.getAccountId());
-
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java b/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java
index 8291fb9..3484fdb 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestCatalog.java
@@ -23,19 +23,19 @@ import java.util.Set;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.json.CatalogJsonSimple;
-import com.ning.billing.jaxrs.json.CatalogJsonSimple.PlanJson;
-import com.ning.billing.jaxrs.json.CatalogJsonSimple.ProductJson;
-import com.ning.billing.jaxrs.json.PlanDetailJson;
+import com.ning.billing.client.model.Catalog;
+import com.ning.billing.client.model.Plan;
+import com.ning.billing.client.model.PlanDetail;
+import com.ning.billing.client.model.Product;
 
 public class TestCatalog extends TestJaxrsBase {
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can retrieve a simplified version of the catalog")
     public void testCatalogSimple() throws Exception {
         final Set<String> allBasePlans = new HashSet<String>();
 
-        final CatalogJsonSimple catalogJsonSimple = getSimpleCatalog();
-        for (final ProductJson productJson : catalogJsonSimple.getProducts()) {
+        final Catalog catalogJsonSimple = killBillClient.getSimpleCatalog();
+        for (final Product productJson : catalogJsonSimple.getProducts()) {
             if (!"BASE".equals(productJson.getType())) {
                 Assert.assertEquals(productJson.getIncluded().size(), 0);
                 Assert.assertEquals(productJson.getAvailable().size(), 0);
@@ -43,23 +43,23 @@ public class TestCatalog extends TestJaxrsBase {
             }
 
             // Save all plans for later (see below)
-            for (final PlanJson planJson : productJson.getPlans()) {
+            for (final Plan planJson : productJson.getPlans()) {
                 allBasePlans.add(planJson.getName());
             }
 
             // Retrieve available products (addons) for that base product
-            final List<PlanDetailJson> availableAddons = getAvailableAddons(productJson.getName());
+            final List<PlanDetail> availableAddons = killBillClient.getAvailableAddons(productJson.getName());
             final Set<String> availableAddonsNames = new HashSet<String>();
-            for (final PlanDetailJson planDetailJson : availableAddons) {
+            for (final PlanDetail planDetailJson : availableAddons) {
                 availableAddonsNames.add(planDetailJson.getProductName());
             }
             Assert.assertEquals(availableAddonsNames, new HashSet<String>(productJson.getAvailable()));
         }
 
         // Verify base plans endpoint
-        final List<PlanDetailJson> basePlans = getBasePlans();
+        final List<PlanDetail> basePlans = killBillClient.getBasePlans();
         final Set<String> foundBasePlans = new HashSet<String>();
-        for (final PlanDetailJson planDetailJson : basePlans) {
+        for (final PlanDetail planDetailJson : basePlans) {
             foundBasePlans.add(planDetailJson.getPlanName());
         }
         Assert.assertEquals(foundBasePlans, allBasePlans);
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java b/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
index 81a6f81..c8458ca 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
@@ -16,188 +16,154 @@
 
 package com.ning.billing.jaxrs;
 
-import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 
-import javax.ws.rs.core.Response.Status;
-
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.ChargebackJson;
-import com.ning.billing.jaxrs.json.InvoiceJson;
-import com.ning.billing.jaxrs.json.PaymentJson;
-import com.ning.billing.jaxrs.json.SubscriptionJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.http.client.Response;
-
-import com.fasterxml.jackson.core.type.TypeReference;
+import com.ning.billing.client.KillBillClientException;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Chargeback;
+import com.ning.billing.client.model.Invoice;
+import com.ning.billing.client.model.Payment;
+import com.ning.billing.client.model.Subscription;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 public class TestChargeback extends TestJaxrsBase {
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create a chargeback")
     public void testAddChargeback() throws Exception {
-        final PaymentJson payment = createAccountWithInvoiceAndPayment();
+        final Payment payment = createAccountWithInvoiceAndPayment();
         createAndVerifyChargeback(payment);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create multiple chargebacks")
     public void testMultipleChargeback() throws Exception {
-        final PaymentJson payment = createAccountWithInvoiceAndPayment();
+        final Payment payment = createAccountWithInvoiceAndPayment();
 
         // We get a 249.95 payment so we do 4 chargeback and then the fifth should fail
-        final ChargebackJson input = new ChargebackJson(null, null, null, null, new BigDecimal("50.00"), payment.getPaymentId(), null, null);
-        final String jsonInput = mapper.writeValueAsString(input);
+        final Chargeback input = new Chargeback();
+        input.setAmount(new BigDecimal("50.00"));
+        input.setPaymentId(payment.getPaymentId());
 
-        //
         int count = 4;
-        Response response;
         while (count-- > 0) {
-            response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-            assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.CREATED.getStatusCode(), response.getResponseBody());
+            assertNotNull(killBillClient.createChargeBack(input, createdBy, reason, comment));
         }
 
         // Last attempt should fail because this is more than the Payment
-        response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
+        try {
+            killBillClient.createChargeBack(input, createdBy, reason, comment);
+            fail();
+        } catch (final KillBillClientException e) {
+        }
 
         // Find the chargeback by account
-        response = doGet(JaxrsResource.ACCOUNTS_PATH + "/" + payment.getAccountId() + "/" + JaxrsResource.CHARGEBACKS, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-        List<ChargebackJson> chargebacks = mapper.readValue(response.getResponseBody(), new TypeReference<List<ChargebackJson>>() {});
+        List<Chargeback> chargebacks = killBillClient.getChargebacksForAccount(payment.getAccountId());
         assertEquals(chargebacks.size(), 4);
-        for (int i = 0; i < chargebacks.size(); i++) {
-            final ChargebackJson chargeBack = chargebacks.get(i);
+        for (final Chargeback chargeBack : chargebacks) {
             assertTrue(chargeBack.getAmount().compareTo(input.getAmount()) == 0);
             assertEquals(chargeBack.getPaymentId(), input.getPaymentId());
         }
 
         // Find the chargeback by payment
-        response = doGet(JaxrsResource.PAYMENTS_PATH + "/" + payment.getPaymentId() + "/" + JaxrsResource.CHARGEBACKS, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-        chargebacks = mapper.readValue(response.getResponseBody(), new TypeReference<List<ChargebackJson>>() {});
+        chargebacks = killBillClient.getChargebacksForPayment(payment.getPaymentId());
         assertEquals(chargebacks.size(), 4);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can add a chargeback for deleted payment methods")
     public void testAddChargebackForDeletedPaymentMethod() throws Exception {
-        final PaymentJson payment = createAccountWithInvoiceAndPayment();
+        final Payment payment = createAccountWithInvoiceAndPayment();
 
         // Check the payment method exists
-        assertEquals(getAccountById(payment.getAccountId()).getPaymentMethodId(), payment.getPaymentMethodId());
-        assertEquals(getPaymentMethod(payment.getPaymentMethodId()).getAccountId(), payment.getAccountId());
+        assertEquals(killBillClient.getAccount(payment.getAccountId()).getPaymentMethodId(), payment.getPaymentMethodId());
+        assertEquals(killBillClient.getPaymentMethod(payment.getPaymentMethodId()).getAccountId(), payment.getAccountId());
 
         // Delete the payment method
-        deletePaymentMethod(payment.getPaymentMethodId(), true);
+        killBillClient.deletePaymentMethod(payment.getPaymentMethodId(), true, createdBy, reason, comment);
 
         // Check the payment method was deleted
-        assertNull(getAccountById(payment.getAccountId()).getPaymentMethodId());
+        assertNull(killBillClient.getAccount(payment.getAccountId()).getPaymentMethodId());
 
         createAndVerifyChargeback(payment);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Cannot add a chargeback for non existent payment")
     public void testInvoicePaymentDoesNotExist() throws Exception {
-        final ChargebackJson input = new ChargebackJson(null, null, new DateTime(DateTimeZone.UTC),
-                                                          new DateTime(DateTimeZone.UTC), BigDecimal.TEN,
-                                                          UUID.randomUUID().toString(), null, null);
-        final String jsonInput = mapper.writeValueAsString(input);
-
-        // Try to create the chargeback
-        final Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode(), response.getResponseBody());
+        final Chargeback input = new Chargeback();
+        input.setAmount(BigDecimal.TEN);
+        input.setPaymentId(UUID.randomUUID());
+        assertNull(killBillClient.createChargeBack(input, createdBy, reason, comment));
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Cannot add a badly formatted chargeback")
     public void testBadRequest() throws Exception {
-        final ChargebackJson input = new ChargebackJson(null, null, null, null, null, null, null, null);
-        final String jsonInput = mapper.writeValueAsString(input);
+        final Payment payment = createAccountWithInvoiceAndPayment();
+
+        final Chargeback input = new Chargeback();
+        input.setAmount(BigDecimal.TEN.negate());
+        input.setPaymentId(payment.getPaymentId());
 
-        // Try to create the chargeback
-        final Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
+        try {
+            killBillClient.createChargeBack(input, createdBy, reason, comment);
+            fail();
+        } catch (final KillBillClientException e) {
+        }
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Accounts can have zero chargeback")
     public void testNoChargebackForAccount() throws Exception {
-        final String accountId = UUID.randomUUID().toString();
-        final Response response = doGet(JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.CHARGEBACKS, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode(), response.getResponseBody());
-
-        final List<ChargebackJson> chargebackJson = mapper.readValue(response.getResponseBody(), new TypeReference<List<ChargebackJson>>() {});
-        Assert.assertEquals(chargebackJson.size(), 0);
+        Assert.assertEquals(killBillClient.getChargebacksForAccount(UUID.randomUUID()).size(), 0);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Payments can have zero chargeback")
     public void testNoChargebackForPayment() throws Exception {
-        final String paymentId = UUID.randomUUID().toString();
-        final Response response = doGet(JaxrsResource.PAYMENTS_PATH + "/" + paymentId + "/" + JaxrsResource.CHARGEBACKS, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        // STEPH needs to fix that we get 200 instaed of 204 although stepping through code, i see we do return NO_CONTENT. mistery that needs to be solved!!!!
-        //assertEquals(response.getStatusCode(),Status.NO_CONTENT.getStatusCode(), response.getResponseBody());
+        Assert.assertEquals(killBillClient.getChargebacksForPayment(UUID.randomUUID()).size(), 0);
     }
 
-    private void createAndVerifyChargeback(final PaymentJson payment) throws IOException {
-        final ChargebackJson input = new ChargebackJson(null, null, null, null, BigDecimal.TEN, payment.getPaymentId(), null, null);
-        final String jsonInput = mapper.writeValueAsString(input);
-
+    private void createAndVerifyChargeback(final Payment payment) throws KillBillClientException {
         // Create the chargeback
-        Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode(), response.getResponseBody());
-
-        // Find the chargeback by location
-        final String location = response.getHeader("Location");
-        assertNotNull(location);
-        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        verifySingleChargebackResponse(response, input);
+        final Chargeback chargeback = new Chargeback();
+        chargeback.setPaymentId(payment.getPaymentId());
+        chargeback.setAmount(BigDecimal.TEN);
+        final Chargeback chargebackJson = killBillClient.createChargeBack(chargeback, createdBy, reason, comment);
+        assertEquals(chargebackJson.getAmount().compareTo(chargeback.getAmount()), 0);
+        assertEquals(chargebackJson.getPaymentId(), chargeback.getPaymentId());
 
         // Find the chargeback by account
-        response = doGet(JaxrsResource.ACCOUNTS_PATH + "/" + payment.getAccountId() + "/" + JaxrsResource.CHARGEBACKS, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        verifyCollectionChargebackResponse(response, input);
+        List<Chargeback> chargebacks = killBillClient.getChargebacksForAccount(payment.getAccountId());
+        assertEquals(chargebacks.size(), 1);
+        assertEquals(chargebacks.get(0).getAmount().compareTo(chargeback.getAmount()), 0);
+        assertEquals(chargebacks.get(0).getPaymentId(), chargeback.getPaymentId());
 
         // Find the chargeback by payment
-        response = doGet(JaxrsResource.PAYMENTS_PATH + "/" + payment.getPaymentId() + "/" + JaxrsResource.CHARGEBACKS, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        verifyCollectionChargebackResponse(response, input);
+        chargebacks = killBillClient.getChargebacksForPayment(payment.getPaymentId());
+        assertEquals(chargebacks.size(), 1);
+        assertEquals(chargebacks.get(0).getAmount().compareTo(chargeback.getAmount()), 0);
+        assertEquals(chargebacks.get(0).getPaymentId(), chargeback.getPaymentId());
     }
 
-    private void verifyCollectionChargebackResponse(final Response response, final ChargebackJson input) throws IOException {
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final List<ChargebackJson> chargebackJson = mapper.readValue(response.getResponseBody(), new TypeReference<List<ChargebackJson>>() {});
-        assertEquals(chargebackJson.size(), 1);
-        final ChargebackJson chargeBack = chargebackJson.get(0);
-        assertTrue(chargeBack.getAmount().compareTo(input.getAmount()) == 0);
-        assertEquals(chargeBack.getPaymentId(), input.getPaymentId());
-    }
-
-    private void verifySingleChargebackResponse(final Response response, final ChargebackJson input) throws IOException {
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final ChargebackJson objFromJson = mapper.readValue(response.getResponseBody(), ChargebackJson.class);
-        assertTrue(objFromJson.getAmount().compareTo(input.getAmount()) == 0);
-    }
-
-    private PaymentJson createAccountWithInvoiceAndPayment() throws Exception {
-        final InvoiceJson invoice = createAccountWithInvoice();
+    private Payment createAccountWithInvoiceAndPayment() throws Exception {
+        final Invoice invoice = createAccountWithInvoice();
         return getPayment(invoice);
     }
 
-    private InvoiceJson createAccountWithInvoice() throws Exception {
+    private Invoice createAccountWithInvoice() throws Exception {
         // Create account
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod(UUID.randomUUID().toString(), UUID.randomUUID().toString(), "nohup@yahoo.com");
-
+        final Account accountJson = createAccountWithDefaultPaymentMethod();
 
         // Create subscription
-        final SubscriptionJson subscriptionJson = createEntitlement(accountJson.getAccountId(), "6253283", "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        final Subscription subscriptionJson = createEntitlement(accountJson.getAccountId(), "6253283", "Shotgun",
+                                                                ProductCategory.BASE, BillingPeriod.MONTHLY, true);
         assertNotNull(subscriptionJson);
 
         // Move after the trial period to trigger an invoice with a non-zero invoice item
@@ -205,29 +171,18 @@ public class TestChargeback extends TestJaxrsBase {
         crappyWaitForLackOfProperSynchonization();
 
         // Retrieve the invoice
-
-        final Response response = doGet(JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.INVOICES, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<InvoiceJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<InvoiceJson>>() {});
-        assertNotNull(objFromJson);
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
         // We should have two invoices, one for the trial (zero dollar amount) and one for the first month
-        assertEquals(objFromJson.size(), 2);
-        assertTrue(objFromJson.get(1).getAmount().doubleValue() > 0);
+        assertEquals(invoices.size(), 2);
+        assertTrue(invoices.get(1).getAmount().doubleValue() > 0);
 
-        return objFromJson.get(1);
+        return invoices.get(1);
     }
 
-    private PaymentJson getPayment(final InvoiceJson invoice) throws IOException {
-        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoice.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<PaymentJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJson>>() {});
-        assertNotNull(objFromJson);
-        assertEquals(objFromJson.size(), 1);
-
-        return objFromJson.get(0);
+    private Payment getPayment(final Invoice invoice) throws KillBillClientException {
+        final List<Payment> payments = killBillClient.getPaymentsForInvoice(invoice.getInvoiceId());
+        assertNotNull(payments);
+        assertEquals(payments.size(), 1);
+        return payments.get(0);
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java b/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
index e9f4ab7..ba46924 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
@@ -19,71 +19,73 @@ package com.ning.billing.jaxrs;
 import java.math.BigDecimal;
 import java.util.UUID;
 
-import javax.ws.rs.core.Response.Status;
-
 import org.joda.time.DateTime;
-import org.joda.time.LocalDate;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.CreditJson;
-import com.ning.billing.jaxrs.json.InvoiceJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.http.client.Response;
+import com.ning.billing.client.KillBillClientException;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Credit;
+import com.ning.billing.client.model.Invoice;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.fail;
 
 public class TestCredit extends TestJaxrsBase {
 
-    AccountJson accountJson;
+    Account accountJson;
 
     @BeforeMethod(groups = "slow")
     public void setUp() throws Exception {
         accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can add a credit to an existing invoice")
     public void testAddCreditToInvoice() throws Exception {
-        final InvoiceJson invoice = getInvoicesForAccount(accountJson.getAccountId()).get(1);
+        final Invoice invoice = killBillClient.getInvoicesForAccount(accountJson.getAccountId()).get(1);
 
         final DateTime effectiveDate = clock.getUTCNow();
         final BigDecimal creditAmount = BigDecimal.ONE;
-        final CreditJson objFromJson = createCreditForInvoice(accountJson.getAccountId(), invoice.getInvoiceId(),
-                                                              creditAmount, clock.getUTCNow(), effectiveDate);
+        final Credit credit = new Credit();
+        credit.setAccountId(accountJson.getAccountId());
+        credit.setInvoiceId(invoice.getInvoiceId());
+        credit.setCreditAmount(creditAmount);
+        final Credit objFromJson = killBillClient.createCredit(credit, createdBy, reason, comment);
 
         // We can't just compare the object via .equals() due e.g. to the invoice id
         assertEquals(objFromJson.getAccountId(), accountJson.getAccountId());
+        assertEquals(objFromJson.getInvoiceId(), invoice.getInvoiceId());
         assertEquals(objFromJson.getCreditAmount().compareTo(creditAmount), 0);
         assertEquals(objFromJson.getEffectiveDate().compareTo(effectiveDate.toLocalDate()), 0);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Cannot add a credit if the account doesn't exist")
     public void testAccountDoesNotExist() throws Exception {
-        final LocalDate effectiveDate = clock.getUTCToday();
-        final CreditJson input = new CreditJson(BigDecimal.TEN, UUID.randomUUID().toString(), UUID.randomUUID().toString(),
-                                                effectiveDate,
-                                                UUID.randomUUID().toString(), null);
-        final String jsonInput = mapper.writeValueAsString(input);
+        final Credit credit = new Credit();
+        credit.setAccountId(UUID.randomUUID());
+        credit.setCreditAmount(BigDecimal.TEN);
 
         // Try to create the credit
-        final Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode(), response.getResponseBody());
+        assertNull(killBillClient.createCredit(credit, createdBy, reason, comment));
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Cannot credit a badly formatted credit")
     public void testBadRequest() throws Exception {
-        final CreditJson input = new CreditJson(null, null, null, null, null, null);
-        final String jsonInput = mapper.writeValueAsString(input);
+        final Credit credit = new Credit();
+        credit.setAccountId(accountJson.getAccountId());
+        credit.setCreditAmount(BigDecimal.TEN.negate());
 
         // Try to create the credit
-        final Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
+        try {
+            killBillClient.createCredit(credit, createdBy, reason, comment);
+            fail();
+        } catch (final KillBillClientException e) {
+        }
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Cannot retrieve a non existing credit")
     public void testCreditDoesNotExist() throws Exception {
-        final Response response = doGet(JaxrsResource.CREDITS_PATH + "/" + UUID.randomUUID().toString(), DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode(), response.getResponseBody());
+        assertNull(killBillClient.getCredit(UUID.randomUUID()));
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestEntitlement.java b/server/src/test/java/com/ning/billing/jaxrs/TestEntitlement.java
index db682de..f146862 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestEntitlement.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestEntitlement.java
@@ -16,24 +16,21 @@
 
 package com.ning.billing.jaxrs;
 
-import java.util.Map;
 import java.util.UUID;
 
-import javax.ws.rs.core.Response.Status;
-
 import org.joda.time.DateTime;
 import org.joda.time.Interval;
 import org.joda.time.LocalDate;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import com.ning.billing.catalog.api.BillingActionPolicy;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.SubscriptionJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.http.client.Response;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Subscription;
+import com.ning.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -42,57 +39,35 @@ import static org.testng.Assert.assertTrue;
 
 public class TestEntitlement extends TestJaxrsBase {
 
-    private static final String CALL_COMPLETION_TIMEOUT_SEC = "5";
+    private static final int CALL_COMPLETION_TIMEOUT_SEC = 5;
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can change plan and cancel a subscription")
     public void testEntitlementInTrialOk() throws Exception {
-
         final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
 
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("xil", "shdxilhkkl", "xil@yahoo.com");
+        final Account accountJson = createAccountWithDefaultPaymentMethod();
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.MONTHLY;
 
-        final SubscriptionJson entitlementJson = createEntitlement(accountJson.getAccountId(), "99999", productName, ProductCategory.BASE.toString(), term.toString(), true);
-
-        String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + entitlementJson.getSubscriptionId();
+        final Subscription entitlementJson = createEntitlement(accountJson.getAccountId(), "99999", productName,
+                                                               ProductCategory.BASE, term, true);
 
         // Retrieves with GET
-        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        String baseJson = response.getResponseBody();
-        SubscriptionJson objFromJson = mapper.readValue(baseJson, SubscriptionJson.class);
+        Subscription objFromJson = killBillClient.getSubscription(entitlementJson.getSubscriptionId());
         Assert.assertTrue(objFromJson.equals(entitlementJson));
 
         // Change plan IMM
         final String newProductName = "Assault-Rifle";
 
-        final SubscriptionJson newInput = new SubscriptionJson(null,
-                                                               null,
-                                                               entitlementJson.getSubscriptionId(),
-                                                               null,
-                                                               null,
-                                                               newProductName,
-                                                               entitlementJson.getProductCategory(),
-                                                               entitlementJson.getBillingPeriod(),
-                                                               entitlementJson.getPriceList(),
-                                                               null,
-                                                               null,
-                                                               null,
-                                                               null,
-                                                               null,
-                                                               null,
-                                                               null,
-                                                               null);
-        baseJson = mapper.writeValueAsString(newInput);
-
-        final Map<String, String> queryParams = getQueryParamsForCallCompletion(CALL_COMPLETION_TIMEOUT_SEC);
-        response = doPut(uri, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        objFromJson = mapper.readValue(baseJson, SubscriptionJson.class);
+        final Subscription newInput = new Subscription();
+        newInput.setSubscriptionId(entitlementJson.getSubscriptionId());
+        newInput.setProductName(newProductName);
+        newInput.setBillingPeriod(entitlementJson.getBillingPeriod());
+        newInput.setPriceList(entitlementJson.getPriceList());
+        objFromJson = killBillClient.updateSubscription(newInput, CALL_COMPLETION_TIMEOUT_SEC, createdBy, reason, comment);
+        Assert.assertNotNull(objFromJson);
 
         // MOVE AFTER TRIAL
         final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(31));
@@ -101,42 +76,29 @@ public class TestEntitlement extends TestJaxrsBase {
         crappyWaitForLackOfProperSynchonization();
 
         // Cancel IMM (Billing EOT)
-        uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + entitlementJson.getSubscriptionId();
-        response = doDelete(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        killBillClient.cancelSubscription(newInput.getSubscriptionId(), CALL_COMPLETION_TIMEOUT_SEC, createdBy, reason, comment);
 
         // Retrieves to check EndDate
-        uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + entitlementJson.getSubscriptionId();
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        objFromJson = mapper.readValue(baseJson, SubscriptionJson.class);
+        objFromJson = killBillClient.getSubscription(entitlementJson.getSubscriptionId());
         assertNotNull(objFromJson.getCancelledDate());
         assertTrue(objFromJson.getCancelledDate().compareTo(new LocalDate(clock.getUTCNow())) == 0);
     }
 
-
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can cancel and uncancel a subscription")
     public void testEntitlementUncancel() throws Exception {
-
         final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
 
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("xil", "shdxilhkkl", "xil@yahoo.com");
+        final Account accountJson = createAccountWithDefaultPaymentMethod();
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.MONTHLY;
 
-        final SubscriptionJson entitlementJson = createEntitlement(accountJson.getAccountId(), "99999", productName, ProductCategory.BASE.toString(), term.toString(), true);
-
-        String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + entitlementJson.getSubscriptionId();
+        final Subscription entitlementJson = createEntitlement(accountJson.getAccountId(), "99999", productName,
+                                                               ProductCategory.BASE, term, true);
 
         // Retrieves with GET
-        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        String baseJson = response.getResponseBody();
-        SubscriptionJson objFromJson = mapper.readValue(baseJson, SubscriptionJson.class);
+        Subscription objFromJson = killBillClient.getSubscription(entitlementJson.getSubscriptionId());
         Assert.assertTrue(objFromJson.equals(entitlementJson));
 
         // MOVE AFTER TRIAL
@@ -146,94 +108,63 @@ public class TestEntitlement extends TestJaxrsBase {
         crappyWaitForLackOfProperSynchonization();
 
         // Cancel EOT
-        final Map<String, String> queryParams = getQueryParamsForCallCompletion(CALL_COMPLETION_TIMEOUT_SEC);
-        queryParams.put(JaxrsResource.QUERY_BILLING_POLICY, "END_OF_TERM");
-        queryParams.put(JaxrsResource.QUERY_ENTITLEMENT_POLICY, "END_OF_TERM");
-
-        uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + entitlementJson.getSubscriptionId();
-        response = doDelete(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC * 10000);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        killBillClient.cancelSubscription(entitlementJson.getSubscriptionId(), EntitlementActionPolicy.END_OF_TERM,
+                                          BillingActionPolicy.END_OF_TERM, CALL_COMPLETION_TIMEOUT_SEC, createdBy, reason, comment);
 
         // Retrieves to check EndDate
-        uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + entitlementJson.getSubscriptionId();
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        objFromJson = mapper.readValue(baseJson, SubscriptionJson.class);
+        objFromJson = killBillClient.getSubscription(entitlementJson.getSubscriptionId());
         assertNotNull(objFromJson.getCancelledDate());
 
+        // Uncancel
+        killBillClient.uncancelSubscription(entitlementJson.getSubscriptionId(), createdBy, reason, comment);
 
-        uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + entitlementJson.getSubscriptionId() + "/uncancel";
-        response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-
-        uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + entitlementJson.getSubscriptionId();
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        objFromJson = mapper.readValue(baseJson, SubscriptionJson.class);
+        objFromJson = killBillClient.getSubscription(entitlementJson.getSubscriptionId());
         assertNull(objFromJson.getCancelledDate());
-
     }
 
-
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can handle non existent subscription")
     public void testWithNonExistentEntitlement() throws Exception {
-        final String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + UUID.randomUUID().toString();
-        final SubscriptionJson subscriptionJson = new SubscriptionJson(null, null, UUID.randomUUID().toString(), null, null, "Pistol", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(),
-                                                                       PriceListSet.DEFAULT_PRICELIST_NAME, null, null, null, null, null, null, null, null);
-        final String baseJson = mapper.writeValueAsString(subscriptionJson);
+        final UUID subscriptionId = UUID.randomUUID();
+        final Subscription subscription = new Subscription();
+        subscription.setSubscriptionId(subscriptionId);
+        subscription.setProductName("Pistol");
+        subscription.setBillingPeriod(BillingPeriod.ANNUAL);
+        subscription.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
 
-        Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
+        Assert.assertNull(killBillClient.updateSubscription(subscription, createdBy, reason, comment));
 
-        response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
+        // No-op (404, doesn't throw an exception)
+        killBillClient.cancelSubscription(subscriptionId, createdBy, reason, comment);
 
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
+        Assert.assertNull(killBillClient.getSubscription(subscriptionId));
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can override billing policy on change")
     public void testOverridePolicy() throws Exception {
         final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
 
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("xil", "shdxilhkkl", "xil@yahoo.com");
+        final Account accountJson = createAccountWithDefaultPaymentMethod();
 
         final String productName = "Shotgun";
         final BillingPeriod term = BillingPeriod.ANNUAL;
 
-        final SubscriptionJson SubscriptionJson = createEntitlement(accountJson.getAccountId(), "99999", productName, ProductCategory.BASE.toString(), term.toString(), true);
-        final String uri = JaxrsResource.SUBSCRIPTIONS_PATH + "/" + SubscriptionJson.getSubscriptionId();
+        final Subscription subscriptionJson = createEntitlement(accountJson.getAccountId(), "99999", productName,
+                                                                ProductCategory.BASE, term, true);
 
         // Retrieves with GET
-        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        String baseJson = response.getResponseBody();
-        SubscriptionJson objFromJson = mapper.readValue(baseJson, SubscriptionJson.class);
-        Assert.assertTrue(objFromJson.equals(SubscriptionJson));
-        assertEquals(objFromJson.getBillingPeriod(), BillingPeriod.ANNUAL.toString());
+        Subscription objFromJson = killBillClient.getSubscription(subscriptionJson.getSubscriptionId());
+        Assert.assertTrue(objFromJson.equals(subscriptionJson));
+        assertEquals(objFromJson.getBillingPeriod(), BillingPeriod.ANNUAL);
 
         // Change billing period immediately
-        final SubscriptionJson newInput = new SubscriptionJson(null,
-                                                               null,
-                                                               SubscriptionJson.getSubscriptionId(),
-                                                               null,
-                                                               null,
-                                                               SubscriptionJson.getProductName(),
-                                                               SubscriptionJson.getProductCategory(),
-                                                               BillingPeriod.MONTHLY.toString(),
-                                                               SubscriptionJson.getPriceList(),
-                                                               SubscriptionJson.getCancelledDate(),
-                                                               null, null, null, null, null, null, null);
-        baseJson = mapper.writeValueAsString(newInput);
-        final Map<String, String> queryParams = getQueryParamsForCallCompletion(CALL_COMPLETION_TIMEOUT_SEC);
-        queryParams.put(JaxrsResource.QUERY_BILLING_POLICY, "immediate");
-        response = doPut(uri, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        objFromJson = mapper.readValue(baseJson, SubscriptionJson.class);
-        assertEquals(objFromJson.getBillingPeriod(), BillingPeriod.MONTHLY.toString());
+        final Subscription newInput = new Subscription();
+        newInput.setSubscriptionId(subscriptionJson.getSubscriptionId());
+        newInput.setProductName(subscriptionJson.getProductName());
+        newInput.setBillingPeriod(BillingPeriod.MONTHLY);
+        newInput.setPriceList(subscriptionJson.getPriceList());
+        objFromJson = killBillClient.updateSubscription(newInput, BillingActionPolicy.IMMEDIATE, CALL_COMPLETION_TIMEOUT_SEC, createdBy, reason, comment);
+        Assert.assertNotNull(objFromJson);
+        assertEquals(objFromJson.getBillingPeriod(), BillingPeriod.MONTHLY);
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestExceptions.java b/server/src/test/java/com/ning/billing/jaxrs/TestExceptions.java
index 4ba5fb9..865013d 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestExceptions.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestExceptions.java
@@ -16,32 +16,38 @@
 
 package com.ning.billing.jaxrs;
 
-import javax.ws.rs.core.Response.Status;
+import java.math.BigDecimal;
+import java.util.List;
 
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.ning.billing.ErrorCode;
-import com.ning.billing.account.api.AccountApiException;
-import com.ning.billing.jaxrs.json.BillingExceptionJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.http.client.Response;
+import com.ning.billing.client.KillBillClientException;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Chargeback;
+import com.ning.billing.client.model.Payment;
+import com.ning.billing.invoice.api.InvoiceApiException;
 
-import com.fasterxml.jackson.core.type.TypeReference;
+import static org.testng.Assert.fail;
 
 public class TestExceptions extends TestJaxrsBase {
 
     @Test(groups = "slow")
     public void testExceptionMapping() throws Exception {
-        // Non-existent account
-        final String uri = JaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
-        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
-
-        final BillingExceptionJson objFromJson = mapper.readValue(response.getResponseBody(), new TypeReference<BillingExceptionJson>() {});
-        Assert.assertNotNull(objFromJson);
-        Assert.assertEquals(objFromJson.getClassName(), AccountApiException.class.getName());
-        Assert.assertEquals(objFromJson.getCode(), (Integer) ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID.getCode());
-        Assert.assertTrue(objFromJson.getStackTrace().size() > 0);
+        final Account account = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final List<Payment> payments = killBillClient.getPaymentsForAccount(account.getAccountId());
+        final Chargeback input = new Chargeback();
+        input.setAmount(BigDecimal.TEN.negate());
+        input.setPaymentId(payments.get(0).getPaymentId());
+
+        try {
+            killBillClient.createChargeBack(input, createdBy, reason, comment);
+            fail();
+        } catch (final KillBillClientException e) {
+            Assert.assertEquals(e.getBillingException().getClassName(), InvoiceApiException.class.getName());
+            Assert.assertEquals(e.getBillingException().getCode(), (Integer) ErrorCode.CHARGE_BACK_AMOUNT_IS_NEGATIVE.getCode());
+            Assert.assertFalse(e.getBillingException().getStackTrace().isEmpty());
+        }
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
index c58fc6f..8a6699e 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
@@ -25,12 +25,12 @@ import org.joda.time.DateTime;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.AuditLogJson;
-import com.ning.billing.jaxrs.json.InvoiceItemJson;
-import com.ning.billing.jaxrs.json.InvoiceJson;
-import com.ning.billing.jaxrs.json.PaymentJson;
-import com.ning.billing.jaxrs.json.PaymentMethodJson;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.AuditLog;
+import com.ning.billing.client.model.Invoice;
+import com.ning.billing.client.model.InvoiceItem;
+import com.ning.billing.client.model.Payment;
+import com.ning.billing.client.model.PaymentMethod;
 import com.ning.billing.payment.provider.ExternalPaymentProviderPlugin;
 import com.ning.billing.util.api.AuditLevel;
 
@@ -41,18 +41,18 @@ import static org.testng.Assert.assertTrue;
 
 public class TestInvoice extends TestJaxrsBase {
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can search and retrieve invoices with and without items")
     public void testInvoiceOk() throws Exception {
         final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
 
-        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final List<InvoiceJson> invoices = getInvoicesForAccountWithAudits(accountJson.getAccountId(), AuditLevel.FULL);
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, AuditLevel.FULL);
         assertEquals(invoices.size(), 2);
-        for (final InvoiceJson invoiceJson : invoices) {
+        for (final Invoice invoiceJson : invoices) {
             Assert.assertEquals(invoiceJson.getAuditLogs().size(), 1);
-            final AuditLogJson auditLogJson = invoiceJson.getAuditLogs().get(0);
+            final AuditLog auditLogJson = invoiceJson.getAuditLogs().get(0);
             Assert.assertEquals(auditLogJson.getChangeType(), "INSERT");
             Assert.assertEquals(auditLogJson.getChangedBy(), "SubscriptionBaseTransition");
             Assert.assertFalse(auditLogJson.getChangeDate().isBefore(initialDate));
@@ -61,45 +61,45 @@ public class TestInvoice extends TestJaxrsBase {
             Assert.assertNull(auditLogJson.getComments());
         }
 
-        final InvoiceJson invoiceJson = invoices.get(0);
+        final Invoice invoiceJson = invoices.get(0);
 
         // Check get with & without items
-        assertTrue(getInvoice(invoiceJson.getInvoiceId(), Boolean.FALSE).getItems().isEmpty());
-        assertTrue(getInvoice(invoiceJson.getInvoiceNumber(), Boolean.FALSE).getItems().isEmpty());
-        assertEquals(getInvoice(invoiceJson.getInvoiceId(), Boolean.TRUE).getItems().size(), invoiceJson.getItems().size());
-        assertEquals(getInvoice(invoiceJson.getInvoiceNumber(), Boolean.TRUE).getItems().size(), invoiceJson.getItems().size());
+        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());
 
         // Check we can retrieve an individual invoice
-        final InvoiceJson firstInvoiceJson = getInvoice(invoiceJson.getInvoiceId());
-        assertEquals(firstInvoiceJson, invoiceJson);
+        final Invoice firstInvoice = killBillClient.getInvoice(invoiceJson.getInvoiceId());
+        assertEquals(firstInvoice, invoiceJson);
 
         // Check we can retrieve the invoice by number
-        final InvoiceJson firstInvoiceByNumberJson = getInvoice(invoiceJson.getInvoiceNumber());
+        final Invoice firstInvoiceByNumberJson = killBillClient.getInvoice(invoiceJson.getInvoiceNumber());
         assertEquals(firstInvoiceByNumberJson, invoiceJson);
 
         // Then create a dryRun Invoice
         final DateTime futureDate = clock.getUTCNow().plusMonths(1).plusDays(3);
-        createDryRunInvoice(accountJson.getAccountId(), futureDate);
+        killBillClient.createDryRunInvoice(accountJson.getAccountId(), futureDate, createdBy, reason, comment);
 
         // The one more time with no DryRun
-        createInvoice(accountJson.getAccountId(), futureDate);
+        killBillClient.createInvoice(accountJson.getAccountId(), futureDate, createdBy, reason, comment);
 
         // Check again # invoices, should be 3 this time
-        final List<InvoiceJson> newInvoiceList = getInvoicesForAccount(accountJson.getAccountId());
+        final List<Invoice> newInvoiceList = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
         assertEquals(newInvoiceList.size(), 3);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can retrieve invoice payments")
     public void testInvoicePayments() throws Exception {
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
-        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final List<InvoiceJson> invoices = getInvoicesForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
         assertEquals(invoices.size(), 2);
 
-        for (final InvoiceJson cur : invoices) {
-            final List<PaymentJson> objFromJson = getPaymentsForInvoice(cur.getInvoiceId());
+        for (final Invoice cur : invoices) {
+            final List<Payment> objFromJson = killBillClient.getPaymentsForInvoice(cur.getInvoiceId());
 
             if (cur.getAmount().compareTo(BigDecimal.ZERO) == 0) {
                 assertEquals(objFromJson.size(), 0);
@@ -110,77 +110,85 @@ public class TestInvoice extends TestJaxrsBase {
         }
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can pay invoices")
     public void testPayAllInvoices() throws Exception {
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
         // No payment method
-        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Check there was no payment made
-        assertEquals(getPaymentsForAccount(accountJson.getAccountId()).size(), 1);
+        assertEquals(killBillClient.getPaymentsForAccount(accountJson.getAccountId()).size(), 1);
 
         // Get the invoices
-        final List<InvoiceJson> invoices = getInvoicesForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
         assertEquals(invoices.size(), 2);
-        final InvoiceJson invoiceToPay = invoices.get(1);
+        final Invoice invoiceToPay = invoices.get(1);
         assertEquals(invoiceToPay.getBalance().compareTo(BigDecimal.ZERO), 1);
 
         // Pay all invoices
-        payAllInvoices(accountJson, true);
-        for (final InvoiceJson invoice : getInvoicesForAccount(accountJson.getAccountId())) {
+        killBillClient.payAllInvoices(accountJson.getAccountId(), true, createdBy, reason, comment);
+        for (final Invoice invoice : killBillClient.getInvoicesForAccount(accountJson.getAccountId())) {
             assertEquals(invoice.getBalance().compareTo(BigDecimal.ZERO), 0);
         }
-        assertEquals(getPaymentsForAccount(accountJson.getAccountId()).size(), 2);
+        assertEquals(killBillClient.getPaymentsForAccount(accountJson.getAccountId()).size(), 2);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create an insta-payment")
     public void testInvoiceCreatePayment() throws Exception {
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
         // STEPH MISSING SET ACCOUNT AUTO_PAY_OFF
-        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<InvoiceJson> invoices = getInvoicesForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
         assertEquals(invoices.size(), 2);
 
-        for (final InvoiceJson cur : invoices) {
-            if (cur.getAmount().compareTo(BigDecimal.ZERO) == 0) {
+        for (final Invoice cur : invoices) {
+            if (cur.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
                 continue;
             }
 
             // CREATE INSTA PAYMENT
-            final List<PaymentJson> objFromJson = createInstaPayment(accountJson, cur);
+            final Payment payment = new Payment();
+            payment.setAccountId(accountJson.getAccountId());
+            payment.setInvoiceId(cur.getInvoiceId());
+            payment.setAmount(cur.getBalance());
+            final List<Payment> objFromJson = killBillClient.createPayment(payment, false, createdBy, reason, comment);
             assertEquals(objFromJson.size(), 1);
-            assertEquals(cur.getAmount().compareTo(objFromJson.get(0).getAmount()), 0);
+            assertEquals(cur.getBalance().compareTo(objFromJson.get(0).getAmount()), 0);
         }
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create an external payment")
     public void testExternalPayment() throws Exception {
-        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Verify we didn't get any payment
-        final List<PaymentJson> noPaymentsFromJson = getPaymentsForAccount(accountJson.getAccountId());
+        final List<Payment> noPaymentsFromJson = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
         assertEquals(noPaymentsFromJson.size(), 1);
-        final String initialPaymentId = noPaymentsFromJson.get(0).getPaymentId();
+        final UUID initialPaymentId = noPaymentsFromJson.get(0).getPaymentId();
 
         // Get the invoices
-        final List<InvoiceJson> invoices = getInvoicesForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
-        final String invoiceId = invoices.get(1).getInvoiceId();
+        final UUID invoiceId = invoices.get(1).getInvoiceId();
 
         // Post an external payment
         final BigDecimal paidAmount = BigDecimal.TEN;
-        createExternalPayment(accountJson, invoiceId, paidAmount);
+        final Payment payment = new Payment();
+        payment.setAmount(BigDecimal.TEN);
+        payment.setAccountId(accountJson.getAccountId());
+        payment.setInvoiceId(invoiceId);
+        killBillClient.createPayment(payment, true, createdBy, reason, comment);
 
         // Verify we indeed got the payment
-        final List<PaymentJson> paymentsFromJson = getPaymentsForAccount(accountJson.getAccountId());
+        final List<Payment> paymentsFromJson = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
         assertEquals(paymentsFromJson.size(), 2);
-        PaymentJson secondPayment = null;
-        for (PaymentJson cur : paymentsFromJson) {
+        Payment secondPayment = null;
+        for (final Payment cur : paymentsFromJson) {
             if (!cur.getPaymentId().equals(initialPaymentId)) {
                 secondPayment = cur;
                 break;
@@ -191,39 +199,43 @@ public class TestInvoice extends TestJaxrsBase {
         assertEquals(secondPayment.getPaidAmount().compareTo(paidAmount), 0);
 
         // Check the PaymentMethod from paymentMethodId returned in the Payment object
-        final String paymentMethodId = secondPayment.getPaymentMethodId();
-        final PaymentMethodJson paymentMethodJson = getPaymentMethod(paymentMethodId);
+        final UUID paymentMethodId = secondPayment.getPaymentMethodId();
+        final PaymentMethod paymentMethodJson = killBillClient.getPaymentMethod(paymentMethodId);
         assertEquals(paymentMethodJson.getPaymentMethodId(), paymentMethodId);
         assertEquals(paymentMethodJson.getAccountId(), accountJson.getAccountId());
         assertEquals(paymentMethodJson.getPluginName(), ExternalPaymentProviderPlugin.PLUGIN_NAME);
         assertNull(paymentMethodJson.getPluginInfo());
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can fully adjust an invoice item")
     public void testFullInvoiceItemAdjustment() throws Exception {
-        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<InvoiceJson> invoices = getInvoicesWithItemsForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
-        final InvoiceJson invoice = invoices.get(1);
+        final Invoice invoice = invoices.get(1);
         // Verify the invoice we picked is non zero
         assertEquals(invoice.getAmount().compareTo(BigDecimal.ZERO), 1);
-        final InvoiceItemJson invoiceItem = invoice.getItems().get(0);
+        final InvoiceItem invoiceItem = invoice.getItems().get(0);
         // Verify the item we picked is non zero
         assertEquals(invoiceItem.getAmount().compareTo(BigDecimal.ZERO), 1);
 
         // Adjust the full amount
-        adjustInvoiceItem(accountJson.getAccountId(), invoice.getInvoiceId(), invoiceItem.getInvoiceItemId(), null, null, null);
+        final InvoiceItem adjustmentInvoiceItem = new InvoiceItem();
+        adjustmentInvoiceItem.setAccountId(accountJson.getAccountId());
+        adjustmentInvoiceItem.setInvoiceId(invoice.getInvoiceId());
+        adjustmentInvoiceItem.setInvoiceItemId(invoiceItem.getInvoiceItemId());
+        killBillClient.adjustInvoiceItem(invoiceItem, createdBy, reason, comment);
 
         // Verify the new invoice balance is zero
-        final InvoiceJson adjustedInvoice = getInvoiceWithItemsWithAudits(invoice.getInvoiceId(), AuditLevel.FULL);
+        final Invoice adjustedInvoice = killBillClient.getInvoice(invoice.getInvoiceId(), true, AuditLevel.FULL);
         assertEquals(adjustedInvoice.getAmount().compareTo(BigDecimal.ZERO), 0);
 
         // Verify invoice audit logs
         Assert.assertEquals(adjustedInvoice.getAuditLogs().size(), 1);
-        final AuditLogJson invoiceAuditLogJson = adjustedInvoice.getAuditLogs().get(0);
+        final AuditLog invoiceAuditLogJson = adjustedInvoice.getAuditLogs().get(0);
         Assert.assertEquals(invoiceAuditLogJson.getChangeType(), "INSERT");
         Assert.assertEquals(invoiceAuditLogJson.getChangedBy(), "SubscriptionBaseTransition");
         Assert.assertNotNull(invoiceAuditLogJson.getChangeDate());
@@ -237,7 +249,7 @@ public class TestInvoice extends TestJaxrsBase {
 
         // The first item is the original item
         Assert.assertEquals(adjustedInvoice.getItems().get(0).getAuditLogs().size(), 1);
-        final AuditLogJson itemAuditLogJson = adjustedInvoice.getItems().get(0).getAuditLogs().get(0);
+        final AuditLog itemAuditLogJson = adjustedInvoice.getItems().get(0).getAuditLogs().get(0);
         Assert.assertEquals(itemAuditLogJson.getChangeType(), "INSERT");
         Assert.assertEquals(itemAuditLogJson.getChangedBy(), "SubscriptionBaseTransition");
         Assert.assertNotNull(itemAuditLogJson.getChangeDate());
@@ -247,7 +259,7 @@ public class TestInvoice extends TestJaxrsBase {
 
         // The second one is the adjustment
         Assert.assertEquals(adjustedInvoice.getItems().get(1).getAuditLogs().size(), 1);
-        final AuditLogJson adjustedItemAuditLogJson = adjustedInvoice.getItems().get(1).getAuditLogs().get(0);
+        final AuditLog adjustedItemAuditLogJson = adjustedInvoice.getItems().get(1).getAuditLogs().get(0);
         Assert.assertEquals(adjustedItemAuditLogJson.getChangeType(), "INSERT");
         Assert.assertEquals(adjustedItemAuditLogJson.getChangedBy(), createdBy);
         Assert.assertEquals(adjustedItemAuditLogJson.getReasonCode(), reason);
@@ -256,158 +268,183 @@ public class TestInvoice extends TestJaxrsBase {
         Assert.assertNotNull(adjustedItemAuditLogJson.getUserToken());
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can partially adjust an invoice item")
     public void testPartialInvoiceItemAdjustment() throws Exception {
-        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<InvoiceJson> invoices = getInvoicesWithItemsForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
-        final InvoiceJson invoice = invoices.get(1);
+        final Invoice invoice = invoices.get(1);
         // Verify the invoice we picked is non zero
         assertEquals(invoice.getAmount().compareTo(BigDecimal.ZERO), 1);
-        final InvoiceItemJson invoiceItem = invoice.getItems().get(0);
+        final InvoiceItem invoiceItem = invoice.getItems().get(0);
         // Verify the item we picked is non zero
         assertEquals(invoiceItem.getAmount().compareTo(BigDecimal.ZERO), 1);
 
         // Adjust partially the item
         final BigDecimal adjustedAmount = invoiceItem.getAmount().divide(BigDecimal.TEN);
-        adjustInvoiceItem(accountJson.getAccountId(), invoice.getInvoiceId(), invoiceItem.getInvoiceItemId(), null, adjustedAmount, null);
+        final InvoiceItem adjustmentInvoiceItem = new InvoiceItem();
+        adjustmentInvoiceItem.setAccountId(accountJson.getAccountId());
+        adjustmentInvoiceItem.setInvoiceId(invoice.getInvoiceId());
+        adjustmentInvoiceItem.setInvoiceItemId(invoiceItem.getInvoiceItemId());
+        adjustmentInvoiceItem.setAmount(adjustedAmount);
+        adjustmentInvoiceItem.setCurrency(invoice.getCurrency());
+        killBillClient.adjustInvoiceItem(adjustmentInvoiceItem, createdBy, reason, comment);
 
         // Verify the new invoice balance
-        final InvoiceJson adjustedInvoice = getInvoice(invoice.getInvoiceId());
+        final Invoice adjustedInvoice = killBillClient.getInvoice(invoice.getInvoiceId());
         final BigDecimal adjustedInvoiceBalance = invoice.getBalance().add(adjustedAmount.negate()).setScale(2, BigDecimal.ROUND_HALF_UP);
-        assertEquals(adjustedInvoice.getBalance().compareTo(adjustedInvoiceBalance), 0);
+        assertEquals(adjustedInvoice.getBalance().compareTo(adjustedInvoiceBalance), 0, String.format("Adjusted invoice balance is %s, should be %s", adjustedInvoice.getBalance(), adjustedInvoiceBalance));
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create an external charge")
     public void testExternalChargeOnNewInvoice() throws Exception {
-        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
-        final InvoiceJson invoiceWithItems = createExternalCharge(accountJson.getAccountId(), chargeAmount, null, null, null, false);
+        final InvoiceItem externalCharge = new InvoiceItem();
+        externalCharge.setAccountId(accountJson.getAccountId());
+        externalCharge.setAmount(chargeAmount);
+        final Invoice invoiceWithItems = killBillClient.createExternalCharge(externalCharge, clock.getUTCNow(), false, createdBy, reason, comment);
         assertEquals(invoiceWithItems.getBalance().compareTo(chargeAmount), 0);
         assertEquals(invoiceWithItems.getItems().size(), 1);
         assertNull(invoiceWithItems.getItems().get(0).getBundleId());
 
         // Verify the total number of invoices
-        assertEquals(getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create an external charge and trigger a payment")
     public void testExternalChargeOnNewInvoiceWithAutomaticPayment() throws Exception {
-        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
-        final InvoiceJson invoiceWithItems = createExternalCharge(accountJson.getAccountId(), chargeAmount, null, null, null, true);
+        final InvoiceItem externalCharge = new InvoiceItem();
+        externalCharge.setAccountId(accountJson.getAccountId());
+        externalCharge.setAmount(chargeAmount);
+        final Invoice invoiceWithItems = killBillClient.createExternalCharge(externalCharge, clock.getUTCNow(), true, createdBy, reason, comment);
         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(getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
-
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create an external charge for a bundle")
     public void testExternalChargeForBundleOnNewInvoice() throws Exception {
-        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        assertEquals(getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 2);
 
         // Post an external charge
         final BigDecimal chargeAmount = BigDecimal.TEN;
-        final String bundleId = UUID.randomUUID().toString();
-        final InvoiceJson invoiceWithItems = createExternalCharge(accountJson.getAccountId(), chargeAmount, bundleId, null, null, false);
+        final UUID bundleId = UUID.randomUUID();
+        final InvoiceItem externalCharge = new InvoiceItem();
+        externalCharge.setAccountId(accountJson.getAccountId());
+        externalCharge.setAmount(chargeAmount);
+        externalCharge.setBundleId(bundleId);
+        final Invoice invoiceWithItems = killBillClient.createExternalCharge(externalCharge, clock.getUTCNow(), false, createdBy, reason, comment);
         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(getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
+        assertEquals(killBillClient.getInvoicesForAccount(accountJson.getAccountId()).size(), 3);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create an external charge on an existing invoice")
     public void testExternalChargeOnExistingInvoice() throws Exception {
-        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<InvoiceJson> invoices = getInvoicesWithItemsForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
-        final String invoiceId = invoices.get(1).getInvoiceId();
+        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
         final BigDecimal chargeAmount = BigDecimal.TEN;
-        final InvoiceJson invoiceWithItems = createExternalChargeForInvoice(accountJson.getAccountId(), invoiceId,
-                                                                            null, chargeAmount, null, null, false);
+        final InvoiceItem externalCharge = new InvoiceItem();
+        externalCharge.setAccountId(accountJson.getAccountId());
+        externalCharge.setAmount(chargeAmount);
+        externalCharge.setInvoiceId(invoiceId);
+        final Invoice invoiceWithItems = killBillClient.createExternalCharge(externalCharge, clock.getUTCNow(), false, createdBy, reason, comment);
         assertEquals(invoiceWithItems.getItems().size(), originalNumberOfItemsForInvoice + 1);
         assertNull(invoiceWithItems.getItems().get(originalNumberOfItemsForInvoice).getBundleId());
 
         // Verify the new invoice balance
-        final InvoiceJson adjustedInvoice = getInvoice(invoiceId);
+        final Invoice adjustedInvoice = killBillClient.getInvoice(invoiceId);
         final BigDecimal adjustedInvoiceBalance = originalInvoiceAmount.add(chargeAmount.setScale(2, RoundingMode.HALF_UP));
         assertEquals(adjustedInvoice.getBalance().compareTo(adjustedInvoiceBalance), 0);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create an external charge on an existing invoice and trigger a payment")
     public void testExternalChargeOnExistingInvoiceWithAutomaticPayment() throws Exception {
-        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<InvoiceJson> invoices = getInvoicesWithItemsForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
-        final String invoiceId = invoices.get(1).getInvoiceId();
+        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
         final BigDecimal chargeAmount = BigDecimal.TEN;
-        final InvoiceJson invoiceWithItems = createExternalChargeForInvoice(accountJson.getAccountId(), invoiceId,
-                                                                            null, chargeAmount, null, null, true);
+        final InvoiceItem externalCharge = new InvoiceItem();
+        externalCharge.setAccountId(accountJson.getAccountId());
+        externalCharge.setAmount(chargeAmount);
+        externalCharge.setInvoiceId(invoiceId);
+        final Invoice invoiceWithItems = killBillClient.createExternalCharge(externalCharge, clock.getUTCNow(), true, createdBy, reason, comment);
         assertEquals(invoiceWithItems.getItems().size(), originalNumberOfItemsForInvoice + 1);
         assertNull(invoiceWithItems.getItems().get(originalNumberOfItemsForInvoice).getBundleId());
 
         // Verify the new invoice balance
-        final InvoiceJson adjustedInvoice = getInvoice(invoiceId);
+        final Invoice adjustedInvoice = killBillClient.getInvoice(invoiceId);
         assertEquals(adjustedInvoice.getBalance().compareTo(BigDecimal.ZERO), 0);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create an external charge for a bundle on an existing invoice")
     public void testExternalChargeForBundleOnExistingInvoice() throws Exception {
-        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<InvoiceJson> invoices = getInvoicesWithItemsForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true);
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
-        final String invoiceId = invoices.get(1).getInvoiceId();
+        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
         final BigDecimal chargeAmount = BigDecimal.TEN;
-        final String bundleId = UUID.randomUUID().toString();
-        final InvoiceJson invoiceWithItems = createExternalChargeForInvoice(accountJson.getAccountId(), invoiceId,
-                                                                            bundleId, chargeAmount, null, null, false);
+        final UUID bundleId = UUID.randomUUID();
+        final InvoiceItem externalCharge = new InvoiceItem();
+        externalCharge.setAccountId(accountJson.getAccountId());
+        externalCharge.setAmount(chargeAmount);
+        externalCharge.setInvoiceId(invoiceId);
+        externalCharge.setBundleId(bundleId);
+        final Invoice invoiceWithItems = killBillClient.createExternalCharge(externalCharge, clock.getUTCNow(), false, createdBy, reason, comment);
         assertEquals(invoiceWithItems.getItems().size(), originalNumberOfItemsForInvoice + 1);
         assertEquals(invoiceWithItems.getItems().get(originalNumberOfItemsForInvoice).getBundleId(), bundleId);
 
         // Verify the new invoice balance
-        final InvoiceJson adjustedInvoice = getInvoice(invoiceId);
+        final Invoice adjustedInvoice = killBillClient.getInvoice(invoiceId);
         final BigDecimal adjustedInvoiceBalance = originalInvoiceAmount.add(chargeAmount.setScale(2, RoundingMode.HALF_UP));
         assertEquals(adjustedInvoice.getBalance().compareTo(adjustedInvoiceBalance), 0);
     }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java
index 7c587d9..8d69d9a 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoiceNotification.java
@@ -17,7 +17,6 @@
 package com.ning.billing.jaxrs;
 
 import java.util.List;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.testng.Assert;
@@ -25,42 +24,32 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.InvoiceJson;
-import com.ning.billing.jaxrs.json.SubscriptionJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.http.client.Response;
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.google.common.collect.ImmutableMap;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Invoice;
+import com.ning.billing.client.model.Subscription;
 
 public class TestInvoiceNotification extends TestJaxrsBase {
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can trigger an invoice notification")
     public void testTriggerNotification() throws Exception {
-        final AccountJson accountJson = createScenarioWithOneInvoice();
+        final Account accountJson = createScenarioWithOneInvoice();
 
-        final String uri = JaxrsResource.INVOICES_PATH;
-        final Response response = doGet(JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.INVOICES, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-        final String baseJson = response.getResponseBody();
-        final List<InvoiceJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<InvoiceJson>>() {});
-        Assert.assertEquals(objFromJson.size(), 1);
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
+        Assert.assertEquals(invoices.size(), 1);
 
-        final InvoiceJson invoice = objFromJson.get(0);
-        final Response triggerResponse = doPost(uri + "/" + invoice.getInvoiceId() + "/" + JaxrsResource.EMAIL_NOTIFICATIONS,
-                                                null, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(triggerResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final Invoice invoice = invoices.get(0);
+        killBillClient.triggerInvoiceNotification(invoice.getInvoiceId(), createdBy, reason, comment);
     }
 
-    private AccountJson createScenarioWithOneInvoice() throws Exception {
+    private Account createScenarioWithOneInvoice() throws Exception {
         final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
 
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        final Account accountJson = createAccountWithDefaultPaymentMethod();
         Assert.assertNotNull(accountJson);
 
-        final SubscriptionJson subscriptionJson = createEntitlement(accountJson.getAccountId(), "76213", "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        final Subscription subscriptionJson = createEntitlement(accountJson.getAccountId(), "76213", "Shotgun",
+                                                                ProductCategory.BASE, BillingPeriod.MONTHLY, true);
         Assert.assertNotNull(subscriptionJson);
 
         return accountJson;
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
index b8a5659..c65501a 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -45,6 +45,9 @@ import com.ning.billing.api.TestApiListener;
 import com.ning.billing.beatrix.glue.BeatrixModule;
 import com.ning.billing.bus.api.PersistentBus;
 import com.ning.billing.catalog.glue.CatalogModule;
+import com.ning.billing.client.KillBillClient;
+import com.ning.billing.client.KillBillHttpClient;
+import com.ning.billing.client.model.Tenant;
 import com.ning.billing.commons.embeddeddb.EmbeddedDB;
 import com.ning.billing.currency.glue.CurrencyModule;
 import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
@@ -81,14 +84,9 @@ import com.ning.billing.util.glue.NotificationQueueModule;
 import com.ning.billing.util.glue.RecordIdModule;
 import com.ning.billing.util.glue.SecurityModule;
 import com.ning.billing.util.glue.TagStoreModule;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.AsyncHttpClientConfig;
 import com.ning.jetty.core.CoreConfig;
 import com.ning.jetty.core.server.HttpServer;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.datatype.joda.JodaModule;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.inject.Module;
@@ -108,13 +106,14 @@ public class TestJaxrsBase extends KillbillClient {
     protected CacheControllerDispatcher cacheControllerDispatcher;
 
     @Inject
-    protected @javax.inject.Named(BeatrixModule.EXTERNAL_BUS)PersistentBus externalBus;
+    protected @javax.inject.Named(BeatrixModule.EXTERNAL_BUS) PersistentBus externalBus;
 
     @Inject
     protected PersistentBus internalBus;
 
     protected static TestKillbillGuiceListener listener;
 
+    protected CoreConfig config;
     private HttpServer server;
     protected TestApiListener busHandler;
 
@@ -132,7 +131,6 @@ public class TestJaxrsBase extends KillbillClient {
 
         private final EmbeddedDB helper;
 
-
         public TestKillbillGuiceListener(final EmbeddedDB helper) {
             super();
             this.helper = helper;
@@ -201,7 +199,6 @@ public class TestJaxrsBase extends KillbillClient {
 
             install(new GuicyKillbillTestWithEmbeddedDBModule());
 
-
             install(new EmailModule(configSource));
             install(new CacheModule(configSource));
             install(new NonEntityDaoModule());
@@ -236,6 +233,35 @@ public class TestJaxrsBase extends KillbillClient {
         }
     }
 
+    protected void setupClient(final String username, final String password, final String apiKey, final String apiSecret) {
+        killBillHttpClient = new KillBillHttpClient(String.format("http://%s:%d", config.getServerHost(), config.getServerPort()),
+                                                    username,
+                                                    password,
+                                                    apiKey,
+                                                    apiSecret);
+        killBillClient = new KillBillClient(killBillHttpClient);
+    }
+
+    protected void loginTenant(final String apiKey, final String apiSecret) {
+        setupClient(USERNAME, PASSWORD, apiKey, apiSecret);
+    }
+
+    protected void logoutTenant() {
+        setupClient(USERNAME, PASSWORD, null, null);
+    }
+
+    protected void login() {
+        login(USERNAME, PASSWORD);
+    }
+
+    protected void login(final String username, final String password) {
+        setupClient(username, password, DEFAULT_API_KEY, DEFAULT_API_SECRET);
+    }
+
+    protected void logout() {
+        setupClient(null, null, null, null);
+    }
+
     @BeforeMethod(groups = "slow")
     public void beforeMethod() throws Exception {
         super.beforeMethod();
@@ -246,14 +272,18 @@ public class TestJaxrsBase extends KillbillClient {
         clock.resetDeltaFromReality();
         clock.setDay(new LocalDate(2012, 8, 25));
 
-        loginAsAdmin();
+        loginTenant(DEFAULT_API_KEY, DEFAULT_API_SECRET);
 
         // Recreate the tenant (tables have been cleaned-up)
-        createTenant(DEFAULT_API_KEY, DEFAULT_API_SECRET);
+        final Tenant tenant = new Tenant();
+        tenant.setApiKey(DEFAULT_API_KEY);
+        tenant.setApiSecret(DEFAULT_API_SECRET);
+        killBillClient.createTenant(tenant, createdBy, reason, comment);
     }
 
     @AfterMethod(groups = "slow")
     public void afterMethod() throws Exception {
+        killBillClient.close();
         externalBus.stop();
         internalBus.stop();
     }
@@ -264,12 +294,6 @@ public class TestJaxrsBase extends KillbillClient {
 
         listener.getInstantiatedInjector().injectMembers(this);
 
-        httpClient = new AsyncHttpClient(new AsyncHttpClientConfig.Builder().setRequestTimeoutInMs(DEFAULT_HTTP_TIMEOUT_SEC * 1000).build());
-
-        mapper = new ObjectMapper();
-        mapper.registerModule(new JodaModule());
-        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
-
         busHandler = new TestApiListener(null, dbi);
     }
 
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestOverdue.java b/server/src/test/java/com/ning/billing/jaxrs/TestOverdue.java
index 1e67816..1334103 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestOverdue.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestOverdue.java
@@ -22,43 +22,47 @@ import java.util.List;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.InvoiceJson;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Invoice;
+import com.ning.billing.client.model.Payment;
 
 import static org.testng.Assert.assertEquals;
 
 public class TestOverdue extends TestJaxrsBase {
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can retrieve the account overdue status")
     public void testOverdueStatus() throws Exception {
         // Create an account without a payment method
-        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
+        final Account accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Get the invoices
-        final List<InvoiceJson> invoices = getInvoicesWithItemsForAccount(accountJson.getAccountId());
+        final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId());
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
-        final String bundleId = invoices.get(1).getItems().get(0).getBundleId();
 
         // We're still clear - see the configuration
-        Assert.assertTrue(getOverdueStateForAccount(accountJson.getAccountId()).isClearState());
+        Assert.assertTrue(killBillClient.getOverdueStateForAccount(accountJson.getAccountId()).getIsClearState());
 
         clock.addDays(30);
         crappyWaitForLackOfProperSynchonization();
-        Assert.assertEquals(getOverdueStateForAccount(accountJson.getAccountId()).getName(), "OD1");
+        Assert.assertEquals(killBillClient.getOverdueStateForAccount(accountJson.getAccountId()).getName(), "OD1");
 
         clock.addDays(10);
         crappyWaitForLackOfProperSynchonization();
-        Assert.assertEquals(getOverdueStateForAccount(accountJson.getAccountId()).getName(), "OD2");
+        Assert.assertEquals(killBillClient.getOverdueStateForAccount(accountJson.getAccountId()).getName(), "OD2");
 
         clock.addDays(10);
         crappyWaitForLackOfProperSynchonization();
-        Assert.assertEquals(getOverdueStateForAccount(accountJson.getAccountId()).getName(), "OD3");
+        Assert.assertEquals(killBillClient.getOverdueStateForAccount(accountJson.getAccountId()).getName(), "OD3");
 
         // Post external payments
-        for (final InvoiceJson invoice : getInvoicesForAccount(accountJson.getAccountId())) {
+        for (final Invoice invoice : killBillClient.getInvoicesForAccount(accountJson.getAccountId())) {
             if (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0) {
-                createExternalPayment(accountJson, invoice.getInvoiceId(), invoice.getBalance());
+                final Payment payment = new Payment();
+                payment.setAccountId(accountJson.getAccountId());
+                payment.setInvoiceId(invoice.getInvoiceId());
+                payment.setAmount(invoice.getBalance());
+                killBillClient.createPayment(payment, true, createdBy, reason, comment);
             }
         }
 
@@ -66,6 +70,6 @@ public class TestOverdue extends TestJaxrsBase {
         crappyWaitForLackOfProperSynchonization();
 
         // Verify we're in clear state
-        Assert.assertTrue(getOverdueStateForAccount(accountJson.getAccountId()).isClearState());
+        Assert.assertTrue(killBillClient.getOverdueStateForAccount(accountJson.getAccountId()).getIsClearState());
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java b/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
index 321903c..96560de 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
@@ -16,134 +16,162 @@
 
 package com.ning.billing.jaxrs;
 
-import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.List;
+import java.util.UUID;
 
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.InvoiceItemJson;
-import com.ning.billing.jaxrs.json.InvoiceJson;
-import com.ning.billing.jaxrs.json.PaymentJson;
-import com.ning.billing.jaxrs.json.PaymentMethodJson;
-import com.ning.billing.jaxrs.json.RefundJson;
+import com.ning.billing.client.KillBillClientException;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Invoice;
+import com.ning.billing.client.model.InvoiceItem;
+import com.ning.billing.client.model.Payment;
+import com.ning.billing.client.model.PaymentMethod;
+import com.ning.billing.client.model.Refund;
 import com.ning.billing.payment.api.RefundStatus;
 
+import com.google.common.collect.ImmutableList;
+
 public class TestPayment extends TestJaxrsBase {
 
     @Test(groups = "slow")
     public void testRetrievePayment() throws Exception {
-        final PaymentJson paymentJson = setupScenarioWithPayment();
+        final Payment paymentJson = setupScenarioWithPayment();
 
-        final PaymentJson retrievedPaymentJson = getPayment(paymentJson.getPaymentId());
+        final Payment retrievedPaymentJson = killBillClient.getPayment(paymentJson.getPaymentId(), false);
         Assert.assertEquals(retrievedPaymentJson, paymentJson);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create a full refund with no adjustment")
     public void testFullRefundWithNoAdjustment() throws Exception {
-        final PaymentJson paymentJson = setupScenarioWithPayment();
+        final Payment paymentJson = setupScenarioWithPayment();
 
         // Issue a refund for the full amount
         final BigDecimal refundAmount = paymentJson.getAmount();
         final BigDecimal expectedInvoiceBalance = refundAmount;
 
         // Post and verify the refund
-        final RefundJson refundJsonCheck = createRefund(paymentJson.getPaymentId(), refundAmount);
+        final Refund refund = new Refund();
+        refund.setPaymentId(paymentJson.getPaymentId());
+        refund.setAmount(refundAmount);
+        final Refund refundJsonCheck = killBillClient.createRefund(refund, createdBy, reason, comment);
         verifyRefund(paymentJson, refundJsonCheck, refundAmount);
 
         // Verify the invoice balance
         verifyInvoice(paymentJson, expectedInvoiceBalance);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create a partial refund with no adjustment")
     public void testPartialRefundWithNoAdjustment() throws Exception {
-        final PaymentJson paymentJson = setupScenarioWithPayment();
+        final Payment paymentJson = setupScenarioWithPayment();
 
         // Issue a refund for a fraction of the amount
         final BigDecimal refundAmount = getFractionOfAmount(paymentJson.getAmount());
         final BigDecimal expectedInvoiceBalance = refundAmount;
 
         // Post and verify the refund
-        final RefundJson refundJsonCheck = createRefund(paymentJson.getPaymentId(), refundAmount);
+        final Refund refund = new Refund();
+        refund.setPaymentId(paymentJson.getPaymentId());
+        refund.setAmount(refundAmount);
+        final Refund refundJsonCheck = killBillClient.createRefund(refund, createdBy, reason, comment);
         verifyRefund(paymentJson, refundJsonCheck, refundAmount);
 
         // Verify the invoice balance
         verifyInvoice(paymentJson, expectedInvoiceBalance);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create a full refund with invoice adjustment")
     public void testFullRefundWithInvoiceAdjustment() throws Exception {
-        final PaymentJson paymentJson = setupScenarioWithPayment();
+        final Payment paymentJson = setupScenarioWithPayment();
 
         // Issue a refund for the full amount
         final BigDecimal refundAmount = paymentJson.getAmount();
         final BigDecimal expectedInvoiceBalance = BigDecimal.ZERO;
 
         // Post and verify the refund
-        final RefundJson refundJsonCheck = createRefundWithInvoiceAdjustment(paymentJson.getPaymentId(), refundAmount);
+        final Refund refund = new Refund();
+        refund.setPaymentId(paymentJson.getPaymentId());
+        refund.setAmount(refundAmount);
+        refund.setAdjusted(true);
+        final Refund refundJsonCheck = killBillClient.createRefund(refund, createdBy, reason, comment);
         verifyRefund(paymentJson, refundJsonCheck, refundAmount);
 
         // Verify the invoice balance
         verifyInvoice(paymentJson, expectedInvoiceBalance);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create a partial refund with invoice adjustment")
     public void testPartialRefundWithInvoiceAdjustment() throws Exception {
-        final PaymentJson paymentJson = setupScenarioWithPayment();
+        final Payment paymentJson = setupScenarioWithPayment();
 
         // Issue a refund for a fraction of the amount
         final BigDecimal refundAmount = getFractionOfAmount(paymentJson.getAmount());
         final BigDecimal expectedInvoiceBalance = BigDecimal.ZERO;
 
         // Post and verify the refund
-        final RefundJson refundJsonCheck = createRefundWithInvoiceAdjustment(paymentJson.getPaymentId(), refundAmount);
+        final Refund refund = new Refund();
+        refund.setPaymentId(paymentJson.getPaymentId());
+        refund.setAmount(refundAmount);
+        refund.setAdjusted(true);
+        final Refund refundJsonCheck = killBillClient.createRefund(refund, createdBy, reason, comment);
         verifyRefund(paymentJson, refundJsonCheck, refundAmount);
 
         // Verify the invoice balance
         verifyInvoice(paymentJson, expectedInvoiceBalance);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create a full refund with invoice item adjustment")
     public void testRefundWithFullInvoiceItemAdjustment() throws Exception {
-        final PaymentJson paymentJson = setupScenarioWithPayment();
+        final Payment paymentJson = setupScenarioWithPayment();
 
         // Get the individual items for the invoice
-        final InvoiceJson invoice = getInvoiceWithItems(paymentJson.getInvoiceId());
-        final InvoiceItemJson itemToAdjust = invoice.getItems().get(0);
+        final Invoice invoice = killBillClient.getInvoice(paymentJson.getInvoiceId(), true);
+        final InvoiceItem itemToAdjust = invoice.getItems().get(0);
 
         // Issue a refund for the full amount
         final BigDecimal refundAmount = itemToAdjust.getAmount();
         final BigDecimal expectedInvoiceBalance = BigDecimal.ZERO;
 
         // Post and verify the refund
-        final RefundJson refundJsonCheck = createRefundWithInvoiceItemAdjustment(paymentJson.getPaymentId(),
-                                                                                 itemToAdjust.getInvoiceItemId(),
-                                                                                 null /* null means full adjustment for that item */);
+        final Refund refund = new Refund();
+        refund.setPaymentId(paymentJson.getPaymentId());
+        refund.setAmount(refundAmount);
+        refund.setAdjusted(true);
+        final InvoiceItem adjustment = new InvoiceItem();
+        adjustment.setInvoiceItemId(itemToAdjust.getInvoiceItemId());
+        /* null amount means full adjustment for that item */
+        refund.setAdjustments(ImmutableList.<InvoiceItem>of(adjustment));
+        final Refund refundJsonCheck = killBillClient.createRefund(refund, createdBy, reason, comment);
         verifyRefund(paymentJson, refundJsonCheck, refundAmount);
 
         // Verify the invoice balance
         verifyInvoice(paymentJson, expectedInvoiceBalance);
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create a partial refund with invoice item adjustment")
     public void testPartialRefundWithInvoiceItemAdjustment() throws Exception {
-        final PaymentJson paymentJson = setupScenarioWithPayment();
+        final Payment paymentJson = setupScenarioWithPayment();
 
         // Get the individual items for the invoice
-        final InvoiceJson invoice = getInvoiceWithItems(paymentJson.getInvoiceId());
-        final InvoiceItemJson itemToAdjust = invoice.getItems().get(0);
+        final Invoice invoice = killBillClient.getInvoice(paymentJson.getInvoiceId(), true);
+        final InvoiceItem itemToAdjust = invoice.getItems().get(0);
 
         // Issue a refund for a fraction of the amount
         final BigDecimal refundAmount = getFractionOfAmount(itemToAdjust.getAmount());
         final BigDecimal expectedInvoiceBalance = BigDecimal.ZERO;
 
         // Post and verify the refund
-        final RefundJson refundJsonCheck = createRefundWithInvoiceItemAdjustment(paymentJson.getPaymentId(),
-                                                                                 itemToAdjust.getInvoiceItemId(),
-                                                                                 refundAmount);
+        final Refund refund = new Refund();
+        refund.setPaymentId(paymentJson.getPaymentId());
+        refund.setAdjusted(true);
+        final InvoiceItem adjustment = new InvoiceItem();
+        adjustment.setInvoiceItemId(itemToAdjust.getInvoiceItemId());
+        adjustment.setAmount(refundAmount);
+        refund.setAdjustments(ImmutableList.<InvoiceItem>of(adjustment));
+        final Refund refundJsonCheck = killBillClient.createRefund(refund, createdBy, reason, comment);
         verifyRefund(paymentJson, refundJsonCheck, refundAmount);
 
         // Verify the invoice balance
@@ -154,27 +182,27 @@ public class TestPayment extends TestJaxrsBase {
         return amount.divide(BigDecimal.TEN).setScale(2, BigDecimal.ROUND_HALF_UP);
     }
 
-    private PaymentJson setupScenarioWithPayment() throws Exception {
-        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+    private Payment setupScenarioWithPayment() throws Exception {
+        final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final List<PaymentJson> firstPaymentForAccount = getPaymentsForAccount(accountJson.getAccountId());
+        final List<Payment> firstPaymentForAccount = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
         Assert.assertEquals(firstPaymentForAccount.size(), 1);
 
-        final PaymentJson paymentJson = firstPaymentForAccount.get(0);
+        final Payment paymentJson = firstPaymentForAccount.get(0);
 
         // Check the PaymentMethod from paymentMethodId returned in the Payment object
-        final String paymentMethodId = paymentJson.getPaymentMethodId();
-        final PaymentMethodJson paymentMethodJson = getPaymentMethodWithPluginInfo(paymentMethodId);
+        final UUID paymentMethodId = paymentJson.getPaymentMethodId();
+        final PaymentMethod paymentMethodJson = killBillClient.getPaymentMethod(paymentMethodId, true);
         Assert.assertEquals(paymentMethodJson.getPaymentMethodId(), paymentMethodId);
         Assert.assertEquals(paymentMethodJson.getAccountId(), accountJson.getAccountId());
 
         // Verify the refunds
-        final List<RefundJson> objRefundFromJson = getRefundsForPayment(paymentJson.getPaymentId());
+        final List<Refund> objRefundFromJson = killBillClient.getRefundsForPayment(paymentJson.getPaymentId());
         Assert.assertEquals(objRefundFromJson.size(), 0);
         return paymentJson;
     }
 
-    private void verifyRefund(final PaymentJson paymentJson, final RefundJson refundJsonCheck, final BigDecimal refundAmount) throws IOException {
+    private void verifyRefund(final Payment paymentJson, final Refund refundJsonCheck, final BigDecimal refundAmount) throws KillBillClientException {
         Assert.assertEquals(refundJsonCheck.getPaymentId(), paymentJson.getPaymentId());
         Assert.assertEquals(refundJsonCheck.getAmount().setScale(2, RoundingMode.HALF_UP), refundAmount.setScale(2, RoundingMode.HALF_UP));
         Assert.assertEquals(refundJsonCheck.getCurrency(), DEFAULT_CURRENCY);
@@ -187,11 +215,11 @@ public class TestPayment extends TestJaxrsBase {
         Assert.assertEquals(refundJsonCheck.getRequestedDate().getDayOfMonth(), clock.getUTCNow().getDayOfMonth());
 
         // Verify the refunds
-        final List<RefundJson> retrievedRefunds = getRefundsForPayment(paymentJson.getPaymentId());
+        final List<Refund> retrievedRefunds = killBillClient.getRefundsForPayment(paymentJson.getPaymentId());
         Assert.assertEquals(retrievedRefunds.size(), 1);
 
         // Verify the refund via the payment API
-        final PaymentJson retrievedPaymentJson = getPaymentWithRefundsAndChargebacks(paymentJson.getPaymentId());
+        final Payment retrievedPaymentJson = killBillClient.getPayment(paymentJson.getPaymentId(), true);
         Assert.assertEquals(retrievedPaymentJson.getPaymentId(), paymentJson.getPaymentId());
         Assert.assertEquals(retrievedPaymentJson.getPaidAmount().setScale(2, RoundingMode.HALF_UP), paymentJson.getPaidAmount().add(refundAmount.negate()).setScale(2, RoundingMode.HALF_UP));
         Assert.assertEquals(retrievedPaymentJson.getAmount().setScale(2, RoundingMode.HALF_UP), paymentJson.getAmount().setScale(2, RoundingMode.HALF_UP));
@@ -210,8 +238,8 @@ public class TestPayment extends TestJaxrsBase {
         Assert.assertEquals(retrievedPaymentJson.getRefunds().get(0), refundJsonCheck);
     }
 
-    private void verifyInvoice(final PaymentJson paymentJson, final BigDecimal expectedInvoiceBalance) throws IOException {
-        final InvoiceJson invoiceJson = getInvoice(paymentJson.getInvoiceId());
+    private void verifyInvoice(final Payment paymentJson, final BigDecimal expectedInvoiceBalance) throws KillBillClientException {
+        final Invoice invoiceJson = killBillClient.getInvoice(paymentJson.getInvoiceId());
         Assert.assertEquals(invoiceJson.getBalance().setScale(2, BigDecimal.ROUND_HALF_UP),
                             expectedInvoiceBalance.setScale(2, BigDecimal.ROUND_HALF_UP));
     }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestPaymentMethod.java b/server/src/test/java/com/ning/billing/jaxrs/TestPaymentMethod.java
index 4d1e2f8..1ebb0e4 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestPaymentMethod.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPaymentMethod.java
@@ -22,24 +22,24 @@ import java.util.UUID;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.PaymentMethodJson;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.PaymentMethod;
 
 public class TestPaymentMethod extends TestJaxrsBase {
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can search payment methods")
     public void testSearchPaymentMethods() throws Exception {
         // Search random key
-        Assert.assertEquals(searchPaymentMethodsByKey(UUID.randomUUID().toString()).size(), 0);
-        Assert.assertEquals(searchPaymentMethodsByKeyAndPlugin(UUID.randomUUID().toString(), PLUGIN_NAME).size(), 0);
+        Assert.assertEquals(killBillClient.searchPaymentMethodsByKey(UUID.randomUUID().toString()).size(), 0);
+        Assert.assertEquals(killBillClient.searchPaymentMethodsByKeyAndPlugin(UUID.randomUUID().toString(), PLUGIN_NAME).size(), 0);
 
         // Create a payment method
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod();
-        final PaymentMethodJson paymentMethodJson = getPaymentMethodWithPluginInfo(accountJson.getPaymentMethodId());
+        final Account accountJson = createAccountWithDefaultPaymentMethod();
+        final PaymentMethod paymentMethodJson = killBillClient.getPaymentMethod(accountJson.getPaymentMethodId(), true);
 
         // Search random key again
-        Assert.assertEquals(searchPaymentMethodsByKey(UUID.randomUUID().toString()).size(), 0);
-        Assert.assertEquals(searchPaymentMethodsByKeyAndPlugin(UUID.randomUUID().toString(), PLUGIN_NAME).size(), 0);
+        Assert.assertEquals(killBillClient.searchPaymentMethodsByKey(UUID.randomUUID().toString()).size(), 0);
+        Assert.assertEquals(killBillClient.searchPaymentMethodsByKeyAndPlugin(UUID.randomUUID().toString(), PLUGIN_NAME).size(), 0);
 
         // Make sure we can search the test plugin
         // Values are hardcoded in TestPaymentMethodPluginBase and the search logic is in MockPaymentProviderPlugin
@@ -56,12 +56,12 @@ public class TestPaymentMethod extends TestJaxrsBase {
         doSearch("Zimbawe", paymentMethodJson);
     }
 
-    private void doSearch(final String searchKey, final PaymentMethodJson paymentMethodJson) throws Exception {
-        final List<PaymentMethodJson> results1 = searchPaymentMethodsByKey(searchKey);
+    private void doSearch(final String searchKey, final PaymentMethod paymentMethodJson) throws Exception {
+        final List<PaymentMethod> results1 = killBillClient.searchPaymentMethodsByKey(searchKey);
         Assert.assertEquals(results1.size(), 1);
         Assert.assertEquals(results1.get(0), paymentMethodJson);
 
-        final List<PaymentMethodJson> results2 = searchPaymentMethodsByKeyAndPlugin(searchKey, PLUGIN_NAME);
+        final List<PaymentMethod> results2 = killBillClient.searchPaymentMethodsByKeyAndPlugin(searchKey, PLUGIN_NAME);
         Assert.assertEquals(results2.size(), 1);
         Assert.assertEquals(results2.get(0), paymentMethodJson);
     }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestPlugin.java b/server/src/test/java/com/ning/billing/jaxrs/TestPlugin.java
index 7d4ec76..db0338e 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestPlugin.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPlugin.java
@@ -67,22 +67,22 @@ public class TestPlugin extends TestJaxrsBase {
 
         // We don't test the output here as it is some Jetty specific HTML blurb
 
-        response = pluginGET(uri);
+        response = killBillClient.pluginGET(uri);
         testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
 
-        response = pluginHEAD(uri);
+        response = killBillClient.pluginHEAD(uri);
         testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
 
-        response = pluginPOST(uri, null);
+        response = killBillClient.pluginPOST(uri, null);
         testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
 
-        response = pluginPUT(uri, null);
+        response = killBillClient.pluginPUT(uri, null);
         testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
 
-        response = pluginDELETE(uri);
+        response = killBillClient.pluginDELETE(uri);
         testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
 
-        response = pluginOPTIONS(uri);
+        response = killBillClient.pluginOPTIONS(uri);
         testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
     }
 
@@ -91,22 +91,22 @@ public class TestPlugin extends TestJaxrsBase {
         final String uri = TEST_PLUGIN_NAME + "/somethingSomething";
         Response response;
 
-        response = pluginGET(uri);
+        response = killBillClient.pluginGET(uri);
         testAndResetAllMarkers(response, 200, new byte[]{}, false, false, false, false, false, false);
 
-        response = pluginHEAD(uri);
+        response = killBillClient.pluginHEAD(uri);
         testAndResetAllMarkers(response, 204, new byte[]{}, false, false, false, false, false, false);
 
-        response = pluginPOST(uri, null);
+        response = killBillClient.pluginPOST(uri, null);
         testAndResetAllMarkers(response, 200, new byte[]{}, false, false, false, false, false, false);
 
-        response = pluginPUT(uri, null);
+        response = killBillClient.pluginPUT(uri, null);
         testAndResetAllMarkers(response, 200, new byte[]{}, false, false, false, false, false, false);
 
-        response = pluginDELETE(uri);
+        response = killBillClient.pluginDELETE(uri);
         testAndResetAllMarkers(response, 200, new byte[]{}, false, false, false, false, false, false);
 
-        response = pluginOPTIONS(uri);
+        response = killBillClient.pluginOPTIONS(uri);
         testAndResetAllMarkers(response, 200, new byte[]{}, false, false, false, false, false, false);
     }
 
@@ -114,30 +114,35 @@ public class TestPlugin extends TestJaxrsBase {
     public void testPassRequestsToKnownPluginAndKnownPath() throws Exception {
         Response response;
 
-        response = pluginGET(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_GET_PATH);
+        response = killBillClient.pluginGET(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_GET_PATH);
         testAndResetAllMarkers(response, 230, TEST_PLUGIN_RESPONSE_BYTES, true, false, false, false, false, false);
 
-        response = pluginHEAD(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_HEAD_PATH);
+        response = killBillClient.pluginHEAD(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_HEAD_PATH);
         testAndResetAllMarkers(response, 204, new byte[]{}, false, true, false, false, false, false);
 
-        response = pluginPOST(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_POST_PATH, null);
+        response = killBillClient.pluginPOST(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_POST_PATH, null);
         testAndResetAllMarkers(response, 230, TEST_PLUGIN_RESPONSE_BYTES, false, false, true, false, false, false);
 
-        response = pluginPUT(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_PUT_PATH, null);
+        response = killBillClient.pluginPUT(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_PUT_PATH, null);
         testAndResetAllMarkers(response, 230, TEST_PLUGIN_RESPONSE_BYTES, false, false, false, true, false, false);
 
-        response = pluginDELETE(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_DELETE_PATH);
+        response = killBillClient.pluginDELETE(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_DELETE_PATH);
         testAndResetAllMarkers(response, 230, TEST_PLUGIN_RESPONSE_BYTES, false, false, false, false, true, false);
 
-        response = pluginOPTIONS(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_OPTIONS_PATH);
+        response = killBillClient.pluginOPTIONS(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_OPTIONS_PATH);
         testAndResetAllMarkers(response, 230, TEST_PLUGIN_RESPONSE_BYTES, false, false, false, false, false, true);
     }
 
-    private void testAndResetAllMarkers(final Response response, final int responseCode, @Nullable final byte[] responseBytes, final boolean get, final boolean head,
+    private void testAndResetAllMarkers(@Nullable final Response response, final int responseCode, @Nullable final byte[] responseBytes, final boolean get, final boolean head,
                                         final boolean post, final boolean put, final boolean delete, final boolean options) throws IOException {
-        Assert.assertEquals(response.getStatusCode(), responseCode);
-        if (responseBytes != null) {
-            Assert.assertEquals(response.getResponseBodyAsBytes(), responseBytes);
+        if (responseCode == 404 || responseCode == 204) {
+            Assert.assertNull(response);
+        } else {
+            Assert.assertNotNull(response);
+            Assert.assertEquals(response.getStatusCode(), responseCode);
+            if (responseBytes != null) {
+                Assert.assertEquals(response.getResponseBodyAsBytes(), responseBytes);
+            }
         }
 
         Assert.assertEquals(requestGETMarker.get(), get);
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestPushNotification.java b/server/src/test/java/com/ning/billing/jaxrs/TestPushNotification.java
index 68d5a6d..135cf13 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestPushNotification.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPushNotification.java
@@ -13,10 +13,12 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.jaxrs;
 
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.util.UUID;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.servlet.ServletException;
@@ -41,16 +43,14 @@ import com.google.common.io.CharStreams;
 
 public class TestPushNotification extends TestJaxrsBase {
 
-
     private CallbackServer callbackServer;
 
-    private final static int SERVER_PORT = 8087;
-    private final static String CALLBACK_ENDPPOINT = "/callmeback";
+    private static final int SERVER_PORT = 8087;
+    private static final String CALLBACK_ENDPPOINT = "/callmeback";
 
     private volatile boolean callbackCompleted;
     private volatile boolean callbackCompletedWithError;
 
-
     @Override
     @BeforeMethod(groups = "slow")
     public void beforeMethod() throws Exception {
@@ -67,7 +67,6 @@ public class TestPushNotification extends TestJaxrsBase {
     }
 
     private boolean waitForCallbacksToComplete() throws InterruptedException {
-
         long remainingMs = 20000;
         do {
             if (callbackCompleted) {
@@ -82,8 +81,8 @@ public class TestPushNotification extends TestJaxrsBase {
     public void retrieveAccountWithAsserts(final String accountId) {
         try {
             // Just check we can retrieve the account with the id from the callback
-            /* final AccountJson account = */ getAccountById(accountId);
-        } catch(final Exception e) {
+            killBillClient.getAccount(UUID.fromString(accountId));
+        } catch (final Exception e) {
             Assert.fail(e.getMessage());
         }
     }
@@ -91,7 +90,7 @@ public class TestPushNotification extends TestJaxrsBase {
     @Test(groups = "slow")
     public void testPushNotification() throws Exception {
         // Register tenant for callback
-        registerCallbackNotificationForTenant("http://127.0.0.1:" + SERVER_PORT + CALLBACK_ENDPPOINT);
+        killBillClient.registerCallbackNotificationForTenant("http://127.0.0.1:" + SERVER_PORT + CALLBACK_ENDPPOINT, createdBy, reason, comment);
         // Create account to trigger a push notification
         createAccount();
 
@@ -117,7 +116,7 @@ public class TestPushNotification extends TestJaxrsBase {
         private final TestPushNotification test;
 
         public CallbackServer(final TestPushNotification test, final int port, final String callbackEndpoint) {
-            this.callbackEndpoint =  callbackEndpoint;
+            this.callbackEndpoint = callbackEndpoint;
             this.test = test;
             this.server = new Server(port);
         }
@@ -126,7 +125,7 @@ public class TestPushNotification extends TestJaxrsBase {
             final ServletContextHandler context = new ServletContextHandler();
             context.setContextPath("/");
             server.setHandler(context);
-            context.addServlet(new ServletHolder(new CallmebackServlet(test,  1)), callbackEndpoint);
+            context.addServlet(new ServletHolder(new CallmebackServlet(test, 1)), callbackEndpoint);
             server.start();
         }
 
@@ -135,12 +134,11 @@ public class TestPushNotification extends TestJaxrsBase {
         }
     }
 
-
     public static class CallmebackServlet extends HttpServlet {
 
         private static final long serialVersionUID = -5181211514918217301L;
 
-        private final static Logger log = LoggerFactory.getLogger(CallmebackServlet.class);
+        private static final Logger log = LoggerFactory.getLogger(CallmebackServlet.class);
 
         private final int expectedNbCalls;
         private final AtomicInteger receivedCalls;
@@ -160,7 +158,7 @@ public class TestPushNotification extends TestJaxrsBase {
         protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
             final int current = receivedCalls.incrementAndGet();
 
-            final String body = CharStreams.toString( new InputStreamReader(request.getInputStream(), "UTF-8" ));
+            final String body = CharStreams.toString(new InputStreamReader(request.getInputStream(), "UTF-8"));
 
             response.setContentType("application/json");
             response.setStatus(HttpServletResponse.SC_OK);
@@ -168,7 +166,7 @@ public class TestPushNotification extends TestJaxrsBase {
             log.info("Got body {}", body);
 
             try {
-                final NotificationJson notification =  objectMapper.readValue(body, NotificationJson.class);
+                final NotificationJson notification = objectMapper.readValue(body, NotificationJson.class);
                 Assert.assertEquals(notification.getEventType(), "ACCOUNT_CREATION");
                 Assert.assertEquals(notification.getObjectType(), "ACCOUNT");
                 Assert.assertNotNull(notification.getObjectId());
@@ -184,7 +182,6 @@ public class TestPushNotification extends TestJaxrsBase {
             stopServerWhenComplete(current, withError);
         }
 
-
         private void stopServerWhenComplete(final int current, final boolean withError) {
             if (current == expectedNbCalls) {
                 log.info("Excellent, we are done!");
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestSecurity.java b/server/src/test/java/com/ning/billing/jaxrs/TestSecurity.java
index 3c820d8..e9bd3d7 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestSecurity.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestSecurity.java
@@ -22,20 +22,13 @@ import java.util.List;
 import javax.annotation.Nullable;
 import javax.ws.rs.core.Response.Status;
 
-import org.apache.shiro.web.servlet.ShiroHttpSession;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.billing.client.KillBillClientException;
 import com.ning.billing.security.Permission;
-import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder;
-import com.ning.http.client.Cookie;
-import com.ning.http.client.Response;
 
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
 
 public class TestSecurity extends TestJaxrsBase {
 
@@ -43,8 +36,12 @@ public class TestSecurity extends TestJaxrsBase {
     public void testPermissions() throws Exception {
         logout();
 
-        final Response anonResponse = doGet(JaxrsResource.SECURITY_PATH + "/permissions", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(anonResponse.getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
+        try {
+            killBillClient.getPermissions();
+            Assert.fail();
+        } catch (final KillBillClientException e) {
+            Assert.assertEquals(e.getResponse().getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
+        }
 
         // See src/test/resources/shiro.ini
 
@@ -57,32 +54,8 @@ public class TestSecurity extends TestJaxrsBase {
         Assert.assertEquals(new HashSet<String>(stephanesPermissions), ImmutableSet.<String>of(Permission.PAYMENT_CAN_REFUND.toString()));
     }
 
-    @Test(groups = "slow")
-    public void testSession() throws Exception {
-        loginAs("pierre", "password");
-
-        final Response firstResponse = doGet(JaxrsResource.SECURITY_PATH + "/permissions", DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(firstResponse.getStatusCode(), Status.OK.getStatusCode());
-        Assert.assertEquals(((List) mapper.readValue(firstResponse.getResponseBody(), new TypeReference<List<String>>() {})).size(), 2);
-
-        // Retrieve the session id
-        final Cookie session = Iterables.find(firstResponse.getCookies(),
-                                              new Predicate<Cookie>() {
-                                                  @Override
-                                                  public boolean apply(@Nullable final Cookie cookie) {
-                                                      return ShiroHttpSession.DEFAULT_SESSION_ID_NAME.equals(cookie.getName());
-                                                  }
-                                              });
-
-        // Make sure we don't use the credentials anymore
-        logout();
-
-        // Re-issue the query with the cookie
-        final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), JaxrsResource.SECURITY_PATH + "/permissions");
-        final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("GET", url, DEFAULT_EMPTY_QUERY);
-        builder.addCookie(session);
-        final Response secondResponse = executeAndWait(builder, DEFAULT_HTTP_TIMEOUT_SEC, false);
-        Assert.assertEquals(secondResponse.getStatusCode(), Status.OK.getStatusCode());
-        Assert.assertEquals(((List) mapper.readValue(firstResponse.getResponseBody(), new TypeReference<List<String>>() {})).size(), 2);
+    private List<String> getPermissions(@Nullable final String username, @Nullable final String password) throws Exception {
+        login(username, password);
+        return killBillClient.getPermissions();
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
index 9003537..d2e397f 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
@@ -18,15 +18,11 @@ package com.ning.billing.jaxrs;
 
 import java.util.List;
 
-import javax.ws.rs.core.Response.Status;
-
 import org.testng.annotations.Test;
 
-import com.ning.billing.jaxrs.json.TagDefinitionJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.http.client.Response;
+import com.ning.billing.client.KillBillClientException;
+import com.ning.billing.client.model.TagDefinition;
 
-import com.fasterxml.jackson.core.type.TypeReference;
 import com.google.common.collect.ImmutableList;
 
 import static org.testng.Assert.assertEquals;
@@ -34,85 +30,54 @@ import static org.testng.Assert.assertNotNull;
 
 public class TestTag extends TestJaxrsBase {
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Cannot add badly formatted TagDefinition")
     public void testTagErrorHandling() throws Exception {
-        final TagDefinitionJson[] tags = new TagDefinitionJson[]{new TagDefinitionJson(null, false, null, null, null),
-                                                                 new TagDefinitionJson(null, false, "something", null, null),
-                                                                 new TagDefinitionJson(null, false, null, "something", null)};
-        for (final TagDefinitionJson tag : tags) {
-            final String baseJson = mapper.writeValueAsString(tag);
-            final Response response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-            assertEquals(response.getStatusCode(), Status.BAD_REQUEST.getStatusCode());
+        final TagDefinition[] tagDefinitions = {new TagDefinition(null, false, null, null, null),
+                                                new TagDefinition(null, false, "something", null, null),
+                                                new TagDefinition(null, false, null, "something", null)};
+
+        for (final TagDefinition tagDefinition : tagDefinitions) {
+            try {
+                killBillClient.createTagDefinition(tagDefinition, createdBy, reason, comment);
+            } catch (final KillBillClientException e) {
+            }
         }
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create a TagDefinition")
     public void testTagDefinitionOk() throws Exception {
-        final TagDefinitionJson input = new TagDefinitionJson(null, false, "blue", "relaxing color", ImmutableList.<String>of());
-        String baseJson = mapper.writeValueAsString(input);
-        Response response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        assertNotNull(location);
-
-        // Retrieves by Id based on Location returned
-        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final TagDefinition input = new TagDefinition(null, false, "blue", "relaxing color", ImmutableList.<String>of());
 
-        baseJson = response.getResponseBody();
-        final TagDefinitionJson objFromJson = mapper.readValue(baseJson, TagDefinitionJson.class);
+        final TagDefinition objFromJson = killBillClient.createTagDefinition(input, createdBy, reason, comment);
         assertNotNull(objFromJson);
         assertEquals(objFromJson.getName(), input.getName());
         assertEquals(objFromJson.getDescription(), input.getDescription());
     }
 
-    @Test(groups = "slow")
+    @Test(groups = "slow", description = "Can create and delete TagDefinitions")
     public void testMultipleTagDefinitionOk() throws Exception {
-        Response response = doGet(JaxrsResource.TAG_DEFINITIONS_PATH, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        String baseJson = response.getResponseBody();
-
-        List<TagDefinitionJson> objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
-        final int sizeSystemTag = (objFromJson == null || objFromJson.size() == 0) ? 0 : objFromJson.size();
-
-        final TagDefinitionJson inputBlue = new TagDefinitionJson(null, false, "blue", "relaxing color", ImmutableList.<String>of());
-        baseJson = mapper.writeValueAsString(inputBlue);
-        response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final TagDefinitionJson inputRed = new TagDefinitionJson(null, false, "red", "hot color", ImmutableList.<String>of());
-        baseJson = mapper.writeValueAsString(inputRed);
-        response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final TagDefinitionJson inputYellow = new TagDefinitionJson(null, false, "yellow", "vibrant color", ImmutableList.<String>of());
-        baseJson = mapper.writeValueAsString(inputYellow);
-        response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final TagDefinitionJson inputGreen = new TagDefinitionJson(null, false, "green", "super relaxing color", ImmutableList.<String>of());
-        baseJson = mapper.writeValueAsString(inputGreen);
-        response = doPost(JaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        response = doGet(JaxrsResource.TAG_DEFINITIONS_PATH, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-
-        objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
+        List<TagDefinition> objFromJson = killBillClient.getTagDefinitions();
+        final int sizeSystemTag = objFromJson.isEmpty() ? 0 : objFromJson.size();
+
+        final TagDefinition inputBlue = new TagDefinition(null, false, "blue", "relaxing color", ImmutableList.<String>of());
+        killBillClient.createTagDefinition(inputBlue, createdBy, reason, comment);
+
+        final TagDefinition inputRed = new TagDefinition(null, false, "red", "hot color", ImmutableList.<String>of());
+        killBillClient.createTagDefinition(inputRed, createdBy, reason, comment);
+
+        final TagDefinition inputYellow = new TagDefinition(null, false, "yellow", "vibrant color", ImmutableList.<String>of());
+        killBillClient.createTagDefinition(inputYellow, createdBy, reason, comment);
+
+        final TagDefinition inputGreen = new TagDefinition(null, false, "green", "super relaxing color", ImmutableList.<String>of());
+        killBillClient.createTagDefinition(inputGreen, createdBy, reason, comment);
+
+        objFromJson = killBillClient.getTagDefinitions();
         assertNotNull(objFromJson);
         assertEquals(objFromJson.size(), 4 + sizeSystemTag);
 
-        final String uri = JaxrsResource.TAG_DEFINITIONS_PATH + "/" + objFromJson.get(0).getId();
-        response = doDelete(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-
-        response = doGet(JaxrsResource.TAG_DEFINITIONS_PATH, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
+        killBillClient.deleteTagDefinition(objFromJson.get(0).getId(), createdBy, reason, comment);
 
-        objFromJson = mapper.readValue(baseJson, new TypeReference<List<TagDefinitionJson>>() {});
+        objFromJson = killBillClient.getTagDefinitions();
         assertNotNull(objFromJson);
         assertEquals(objFromJson.size(), 3 + sizeSystemTag);
     }
diff --git a/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java b/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java
index e4c54b4..3a88439 100644
--- a/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java
+++ b/server/src/test/java/com/ning/billing/server/security/TestTenantFilter.java
@@ -22,10 +22,13 @@ import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.Test;
 
+import com.ning.billing.client.KillBillClient;
+import com.ning.billing.client.KillBillClientException;
+import com.ning.billing.client.KillBillHttpClient;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Tenant;
 import com.ning.billing.jaxrs.TestJaxrsBase;
-import com.ning.billing.jaxrs.json.AccountJson;
 
-// Pure Multi-Tenancy test (no RBAC)
 public class TestTenantFilter extends TestJaxrsBase {
 
     @AfterMethod(groups = "slow")
@@ -38,51 +41,44 @@ public class TestTenantFilter extends TestJaxrsBase {
     public void testTenantShouldOnlySeeOwnAccount() throws Exception {
         // Try to create an account without being logged-in
         logoutTenant();
-        Assert.assertEquals(createAccountNoValidation().getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
+        try {
+            killBillClient.createAccount(getAccount(), createdBy, reason, comment);
+            Assert.fail();
+        } catch (final KillBillClientException e) {
+            Assert.assertEquals(e.getResponse().getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
+        }
 
         // Create the tenant
         final String apiKeyTenant1 = "pierre";
         final String apiSecretTenant1 = "pierreIsFr3nch";
-        createTenant(apiKeyTenant1, apiSecretTenant1);
-
-        // We should still not be able to create an account
-        Assert.assertEquals(createAccountNoValidation().getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
-
-        // Now, let's log-in and try again
         loginTenant(apiKeyTenant1, apiSecretTenant1);
-        final AccountJson account1 = createAccount();
-        Assert.assertEquals(getAccountByExternalKey(account1.getExternalKey()), account1);
+        final Tenant tenant1 = new Tenant();
+        tenant1.setApiKey(apiKeyTenant1);
+        tenant1.setApiSecret(apiSecretTenant1);
+        killBillClient.createTenant(tenant1, createdBy, reason, comment);
+
+        final Account account1 = createAccount();
+        Assert.assertEquals(killBillClient.getAccount(account1.getExternalKey()), account1);
 
         logoutTenant();
 
         // Create another tenant
         final String apiKeyTenant2 = "stephane";
         final String apiSecretTenant2 = "stephane1sAlsoFr3nch";
-        createTenant(apiKeyTenant2, apiSecretTenant2);
-
-        // We should not be able to create an account before being logged-in
-        Assert.assertEquals(createAccountNoValidation().getStatusCode(), Status.UNAUTHORIZED.getStatusCode());
-
-        // Now, let's log-in and try again
         loginTenant(apiKeyTenant2, apiSecretTenant2);
-        final AccountJson account2 = createAccount();
-        Assert.assertEquals(getAccountByExternalKey(account2.getExternalKey()), account2);
+        final Tenant tenant2 = new Tenant();
+        tenant2.setApiKey(apiKeyTenant2);
+        tenant2.setApiSecret(apiSecretTenant2);
+        killBillClient.createTenant(tenant2, createdBy, reason, comment);
+
+        final Account account2 = createAccount();
+        Assert.assertEquals(killBillClient.getAccount(account2.getExternalKey()), account2);
 
         // We should not be able to retrieve the first account as tenant2
-        Assert.assertEquals(getAccountByExternalKeyNoValidation(account1.getExternalKey()).getStatusCode(), Status.NOT_FOUND.getStatusCode());
+        Assert.assertNull(killBillClient.getAccount(account1.getExternalKey()));
 
         // Same for tenant1 and account2
         loginTenant(apiKeyTenant1, apiSecretTenant1);
-        Assert.assertEquals(getAccountByExternalKeyNoValidation(account2.getExternalKey()).getStatusCode(), Status.NOT_FOUND.getStatusCode());
-    }
-
-    private void loginTenant(final String apiKey, final String apiSecret) {
-        this.apiKey = apiKey;
-        this.apiSecret = apiSecret;
-    }
-
-    private void logoutTenant() {
-        apiKey = "";
-        apiSecret = "";
+        Assert.assertNull(killBillClient.getAccount(account2.getExternalKey()));
     }
 }