killbill-uncached

server: add missing tests for pagination and search endpoints Signed-off-by:

1/19/2014 9:08:20 AM

Changes

pom.xml 2(+1 -1)

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

Details

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 b922017..ae53882 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
@@ -252,10 +252,11 @@ public class AccountResource extends JaxRsResourceBase {
                                   @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                   @HeaderParam(HDR_REASON) final String reason,
                                   @HeaderParam(HDR_COMMENT) final String comment,
-                                  @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
+                                  @javax.ws.rs.core.Context final HttpServletRequest request,
+                                  @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException {
         final AccountData data = json.toAccountData();
         final Account account = accountUserApi.createAccount(data, context.createContext(createdBy, reason, comment, request));
-        return uriBuilder.buildResponse(AccountResource.class, "getAccount", account.getId());
+        return uriBuilder.buildResponse(uriInfo, AccountResource.class, "getAccount", account.getId());
     }
 
     @PUT
@@ -623,9 +624,10 @@ public class AccountResource extends JaxRsResourceBase {
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
-                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
+                                       @javax.ws.rs.core.Context final HttpServletRequest request,
+                                       @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                                        context.createContext(createdBy, reason, comment, request));
+                                        context.createContext(createdBy, reason, comment, request), uriInfo);
     }
 
     @DELETE
@@ -732,7 +734,8 @@ public class AccountResource extends JaxRsResourceBase {
                              @HeaderParam(HDR_CREATED_BY) final String createdBy,
                              @HeaderParam(HDR_REASON) final String reason,
                              @HeaderParam(HDR_COMMENT) final String comment,
-                             @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
+                             @javax.ws.rs.core.Context final HttpServletRequest request,
+                             @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         final UUID accountId = UUID.fromString(id);
@@ -753,7 +756,7 @@ public class AccountResource extends JaxRsResourceBase {
             accountUserApi.addEmail(accountId, json.toAccountEmail(UUID.randomUUID()), callContext);
         }
 
-        return uriBuilder.buildResponse(AccountResource.class, "getEmails", json.getAccountId());
+        return uriBuilder.buildResponse(uriInfo, AccountResource.class, "getEmails", json.getAccountId());
     }
 
     @DELETE
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
index 423f861..ef4a230 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BundleResource.java
@@ -163,9 +163,10 @@ public class BundleResource extends JaxRsResourceBase {
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
-                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
+                                       @javax.ws.rs.core.Context final HttpServletRequest request,
+                                       @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                                        context.createContext(createdBy, reason, comment, request));
+                                        context.createContext(createdBy, reason, comment, request), uriInfo);
     }
 
     @DELETE
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
index b52ddce..920d46b 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
@@ -27,6 +27,7 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 
 import com.ning.billing.ErrorCode;
 import com.ning.billing.ObjectType;
