Repository: killbill/killbill
Issue: Search endpoint issue

```
GET http://127.0.0.1:8080/1.0/kb/accounts/search/john?offset=0&limit=1&accountWithBalance=true&accountWithBalanceAndCBA=false
```

Results in:

```
org.glassfish.jersey.server.internal.process.MappableException: java.lang.IllegalArgumentException: The template variable 'searchKey' has no value
```

It looks like we need to update `JaxrsUriBuilder` and pass the search key as such (instead of params):

```
uriBuilder.resolveTemplate("searchKey", "john")
```

This is likely a regression from https://github.com/killbill/killbill/issues/1384.

Changed files:
jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java
jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java

diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index 0d414e234a..f86d400bf5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -230,9 +230,14 @@ public class AccountResource extends JaxRsResourceBase {
                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final Pagination<Account> accounts = accountUserApi.getAccounts(offset, limit, tenantContext);
-        final URI nextPageUri = uriBuilder.nextPage(AccountResource.class, "getAccounts", accounts.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_ACCOUNT_WITH_BALANCE, accountWithBalance.toString(),
-                                                                                                                                                           QUERY_ACCOUNT_WITH_BALANCE_AND_CBA, accountWithBalanceAndCBA.toString(),
-                                                                                                                                                           QUERY_AUDIT, auditMode.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(AccountResource.class,
+                                                    "getAccounts",
+                                                    accounts.getNextOffset(),
+                                                    limit,
+                                                    ImmutableMap.<String, String>of(QUERY_ACCOUNT_WITH_BALANCE, accountWithBalance.toString(),
+                                                                                    QUERY_ACCOUNT_WITH_BALANCE_AND_CBA, accountWithBalanceAndCBA.toString(),
+                                                                                    QUERY_AUDIT, auditMode.getLevel().toString()),
+                                                    ImmutableMap.<String, String>of());
         return buildStreamingPaginationResponse(accounts,
                                                 new Function<Account, AccountJson>() {
                                                     @Override
@@ -260,10 +265,14 @@ public class AccountResource extends JaxRsResourceBase {
                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final Pagination<Account> accounts = accountUserApi.searchAccounts(searchKey, offset, limit, tenantContext);
-        final URI nextPageUri = uriBuilder.nextPage(AccountResource.class, "searchAccounts", accounts.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
-                                                                                                                                                              QUERY_ACCOUNT_WITH_BALANCE, accountWithBalance.toString(),
-                                                                                                                                                              QUERY_ACCOUNT_WITH_BALANCE_AND_CBA, accountWithBalanceAndCBA.toString(),
-                                                                                                                                                              QUERY_AUDIT, auditMode.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(AccountResource.class,
+                                                    "searchAccounts",
+                                                    accounts.getNextOffset(),
+                                                    limit,
+                                                    ImmutableMap.<String, String>of(QUERY_ACCOUNT_WITH_BALANCE, accountWithBalance.toString(),
+                                                                                    QUERY_ACCOUNT_WITH_BALANCE_AND_CBA, accountWithBalanceAndCBA.toString(),
+                                                                                    QUERY_AUDIT, auditMode.getLevel().toString()),
+                                                    ImmutableMap.<String, String>of("searchKey", searchKey));
         return buildStreamingPaginationResponse(accounts,
                                                 new Function<Account, AccountJson>() {
                                                     @Override
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
index 3f7afc8d8c..ed30c1b7bf 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
@@ -313,6 +313,7 @@ public class AdminResource extends JaxRsResourceBase {
                                                     "triggerInvoiceGenerationForParkedAccounts",
                                                     tags.getNextOffset(),
                                                     limit,
+                                                    ImmutableMap.<String, String>of(),
                                                     ImmutableMap.<String, String>of());
         return Response.status(Status.OK)
                        .entity(json)
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
index ea2d0a1180..5a15ec0952 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
@@ -193,7 +193,7 @@ public class BundleResource extends JaxRsResourceBase {
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final Pagination<SubscriptionBundle> bundles = subscriptionApi.getSubscriptionBundles(offset, limit, tenantContext);
-        final URI nextPageUri = uriBuilder.nextPage(BundleResource.class, "getBundles", bundles.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(BundleResource.class, "getBundles", bundles.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()), ImmutableMap.<String, String>of());
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
         return buildStreamingPaginationResponse(bundles,
                                                 new Function<SubscriptionBundle, BundleJson>() {
@@ -228,8 +228,7 @@ public class BundleResource extends JaxRsResourceBase {
                                   @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final Pagination<SubscriptionBundle> bundles = subscriptionApi.searchSubscriptionBundles(searchKey, offset, limit, tenantContext);
-        final URI nextPageUri = uriBuilder.nextPage(BundleResource.class, "searchBundles", bundles.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
-                                                                                                                                                           QUERY_AUDIT, auditMode.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(BundleResource.class,"searchBundles", bundles.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()), ImmutableMap.<String, String>of("searchKey", searchKey));
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
         return buildStreamingPaginationResponse(bundles,
                                                 new Function<SubscriptionBundle, BundleJson>() {
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
index 271042051a..b273aa6091 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
@@ -98,7 +98,7 @@ public class CustomFieldResource extends JaxRsResourceBase {
                                     @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(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.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(CustomFieldResource.class, "getCustomFields", customFields.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()), ImmutableMap.<String, String>of());
 
         return buildStreamingPaginationResponse(customFields,
                                                 new Function<CustomField, CustomFieldJson>() {
@@ -135,10 +135,15 @@ public class CustomFieldResource extends JaxRsResourceBase {
                                                      customFieldUserApi.searchCustomFields(fieldName, fieldValue, ObjectType.valueOf(objectType), offset, limit, tenantContext) :
                                                      customFieldUserApi.searchCustomFields(fieldName,  ObjectType.valueOf(objectType), offset, limit, tenantContext);
 
-        final URI nextPageUri = uriBuilder.nextPage(CustomFieldResource.class, "searchCustomFields", customFields.getNextOffset(), limit, ImmutableMap.<String, String>of("objectType", objectType,
-                                                                                                                                                                          "fieldName", fieldName,
-                                                                                                                                                                          "fieldValue", MoreObjects.firstNonNull(fieldValue, ""),
-                                                                                                                                                                          QUERY_AUDIT, auditMode.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(CustomFieldResource.class,
+                                                    "searchCustomFields",
+                                                    customFields.getNextOffset(),
+                                                    limit,
+                                                    ImmutableMap.<String, String>of("objectType", objectType,
+                                                                                    "fieldName", fieldName,
+                                                                                    "fieldValue", MoreObjects.firstNonNull(fieldValue, ""),
+                                                                                    QUERY_AUDIT, auditMode.getLevel().toString()),
+                                                    ImmutableMap.<String, String>of());
         return buildStreamingPaginationResponse(customFields,
                                                 new Function<CustomField, CustomFieldJson>() {
                                                     @Override
@@ -166,8 +171,7 @@ public class CustomFieldResource extends JaxRsResourceBase {
                                        @javax.ws.rs.core.Context final HttpServletRequest request) throws CustomFieldApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(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.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(CustomFieldResource.class, "searchCustomFields", customFields.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()), ImmutableMap.<String, String>of("searchKey", searchKey));
         return buildStreamingPaginationResponse(customFields,
                                                 new Function<CustomField, CustomFieldJson>() {
                                                     @Override
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index 451811c6f3..7053e9425b 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -270,7 +270,7 @@ public class InvoiceResource extends JaxRsResourceBase {
                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws InvoiceApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(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_AUDIT, auditMode.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(InvoiceResource.class, "getInvoices", invoices.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()), ImmutableMap.<String, String>of());
 
 
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
@@ -302,8 +302,7 @@ public class InvoiceResource extends JaxRsResourceBase {
                                    @javax.ws.rs.core.Context final HttpServletRequest request) throws SubscriptionApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(request);
         final Pagination<Invoice> invoices = invoiceApi.searchInvoices(searchKey, offset, limit, tenantContext);
-        final URI nextPageUri = uriBuilder.nextPage(InvoiceResource.class, "searchInvoices", invoices.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
-                                                                                                                                                              QUERY_AUDIT, auditMode.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(InvoiceResource.class, "searchInvoices", invoices.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()), ImmutableMap.<String, String>of("searchKey", searchKey));
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
         return buildStreamingPaginationResponse(invoices,
                                                 new Function<Invoice, InvoiceJson>() {
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
index 5402912ebe..605bc77310 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
@@ -168,8 +168,13 @@ public class PaymentMethodResource extends JaxRsResourceBase {
             paymentMethods = paymentApi.getPaymentMethods(offset, limit, pluginName, withPluginInfo, pluginProperties, tenantContext);
         }
 
-        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.getLevel().toString()));
+        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.getLevel().toString()),
+                                                    ImmutableMap.<String, String>of());
 
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
         final Map<UUID, Account> accounts = new HashMap<UUID, Account>();
@@ -226,9 +231,13 @@ public class PaymentMethodResource extends JaxRsResourceBase {
             paymentMethods = paymentApi.searchPaymentMethods(searchKey, offset, limit, pluginName, withPluginInfo, pluginProperties, tenantContext);
         }
 
-        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.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(PaymentMethodResource.class,
+                                                    "searchPaymentMethods",
+                                                    paymentMethods.getNextOffset(),
+                                                    limit,
+                                                    ImmutableMap.<String, String>of(QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
+                                                                                    QUERY_AUDIT, auditMode.getLevel().toString()),
+                                                    ImmutableMap.<String, String>of("searchKey", searchKey));
 
         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/org/killbill/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
index bbe6e4aa62..99934df39e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
@@ -178,8 +178,13 @@ public class PaymentResource extends ComboPaymentResource {
             payments = paymentApi.getPayments(offset, limit, pluginName, withPluginInfo, withAttempts, pluginProperties, tenantContext);
         }
 
-        final URI nextPageUri = uriBuilder.nextPage(PaymentResource.class, "getPayments", payments.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
-                                                                                                                                                           QUERY_AUDIT, auditMode.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(PaymentResource.class,
+                                                    "getPayments",
+                                                    payments.getNextOffset(),
+                                                    limit,
+                                                    ImmutableMap.<String, String>of(QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
+                                                                                    QUERY_AUDIT, auditMode.getLevel().toString()),
+                                                    ImmutableMap.<String, String>of());
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
 
         return buildStreamingPaginationResponse(payments,
@@ -224,9 +229,13 @@ public class PaymentResource extends ComboPaymentResource {
             payments = paymentApi.searchPayments(searchKey, offset, limit, pluginName, withPluginInfo, withAttempts, pluginProperties, tenantContext);
         }
 
-        final URI nextPageUri = uriBuilder.nextPage(PaymentResource.class, "searchPayments", payments.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
-                                                                                                                                                              QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
-                                                                                                                                                              QUERY_AUDIT, auditMode.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(PaymentResource.class,
+                                                    "searchPayments",
+                                                    payments.getNextOffset(),
+                                                    limit,
+                                                    ImmutableMap.<String, String>of(QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
+                                                                                    QUERY_AUDIT, auditMode.getLevel().toString()),
+                                                    ImmutableMap.<String, String>of("searchKey", searchKey));
         final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
 
         return buildStreamingPaginationResponse(payments,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
index 9762fb8c05..bb76391d56 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
@@ -98,7 +98,7 @@ public class TagResource extends JaxRsResourceBase {
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(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.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(TagResource.class, "getTags", tags.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()), ImmutableMap.<String, String>of());
 
         final Map<UUID, TagDefinition> tagDefinitionsCache = new HashMap<UUID, TagDefinition>();
         for (final TagDefinition tagDefinition : tagUserApi.getTagDefinitions(tenantContext)) {
@@ -132,8 +132,7 @@ public class TagResource extends JaxRsResourceBase {
                                @javax.ws.rs.core.Context final HttpServletRequest request) throws TagApiException {
         final TenantContext tenantContext = context.createTenantContextNoAccountId(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.getLevel().toString()));
+        final URI nextPageUri = uriBuilder.nextPage(TagResource.class, "searchTags", tags.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_AUDIT, auditMode.getLevel().toString()), ImmutableMap.<String, String>of("searchKey", searchKey));
         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/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java
index 6d9f9b666c..d57cb06701 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java
@@ -117,7 +117,12 @@ public class JaxrsUriBuilder {
         return objectId != null ? uriBuilder.build(objectId) : uriBuilder.build();
     }
 
-    public URI nextPage(final Class<? extends JaxrsResource> theClass, final String getMethodName, final Long nextOffset, final Long limit, final Map<String, String> params) {
+    public URI nextPage(final Class<? extends JaxrsResource> theClass,
+                        final String getMethodName,
+                        final Long nextOffset,
+                        final Long limit,
+                        final Map<String, String> queryParams,
+                        final Map<String, String> pathParams) {
         if (nextOffset == null || limit == null) {
             // End of pagination?
             return null;
@@ -125,8 +130,11 @@ public class JaxrsUriBuilder {
 
         final UriBuilder uriBuilder = getUriBuilder(theClass, getMethodName).queryParam(JaxRsResourceBase.QUERY_SEARCH_OFFSET, nextOffset)
                                                                             .queryParam(JaxRsResourceBase.QUERY_SEARCH_LIMIT, limit);
-        for (final String key : params.keySet()) {
-            uriBuilder.queryParam(key, params.get(key));
+        for (final String key : queryParams.keySet()) {
+            uriBuilder.queryParam(key, queryParams.get(key));
+        }
+        for (final String key : pathParams.keySet()) {
+            uriBuilder.resolveTemplate(key, pathParams.get(key));
         }
         return uriBuilder.build();
     }
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
index d6bbd1b5d6..46dc3cc8bb 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
@@ -118,13 +118,27 @@ public class TestAccount extends TestJaxrsBase {
     public void testAccountOk() throws Exception {
         final Account input = createAccount();
 
+        // Create a second account (https://github.com/killbill/killbill/issues/1422 regression testing)
+        final Account secondAccount = createAccount();
+        final Account retrievedSecondAccount = accountApi.getAccountByKey(secondAccount.getExternalKey(), requestOptions);
+        Assert.assertEquals(secondAccount, retrievedSecondAccount);
+
         // Retrieves by external key
         final Account retrievedAccount = accountApi.getAccountByKey(input.getExternalKey(), requestOptions);
-        Assert.assertTrue(retrievedAccount.equals(input));
+        Assert.assertEquals(input, retrievedAccount);
 
         // Try search endpoint
         searchAccount(input, retrievedAccount);
 
+        // Force limit=1 (https://github.com/killbill/killbill/issues/1422 regression testing)
+        final Accounts allAccounts = accountApi.searchAccounts(input.getCompany(), 0L, 1L, false, false, AuditLevel.NONE, requestOptions);
+        // Company name is the same for both accounts
+        Assert.assertEquals(allAccounts.size(), 1);
+        Assert.assertEquals(allAccounts.get(0).getExternalKey(), retrievedAccount.getExternalKey());
+        final Accounts secondPage = allAccounts.getNext();
+        Assert.assertEquals(secondPage.size(), 1);
+        Assert.assertEquals(secondPage.get(0).getExternalKey(), retrievedSecondAccount.getExternalKey());
+
         // Update Account
         final Account newInput = new Account(input.getAccountId(),
                                              "zozo", 4, input.getExternalKey(), "rr@google.com", 18,
@@ -445,9 +459,6 @@ public class TestAccount extends TestJaxrsBase {
         // Search by email
         doSearchAccount(input.getEmail(), output);
 
-        // Search by company name
-        doSearchAccount(input.getCompany(), output);
-
         // Search by external key.
         // Note: we will always find a match since we don't update it
         final List<Account> accountsByExternalKey = accountApi.searchAccounts(input.getExternalKey(), requestOptions);