@@ -90,7 +91,8 @@ public class ChargebackResource extends JaxRsResourceBase {
                                      @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                      @HeaderParam(HDR_REASON) final String reason,
                                      @HeaderParam(HDR_COMMENT) final String comment,
-                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException {
+                                     @javax.ws.rs.core.Context final HttpServletRequest request,
+                                     @javax.ws.rs.core.Context final UriInfo uriInfo) throws InvoiceApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         final InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePaymentForAttempt(UUID.fromString(json.getPaymentId()), callContext);
@@ -99,7 +101,7 @@ public class ChargebackResource extends JaxRsResourceBase {
         }
         final InvoicePayment chargeBack = invoicePaymentApi.createChargeback(invoicePayment.getId(), json.getAmount(),
                                                                              callContext);
-        return uriBuilder.buildResponse(ChargebackResource.class, "getChargeback", chargeBack.getId());
+        return uriBuilder.buildResponse(uriInfo, ChargebackResource.class, "getChargeback", chargeBack.getId());
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
index 990b23e..f6631d7 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
@@ -27,6 +27,7 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 
 import org.joda.time.LocalDate;
 
@@ -93,7 +94,8 @@ public class CreditResource extends JaxRsResourceBase {
                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                  @HeaderParam(HDR_REASON) final String reason,
                                  @HeaderParam(HDR_COMMENT) final String comment,
-                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException {
+                                 @javax.ws.rs.core.Context final HttpServletRequest request,
+                                 @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, InvoiceApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         final Account account = accountUserApi.getAccountById(UUID.fromString(json.getAccountId()), callContext);
@@ -110,7 +112,7 @@ public class CreditResource extends JaxRsResourceBase {
                                                  account.getCurrency(), callContext);
         }
 
-        return uriBuilder.buildResponse(CreditResource.class, "getCredit", credit.getId());
+        return uriBuilder.buildResponse(uriInfo, CreditResource.class, "getCredit", credit.getId());
     }
 
     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CustomFieldResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CustomFieldResource.java
index 641a74d..b37b78d 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CustomFieldResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CustomFieldResource.java
@@ -74,7 +74,7 @@ public class CustomFieldResource extends JaxRsResourceBase {
                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
         final TenantContext tenantContext = context.createContext(request);
         final Pagination<CustomField> customFields = customFieldUserApi.getCustomFields(offset, limit, tenantContext);
-        final URI nextPageUri = uriBuilder.nextPage(CustomFieldResource.class, "getCustomFields", customFields.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.toString()));
+        final URI nextPageUri = uriBuilder.nextPage(CustomFieldResource.class, "getCustomFields", customFields.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()));
 
         return buildStreamingPaginationResponse(customFields,
                                                 new Function<CustomField, CustomFieldJson>() {
@@ -99,7 +99,7 @@ public class CustomFieldResource extends JaxRsResourceBase {
         final TenantContext tenantContext = context.createContext(request);
         final Pagination<CustomField> customFields = customFieldUserApi.searchCustomFields(searchKey, offset, limit, tenantContext);
         final URI nextPageUri = uriBuilder.nextPage(CustomFieldResource.class, "searchCustomFields", customFields.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
-                                                                                                                                                                          QUERY_AUDIT, auditMode.toString()));
+                                                                                                                                                                          QUERY_AUDIT, auditMode.getLevel().toString()));
         return buildStreamingPaginationResponse(customFields,
                                                 new Function<CustomField, CustomFieldJson>() {
                                                     @Override
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
index 71e278d..f034473 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
@@ -169,7 +169,7 @@ public class InvoiceResource extends JaxRsResourceBase {
         final TenantContext tenantContext = context.createContext(request);
         final Pagination<Invoice> invoices = invoiceApi.getInvoices(offset, limit, tenantContext);
         final URI nextPageUri = uriBuilder.nextPage(InvoiceResource.class, "getInvoices", invoices.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_INVOICE_WITH_ITEMS, withItems.toString(),
-                                                                                                                                                           QUERY_AUDIT, auditMode.toString()));
+                                                                                                                                                           QUERY_AUDIT, auditMode.getLevel().toString()));
 
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
         return buildStreamingPaginationResponse(invoices,
@@ -195,7 +195,8 @@ public class InvoiceResource extends JaxRsResourceBase {
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
                                         @HeaderParam(HDR_COMMENT) final String comment,
-                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException {
+                                        @javax.ws.rs.core.Context final HttpServletRequest request,
+                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, InvoiceApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
         final LocalDate inputDate = toLocalDate(UUID.fromString(accountId), targetDateTime, callContext);
 
@@ -204,7 +205,7 @@ public class InvoiceResource extends JaxRsResourceBase {
         if (dryRun) {
             return Response.status(Status.OK).entity(new InvoiceJson(generatedInvoice)).build();
         } else {
-            return uriBuilder.buildResponse(InvoiceResource.class, "getInvoice", generatedInvoice.getId());
+            return uriBuilder.buildResponse(uriInfo, InvoiceResource.class, "getInvoice", generatedInvoice.getId());
         }
     }
 
@@ -238,7 +239,8 @@ public class InvoiceResource extends JaxRsResourceBase {
                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                       @HeaderParam(HDR_REASON) final String reason,
                                       @HeaderParam(HDR_COMMENT) final String comment,
-                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException {
+                                      @javax.ws.rs.core.Context final HttpServletRequest request,
+                                      @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, InvoiceApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         final UUID accountId = UUID.fromString(json.getAccountId());
@@ -260,7 +262,7 @@ public class InvoiceResource extends JaxRsResourceBase {
                                                                     callContext);
         }
 
-        return uriBuilder.buildResponse(InvoiceResource.class, "getInvoice", adjustmentItem.getInvoiceId());
+        return uriBuilder.buildResponse(uriInfo, InvoiceResource.class, "getInvoice", adjustmentItem.getInvoiceId());
     }
 
     @POST
@@ -376,7 +378,8 @@ public class InvoiceResource extends JaxRsResourceBase {
                                          @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                          @HeaderParam(HDR_REASON) final String reason,
                                          @HeaderParam(HDR_COMMENT) final String comment,
-                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
+                                         @javax.ws.rs.core.Context final HttpServletRequest request,
+                                         @javax.ws.rs.core.Context final UriInfo uriInfo) throws AccountApiException, PaymentApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         final Account account = accountUserApi.getAccountById(UUID.fromString(payment.getAccountId()), callContext);
@@ -388,7 +391,7 @@ public class InvoiceResource extends JaxRsResourceBase {
             paymentApi.createPayment(account, invoiceId, payment.getAmount(), callContext);
         }
 
-        return uriBuilder.buildResponse(InvoiceResource.class, "getPayments", payment.getInvoiceId());
+        return uriBuilder.buildResponse(uriInfo, InvoiceResource.class, "getPayments", payment.getInvoiceId());
     }
 
     @POST
@@ -433,9 +436,10 @@ public class InvoiceResource extends JaxRsResourceBase {
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
-                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
+                                       @javax.ws.rs.core.Context final HttpServletRequest request,
+                                       @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                                        context.createContext(createdBy, reason, comment, request));
+                                        context.createContext(createdBy, reason, comment, request), uriInfo);
     }
 
     @DELETE
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
index c915b37..76973e1 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -177,14 +177,15 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
 
     protected Response createCustomFields(final UUID id,
                                           final List<CustomFieldJson> customFields,
-                                          final CallContext context) throws CustomFieldApiException {
+                                          final CallContext context,
+                                          final UriInfo uriInfo) throws CustomFieldApiException {
         final LinkedList<CustomField> input = new LinkedList<CustomField>();
         for (final CustomFieldJson cur : customFields) {
             input.add(new StringCustomField(cur.getName(), cur.getValue(), getObjectType(), id, context.getCreatedDate()));
         }
 
         customFieldUserApi.addCustomFields(input, context);
-        return uriBuilder.buildResponse(this.getClass(), "createCustomFields", id);
+        return uriBuilder.buildResponse(uriInfo, this.getClass(), "createCustomFields", null);
     }
 
     /**
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
index de740e4..fadb479 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentMethodResource.java
@@ -113,7 +113,7 @@ public class PaymentMethodResource extends JaxRsResourceBase {
         }
 
         final URI nextPageUri = uriBuilder.nextPage(PaymentMethodResource.class, "getPaymentMethods", paymentMethods.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
-                                                                                                                                                                             QUERY_AUDIT, auditMode.toString()));
+                                                                                                                                                                             QUERY_AUDIT, auditMode.getLevel().toString()));
 
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
         final Map<UUID, Account> accounts = new HashMap<UUID, Account>();
@@ -166,7 +166,7 @@ public class PaymentMethodResource extends JaxRsResourceBase {
 
         final URI nextPageUri = uriBuilder.nextPage(PaymentMethodResource.class, "searchPaymentMethods", paymentMethods.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
                                                                                                                                                                                 QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
-                                                                                                                                                                                QUERY_AUDIT, auditMode.toString()));
+                                                                                                                                                                                QUERY_AUDIT, auditMode.getLevel().toString()));
 
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
         final Map<UUID, Account> accounts = new HashMap<UUID, Account>();
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
index 96e09b8..7f14aee 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PaymentResource.java
@@ -307,9 +307,10 @@ public class PaymentResource extends JaxRsResourceBase {
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
-                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
+                                       @javax.ws.rs.core.Context final HttpServletRequest request,
+                                       @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                                        context.createContext(createdBy, reason, comment, request));
+                                        context.createContext(createdBy, reason, comment, request), uriInfo);
     }
 
     @DELETE
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
index 7790be3..e4c37f1 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/RefundResource.java
@@ -107,7 +107,7 @@ public class RefundResource extends JaxRsResourceBase {
         }
 
         final URI nextPageUri = uriBuilder.nextPage(RefundResource.class, "getRefunds", refunds.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
-                                                                                                                                                        QUERY_AUDIT, auditMode.toString()));
+                                                                                                                                                        QUERY_AUDIT, auditMode.getLevel().toString()));
 
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
         final Map<UUID, UUID> paymentIdAccountIdMappings = new HashMap<UUID, UUID>();
@@ -158,7 +158,7 @@ public class RefundResource extends JaxRsResourceBase {
 
         final URI nextPageUri = uriBuilder.nextPage(RefundResource.class, "searchRefunds", refunds.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
                                                                                                                                                            QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
-                                                                                                                                                           QUERY_AUDIT, auditMode.toString()));
+                                                                                                                                                           QUERY_AUDIT, auditMode.getLevel().toString()));
 
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
         final Map<UUID, UUID> paymentIdAccountIdMappings = new HashMap<UUID, UUID>();
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
index 6c19a71..49ae2a6 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/SubscriptionResource.java
@@ -129,7 +129,8 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                       @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                       @HeaderParam(HDR_REASON) final String reason,
                                       @HeaderParam(HDR_COMMENT) final String comment,
-                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementApiException, AccountApiException, SubscriptionApiException {
+                                      @javax.ws.rs.core.Context final HttpServletRequest request,
+                                      @javax.ws.rs.core.Context final UriInfo uriInfo) throws EntitlementApiException, AccountApiException, SubscriptionApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
         final EntitlementCallCompletionCallback<Entitlement> callback = new EntitlementCallCompletionCallback<Entitlement>() {
             @Override
@@ -154,7 +155,7 @@ public class SubscriptionResource extends JaxRsResourceBase {
 
             @Override
             public Response doResponseOk(final Entitlement createdEntitlement) {
-                return uriBuilder.buildResponse(SubscriptionResource.class, "getEntitlement", createdEntitlement.getId());
+                return uriBuilder.buildResponse(uriInfo, SubscriptionResource.class, "getEntitlement", createdEntitlement.getId());
             }
         };
 
@@ -406,10 +407,10 @@ public class SubscriptionResource extends JaxRsResourceBase {
                                        @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                        @HeaderParam(HDR_REASON) final String reason,
                                        @HeaderParam(HDR_COMMENT) final String comment,
-                                       @javax.ws.rs.core.Context final UriInfo uriInfo,
-                                       @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
+                                       @javax.ws.rs.core.Context final HttpServletRequest request,
+                                       @javax.ws.rs.core.Context final UriInfo uriInfo) throws CustomFieldApiException {
         return super.createCustomFields(UUID.fromString(id), customFields,
-                                        context.createContext(createdBy, reason, comment, request));
+                                        context.createContext(createdBy, reason, comment, request), uriInfo);
     }
 
     @DELETE
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagDefinitionResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagDefinitionResource.java
index bc7202c..8d29465 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagDefinitionResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagDefinitionResource.java
@@ -31,6 +31,7 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
 
 import com.ning.billing.ObjectType;
 import com.ning.billing.account.api.AccountUserApi;
@@ -95,13 +96,14 @@ public class TagDefinitionResource extends JaxRsResourceBase {
                                         @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                         @HeaderParam(HDR_REASON) final String reason,
                                         @HeaderParam(HDR_COMMENT) final String comment,
-                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
+                                        @javax.ws.rs.core.Context final HttpServletRequest request,
+                                        @javax.ws.rs.core.Context final UriInfo uriInfo) throws TagDefinitionApiException {
         // Checked as the database layer as well, but bail early and return 400 instead of 500
         Preconditions.checkNotNull(json.getName(), String.format("TagDefinition name needs to be set"));
         Preconditions.checkNotNull(json.getDescription(), String.format("TagDefinition description needs to be set"));
 
         final TagDefinition createdTagDef = tagUserApi.createTagDefinition(json.getName(), json.getDescription(), context.createContext(createdBy, reason, comment, request));
-        return uriBuilder.buildResponse(TagDefinitionResource.class, "getTagDefinition", createdTagDef.getId());
+        return uriBuilder.buildResponse(uriInfo, TagDefinitionResource.class, "getTagDefinition", createdTagDef.getId());
     }
 
     @DELETE
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
index 0734a08..e855295 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TagResource.java
@@ -78,7 +78,7 @@ public class TagResource extends JaxRsResourceBase {
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         final TenantContext tenantContext = context.createContext(request);
         final Pagination<Tag> tags = tagUserApi.getTags(offset, limit, tenantContext);
-        final URI nextPageUri = uriBuilder.nextPage(TagResource.class, "getTags", tags.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.toString()));
+        final URI nextPageUri = uriBuilder.nextPage(TagResource.class, "getTags", tags.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()));
 
         final Map<UUID, TagDefinition> tagDefinitionsCache = new HashMap<UUID, TagDefinition>();
         for (final TagDefinition tagDefinition : tagUserApi.getTagDefinitions(tenantContext)) {
@@ -110,7 +110,7 @@ public class TagResource extends JaxRsResourceBase {
         final TenantContext tenantContext = context.createContext(request);
         final Pagination<Tag> tags = tagUserApi.searchTags(searchKey, offset, limit, tenantContext);
         final URI nextPageUri = uriBuilder.nextPage(TagResource.class, "searchTags", tags.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
-                                                                                                                                                  QUERY_AUDIT, auditMode.toString()));
+                                                                                                                                                  QUERY_AUDIT, auditMode.getLevel().toString()));
         final Map<UUID, TagDefinition> tagDefinitionsCache = new HashMap<UUID, TagDefinition>();
         for (final TagDefinition tagDefinition : tagUserApi.getTagDefinitions(tenantContext)) {
             tagDefinitionsCache.put(tagDefinition.getId(), tagDefinition);
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TenantResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TenantResource.java
index 8fc974e..f764012 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TenantResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/TenantResource.java
@@ -16,8 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
 import java.net.URI;
 import java.util.List;
 import java.util.UUID;
@@ -35,6 +33,7 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
 
 import com.ning.billing.ObjectType;
 import com.ning.billing.account.api.AccountUserApi;
@@ -57,6 +56,8 @@ import com.ning.billing.util.callcontext.TenantContext;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
 @Singleton
 @Path(JaxrsResource.TENANTS_PATH)
 public class TenantResource extends JaxRsResourceBase {
@@ -65,13 +66,13 @@ public class TenantResource extends JaxRsResourceBase {
 
     @Inject
     public TenantResource(final TenantUserApi tenantApi,
-            final JaxrsUriBuilder uriBuilder,
-            final TagUserApi tagUserApi,
-            final CustomFieldUserApi customFieldUserApi,
-            final AuditUserApi auditUserApi,
-            final AccountUserApi accountUserApi,
-            final Clock clock,
-            final Context context) {
+                          final JaxrsUriBuilder uriBuilder,
+                          final TagUserApi tagUserApi,
+                          final CustomFieldUserApi customFieldUserApi,
+                          final AuditUserApi auditUserApi,
+                          final AccountUserApi accountUserApi,
+                          final Clock clock,
+                          final Context context) {
         super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, clock, context);
         this.tenantApi = tenantApi;
     }
@@ -95,13 +96,14 @@ public class TenantResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createTenant(final TenantJson json,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment,
-            @javax.ws.rs.core.Context final HttpServletRequest request) throws TenantApiException {
+                                 @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                 @HeaderParam(HDR_REASON) final String reason,
+                                 @HeaderParam(HDR_COMMENT) final String comment,
+                                 @javax.ws.rs.core.Context final HttpServletRequest request,
+                                 @javax.ws.rs.core.Context final UriInfo uriInfo) throws TenantApiException {
         final TenantData data = json.toTenantData();
         final Tenant tenant = tenantApi.createTenant(data, context.createContext(createdBy, reason, comment, request));
-        return uriBuilder.buildResponse(TenantResource.class, "getTenant", tenant.getId());
+        return uriBuilder.buildResponse(uriInfo, TenantResource.class, "getTenant", tenant.getId());
     }
 
     @POST
@@ -109,14 +111,14 @@ public class TenantResource extends JaxRsResourceBase {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response registerPushNotificationCallback(@PathParam("tenantId") final String tenantId,
-            @QueryParam(QUERY_NOTIFICATION_CALLBACK) final String notificationCallback,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment,
-            @javax.ws.rs.core.Context final HttpServletRequest request) throws TenantApiException {
+                                                     @QueryParam(QUERY_NOTIFICATION_CALLBACK) final String notificationCallback,
+                                                     @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                                     @HeaderParam(HDR_REASON) final String reason,
+                                                     @HeaderParam(HDR_COMMENT) final String comment,
+                                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws TenantApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
         tenantApi.addTenantKeyValue(TenantKey.PUSH_NOTIFICATION_CB.toString(), notificationCallback, callContext);
-        final URI uri =  UriBuilder.fromResource(TenantResource.class).path(TenantResource.class, "getPushNotificationCallbacks").build();
+        final URI uri = UriBuilder.fromResource(TenantResource.class).path(TenantResource.class, "getPushNotificationCallbacks").build();
         return Response.created(uri).build();
     }
 
@@ -134,16 +136,15 @@ public class TenantResource extends JaxRsResourceBase {
     @DELETE
     @Path("/REGISTER_NOTIFICATION_CALLBACK")
     public Response deletePushNotificationCallbacks(@PathParam("tenantId") final String tenantId,
-            @HeaderParam(HDR_CREATED_BY) final String createdBy,
-            @HeaderParam(HDR_REASON) final String reason,
-            @HeaderParam(HDR_COMMENT) final String comment,
-            @javax.ws.rs.core.Context final HttpServletRequest request) throws TenantApiException {
+                                                    @HeaderParam(HDR_CREATED_BY) final String createdBy,
+                                                    @HeaderParam(HDR_REASON) final String reason,
+                                                    @HeaderParam(HDR_COMMENT) final String comment,
+                                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws TenantApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
         tenantApi.deleteTenantKey(TenantKey.PUSH_NOTIFICATION_CB.toString(), callContext);
         return Response.status(Status.OK).build();
     }
 
-
     @Override
     protected ObjectType getObjectType() {
         return ObjectType.TENANT;
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java
index 4a25ec0..11aaacd 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/JaxrsUriBuilder.java
@@ -21,24 +21,23 @@ import java.util.Map;
 
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
 
 import com.ning.billing.jaxrs.resources.JaxRsResourceBase;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
 
 public class JaxrsUriBuilder {
 
-    public Response buildResponse(final Class<? extends JaxrsResource> theClass, final String getMethodName, final Object objectId) {
-        final URI uri = UriBuilder.fromPath(objectId.toString()).build();
-        final Response.ResponseBuilder ri = Response.created(uri);
-        return ri.entity(new Object() {
-            @SuppressWarnings(value = "all")
-            public URI getUri() {
-                final URI newUriFromResource = objectId != null ?
-                                               UriBuilder.fromResource(theClass).path(theClass, getMethodName).build(objectId) :
-                                               UriBuilder.fromResource(theClass).path(theClass, getMethodName).build();
-                return newUriFromResource;
-            }
-        }).build();
+    public Response buildResponse(final UriInfo uriInfo, final Class<? extends JaxrsResource> theClass, final String getMethodName, final Object objectId) {
+        final UriBuilder uriBuilder = UriBuilder.fromResource(theClass)
+                                                .path(theClass, getMethodName)
+                                                .scheme(uriInfo.getAbsolutePath().getScheme())
+                                                .host(uriInfo.getAbsolutePath().getHost())
+                                                .port(uriInfo.getAbsolutePath().getPort());
+
+        final URI location = objectId != null ? uriBuilder.build(objectId) : uriBuilder.build();
+
+        return Response.created(location).build();
     }
 
     public URI nextPage(final Class<? extends JaxrsResource> theClass, final String getMethodName, final Long nextOffset, final Long limit, final Map<String, String> params) {

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index 8bd1bad..b4e0c48 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.18-SNAPSHOT</version>
+        <version>0.5.19</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.8.8-SNAPSHOT</version>

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

diff --git a/server/pom.xml b/server/pom.xml
index 1838ab3..0c17e1f 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -73,7 +73,6 @@
         <dependency>
             <groupId>com.ning</groupId>
             <artifactId>async-http-client</artifactId>
-            <version>${async-http-client.version}</version>
         </dependency>
         <dependency>
             <groupId>com.ning.billing</groupId>
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 ccefafe..6b08e3b 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
@@ -29,6 +29,7 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.client.KillBillClientException;
 import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Accounts;
 import com.ning.billing.client.model.AuditLog;
 import com.ning.billing.client.model.CustomField;
 import com.ning.billing.client.model.Payment;
@@ -240,6 +241,25 @@ public class TestAccount extends TestJaxrsBase {
         assertEquals(remainingCustomFields.size(), 0);
     }
 
+    @Test(groups = "slow", description = "Can paginate through all accounts")
+    public void testAccountsPagination() throws Exception {
+        for (int i = 0; i < 5; i++) {
+            createAccount();
+        }
+
+        final Accounts allAccounts = killBillClient.getAccounts();
+        Assert.assertEquals(allAccounts.size(), 5);
+
+        Accounts page = killBillClient.getAccounts(0L, 1L);
+        for (int i = 0; i < 5; i++) {
+            Assert.assertNotNull(page);
+            Assert.assertEquals(page.size(), 1);
+            Assert.assertEquals(page.get(0), allAccounts.get(i));
+            page = page.getNext();
+        }
+        Assert.assertNull(page);
+    }
+
     private void searchAccount(final Account input, @Nullable final Account output) throws Exception {
         // Search by id
         if (output != null) {
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestCustomField.java b/server/src/test/java/com/ning/billing/jaxrs/TestCustomField.java
new file mode 100644
index 0000000..b49483f
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestCustomField.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2010-2014 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.jaxrs;
+
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ning.billing.ObjectType;
+import com.ning.billing.client.KillBillClientException;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.CustomField;
+import com.ning.billing.client.model.CustomFields;
+
+public class TestCustomField extends TestJaxrsBase {
+
+    @Test(groups = "slow", description = "Can paginate through all custom fields")
+    public void testCustomFieldsPagination() throws Exception {
+        final Account account = createAccount();
+        for (int i = 0; i < 5; i++) {
+            final CustomField customField = new CustomField();
+            customField.setName(UUID.randomUUID().toString().substring(0, 5));
+            customField.setValue(UUID.randomUUID().toString().substring(0, 5));
+            killBillClient.createAccountCustomField(account.getAccountId(), customField, createdBy, reason, comment);
+        }
+
+        final CustomFields allCustomFields = killBillClient.getCustomFields();
+        Assert.assertEquals(allCustomFields.size(), 5);
+
+        CustomFields page = killBillClient.getCustomFields(0L, 1L);
+        for (int i = 0; i < 5; i++) {
+            Assert.assertNotNull(page);
+            Assert.assertEquals(page.size(), 1);
+            Assert.assertEquals(page.get(0), allCustomFields.get(i));
+            page = page.getNext();
+        }
+        Assert.assertNull(page);
+
+        for (final CustomField customField : allCustomFields) {
+            doSearchCustomField(UUID.randomUUID().toString(), null);
+            doSearchCustomField(customField.getName(), customField);
+            doSearchCustomField(customField.getValue(), customField);
+        }
+
+        final CustomFields customFields = killBillClient.searchCustomFields(ObjectType.ACCOUNT.toString());
+        Assert.assertEquals(customFields.size(), 5);
+        Assert.assertEquals(customFields.getPaginationCurrentOffset(), 0);
+        Assert.assertEquals(customFields.getPaginationTotalNbRecords(), 5);
+        Assert.assertEquals(customFields.getPaginationMaxNbRecords(), 5);
+    }
+
+    private void doSearchCustomField(final String searchKey, @Nullable final CustomField expectedCustomField) throws KillBillClientException {
+        final CustomFields customFields = killBillClient.searchCustomFields(searchKey);
+        if (expectedCustomField == null) {
+            Assert.assertTrue(customFields.isEmpty());
+            Assert.assertEquals(customFields.getPaginationCurrentOffset(), 0);
+            Assert.assertEquals(customFields.getPaginationTotalNbRecords(), 0);
+            Assert.assertEquals(customFields.getPaginationMaxNbRecords(), 5);
+        } else {
+            Assert.assertEquals(customFields.size(), 1);
+            Assert.assertEquals(customFields.get(0), expectedCustomField);
+            Assert.assertEquals(customFields.getPaginationCurrentOffset(), 0);
+            Assert.assertEquals(customFields.getPaginationTotalNbRecords(), 1);
+            Assert.assertEquals(customFields.getPaginationMaxNbRecords(), 5);
+        }
+    }
+}
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 8a6699e..6d904a2 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
@@ -29,6 +29,7 @@ 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.Invoices;
 import com.ning.billing.client.model.Payment;
 import com.ning.billing.client.model.PaymentMethod;
 import com.ning.billing.payment.provider.ExternalPaymentProviderPlugin;
@@ -448,4 +449,26 @@ public class TestInvoice extends TestJaxrsBase {
         final BigDecimal adjustedInvoiceBalance = originalInvoiceAmount.add(chargeAmount.setScale(2, RoundingMode.HALF_UP));
         assertEquals(adjustedInvoice.getBalance().compareTo(adjustedInvoiceBalance), 0);
     }
+
+    @Test(groups = "slow", description = "Can paginate through all invoices")
+    public void testInvoicesPagination() throws Exception {
+        createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
+
+        for (int i = 0; i < 3; i++) {
+            clock.addMonths(1);
+            crappyWaitForLackOfProperSynchonization();
+        }
+
+        final Invoices allInvoices = killBillClient.getInvoices();
+        Assert.assertEquals(allInvoices.size(), 5);
+
+        Invoices page = killBillClient.getInvoices(0L, 1L);
+        for (int i = 0; i < 5; i++) {
+            Assert.assertNotNull(page);
+            Assert.assertEquals(page.size(), 1);
+            Assert.assertEquals(page.get(0), allInvoices.get(i));
+            page = page.getNext();
+        }
+        Assert.assertNull(page);
+    }
 }
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 96560de..3b15dfe 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPayment.java
@@ -30,7 +30,9 @@ 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.Payments;
 import com.ning.billing.client.model.Refund;
+import com.ning.billing.client.model.Refunds;
 import com.ning.billing.payment.api.RefundStatus;
 
 import com.google.common.collect.ImmutableList;
@@ -178,6 +180,50 @@ public class TestPayment extends TestJaxrsBase {
         verifyInvoice(paymentJson, expectedInvoiceBalance);
     }
 
+    @Test(groups = "slow", description = "Can paginate through all payments and refunds")
+    public void testPaymentsAndRefundsPagination() throws Exception {
+        Payment lastPayment = setupScenarioWithPayment();
+
+        for (int i = 0; i < 5; i++) {
+            final Refund refund = new Refund();
+            refund.setPaymentId(lastPayment.getPaymentId());
+            refund.setAmount(lastPayment.getAmount());
+            killBillClient.createRefund(refund, createdBy, reason, comment);
+
+            final Payment payment = new Payment();
+            payment.setAccountId(lastPayment.getAccountId());
+            payment.setInvoiceId(lastPayment.getInvoiceId());
+            payment.setAmount(lastPayment.getAmount());
+            final List<Payment> payments = killBillClient.createPayment(payment, false, createdBy, reason, comment);
+
+            lastPayment = payments.get(payments.size() - 1);
+        }
+
+        final Payments allPayments = killBillClient.getPayments();
+        Assert.assertEquals(allPayments.size(), 6);
+
+        final Refunds allRefunds = killBillClient.getRefunds();
+        Assert.assertEquals(allRefunds.size(), 5);
+
+        Payments paymentsPage = killBillClient.getPayments(0L, 1L);
+        for (int i = 0; i < 6; i++) {
+            Assert.assertNotNull(paymentsPage);
+            Assert.assertEquals(paymentsPage.size(), 1);
+            Assert.assertEquals(paymentsPage.get(0), allPayments.get(i));
+            paymentsPage = paymentsPage.getNext();
+        }
+        Assert.assertNull(paymentsPage);
+
+        Refunds refundsPage = killBillClient.getRefunds(0L, 1L);
+        for (int i = 0; i < 5; i++) {
+            Assert.assertNotNull(refundsPage);
+            Assert.assertEquals(refundsPage.size(), 1);
+            Assert.assertEquals(refundsPage.get(0), allRefunds.get(i));
+            refundsPage = refundsPage.getNext();
+        }
+        Assert.assertNull(refundsPage);
+    }
+
     private BigDecimal getFractionOfAmount(final BigDecimal amount) {
         return amount.divide(BigDecimal.TEN).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 1ebb0e4..0a24deb 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestPaymentMethod.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPaymentMethod.java
@@ -24,6 +24,7 @@ import org.testng.annotations.Test;
 
 import com.ning.billing.client.model.Account;
 import com.ning.billing.client.model.PaymentMethod;
+import com.ning.billing.client.model.PaymentMethods;
 
 public class TestPaymentMethod extends TestJaxrsBase {
 
@@ -56,6 +57,25 @@ public class TestPaymentMethod extends TestJaxrsBase {
         doSearch("Zimbawe", paymentMethodJson);
     }
 
+    @Test(groups = "slow", description = "Can paginate through all payment methods")
+    public void testPaymentMethodsPagination() throws Exception {
+        for (int i = 0; i < 5; i++) {
+            createAccountWithDefaultPaymentMethod();
+        }
+
+        final PaymentMethods allPaymentMethods = killBillClient.getPaymentMethods();
+        Assert.assertEquals(allPaymentMethods.size(), 5);
+
+        PaymentMethods page = killBillClient.getPaymentMethods(0L, 1L);
+        for (int i = 0; i < 5; i++) {
+            Assert.assertNotNull(page);
+            Assert.assertEquals(page.size(), 1);
+            Assert.assertEquals(page.get(0), allPaymentMethods.get(i));
+            page = page.getNext();
+        }
+        Assert.assertNull(page);
+    }
+
     private void doSearch(final String searchKey, final PaymentMethod paymentMethodJson) throws Exception {
         final List<PaymentMethod> results1 = killBillClient.searchPaymentMethodsByKey(searchKey);
         Assert.assertEquals(results1.size(), 1);
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 d2e397f..3ea5658 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestTag.java
@@ -17,16 +17,25 @@
 package com.ning.billing.jaxrs;
 
 import java.util.List;
+import java.util.UUID;
 
+import javax.annotation.Nullable;
+
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
+import com.ning.billing.ObjectType;
 import com.ning.billing.client.KillBillClientException;
+import com.ning.billing.client.model.Account;
+import com.ning.billing.client.model.Tag;
 import com.ning.billing.client.model.TagDefinition;
+import com.ning.billing.client.model.Tags;
 
 import com.google.common.collect.ImmutableList;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
 
 public class TestTag extends TestJaxrsBase {
 
@@ -39,6 +48,7 @@ public class TestTag extends TestJaxrsBase {
         for (final TagDefinition tagDefinition : tagDefinitions) {
             try {
                 killBillClient.createTagDefinition(tagDefinition, createdBy, reason, comment);
+                fail();
             } catch (final KillBillClientException e) {
             }
         }
@@ -46,7 +56,7 @@ public class TestTag extends TestJaxrsBase {
 
     @Test(groups = "slow", description = "Can create a TagDefinition")
     public void testTagDefinitionOk() throws Exception {
-        final TagDefinition input = new TagDefinition(null, false, "blue", "relaxing color", ImmutableList.<String>of());
+        final TagDefinition input = new TagDefinition(null, false, "blue", "relaxing color", ImmutableList.<ObjectType>of());
 
         final TagDefinition objFromJson = killBillClient.createTagDefinition(input, createdBy, reason, comment);
         assertNotNull(objFromJson);
@@ -59,16 +69,16 @@ public class TestTag extends TestJaxrsBase {
         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());
+        final TagDefinition inputBlue = new TagDefinition(null, false, "blue", "relaxing color", ImmutableList.<ObjectType>of());
         killBillClient.createTagDefinition(inputBlue, createdBy, reason, comment);
 
-        final TagDefinition inputRed = new TagDefinition(null, false, "red", "hot color", ImmutableList.<String>of());
+        final TagDefinition inputRed = new TagDefinition(null, false, "red", "hot color", ImmutableList.<ObjectType>of());
         killBillClient.createTagDefinition(inputRed, createdBy, reason, comment);
 
-        final TagDefinition inputYellow = new TagDefinition(null, false, "yellow", "vibrant color", ImmutableList.<String>of());
+        final TagDefinition inputYellow = new TagDefinition(null, false, "yellow", "vibrant color", ImmutableList.<ObjectType>of());
         killBillClient.createTagDefinition(inputYellow, createdBy, reason, comment);
 
-        final TagDefinition inputGreen = new TagDefinition(null, false, "green", "super relaxing color", ImmutableList.<String>of());
+        final TagDefinition inputGreen = new TagDefinition(null, false, "green", "super relaxing color", ImmutableList.<ObjectType>of());
         killBillClient.createTagDefinition(inputGreen, createdBy, reason, comment);
 
         objFromJson = killBillClient.getTagDefinitions();
@@ -81,4 +91,57 @@ public class TestTag extends TestJaxrsBase {
         assertNotNull(objFromJson);
         assertEquals(objFromJson.size(), 3 + sizeSystemTag);
     }
+
+    @Test(groups = "slow", description = "Can paginate through all tags")
+    public void testTagsPagination() throws Exception {
+        final Account account = createAccount();
+        for (int i = 0; i < 5; i++) {
+            final TagDefinition tagDefinition = new TagDefinition(null, false, UUID.randomUUID().toString().substring(0, 5), UUID.randomUUID().toString(), ImmutableList.<ObjectType>of(ObjectType.ACCOUNT));
+            final UUID tagDefinitionId = killBillClient.createTagDefinition(tagDefinition, createdBy, reason, comment).getId();
+            killBillClient.createAccountTag(account.getAccountId(), tagDefinitionId, createdBy, reason, comment);
+        }
+
+        final Tags allTags = killBillClient.getTags();
+        Assert.assertEquals(allTags.size(), 5);
+
+        Tags page = killBillClient.getTags(0L, 1L);
+        for (int i = 0; i < 5; i++) {
+            Assert.assertNotNull(page);
+            Assert.assertEquals(page.size(), 1);
+            Assert.assertEquals(page.get(0), allTags.get(i));
+            page = page.getNext();
+        }
+        Assert.assertNull(page);
+
+        for (final Tag tag : allTags) {
+            doSearchTag(UUID.randomUUID().toString(), null);
+            doSearchTag(tag.getTagId().toString(), tag);
+            doSearchTag(tag.getTagDefinitionName(), tag);
+
+            final TagDefinition tagDefinition = killBillClient.getTagDefinition(tag.getTagDefinitionId());
+            doSearchTag(tagDefinition.getDescription(), tag);
+        }
+
+        final Tags tags = killBillClient.searchTags(ObjectType.ACCOUNT.toString());
+        Assert.assertEquals(tags.size(), 5);
+        Assert.assertEquals(tags.getPaginationCurrentOffset(), 0);
+        Assert.assertEquals(tags.getPaginationTotalNbRecords(), 5);
+        Assert.assertEquals(tags.getPaginationMaxNbRecords(), 5);
+    }
+
+    private void doSearchTag(final String searchKey, @Nullable final Tag expectedTag) throws KillBillClientException {
+        final Tags tags = killBillClient.searchTags(searchKey);
+        if (expectedTag == null) {
+            Assert.assertTrue(tags.isEmpty());
+            Assert.assertEquals(tags.getPaginationCurrentOffset(), 0);
+            Assert.assertEquals(tags.getPaginationTotalNbRecords(), 0);
+            Assert.assertEquals(tags.getPaginationMaxNbRecords(), 5);
+        } else {
+            Assert.assertEquals(tags.size(), 1);
+            Assert.assertEquals(tags.get(0), expectedTag);
+            Assert.assertEquals(tags.getPaginationCurrentOffset(), 0);
+            Assert.assertEquals(tags.getPaginationTotalNbRecords(), 1);
+            Assert.assertEquals(tags.getPaginationMaxNbRecords(), 5);
+        }
+    }
 }
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/DefaultPaginationHelper.java b/util/src/main/java/com/ning/billing/util/entity/dao/DefaultPaginationHelper.java
index 1383955..45429a7 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/DefaultPaginationHelper.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/DefaultPaginationHelper.java
@@ -64,7 +64,8 @@ public class DefaultPaginationHelper {
                     pages = entityPaginationBuilder.build(firstSearch ? offset : 0L, limit - allResults.size(), pluginName);
                     allResults.addAll(ImmutableList.<E>copyOf(pages));
                 }
-                firstSearch = false;
+                // Make sure not to start at 0 for subsequent plugins if previous ones didn't yield any result
+                firstSearch = allResults.isEmpty();
                 totalNbRecords += pages.getTotalNbRecords();
                 maxNbRecords += pages.getMaxNbRecords();
             } catch (final BillingExceptionBase e) {