public void add() {
    Integer pageNumber = getIntParameter(PAGE_NUMBER_KEY);

    if (!IntegerUtils.isPositive(pageNumber)) {
      pageNumber = 1;
    }

    long itemCount = factory.getCount();
    int pageCount = PaginationUtils.getPageCount(itemCount, pageSize);
    if (pageNumber > pageCount) {
      pageNumber = pageCount;
    }

    String pageUrl = request.getRequestURI();

    List<String> parameters = new ArrayList<>();
    @SuppressWarnings("unchecked")
    Set<Map.Entry<String, Object>> entries = request.getParameterMap().entrySet();
    for (Map.Entry<String, Object> entry : entries) {
      if (entry.getKey().equals(PAGE_NUMBER_KEY)) {
        continue;
      }

      Object value = entry.getValue();
      if (value == null) {
        continue;
      }

      if (value instanceof String) {
        parameters.add(entry.getKey() + "=" + UrlUtils.encode((String) value));
      } else if (value.getClass().isArray()) {
        String[] strings = (String[]) value;
        if (strings.length > 0) {
          parameters.add(entry.getKey() + "=" + UrlUtils.encode(strings[0]));
        }
      }
    }
    if (parameters.size() > 0) {
      pageUrl += "?" + Joiner.on("&").join(parameters);
    }

    List<PaginationAnchor> anchors =
        PaginationAnchor.create(pageUrl, pageCount, visibleButtonSize, pageNumber);

    request.setAttribute("paginationAnchors", anchors);
    request.setAttribute("rowStartIndex", (pageNumber - 1) * pageSize + 1);
    request.setAttribute(rowItemsName, factory.getInstances((pageNumber - 1) * pageSize, pageSize));
    request.setAttribute(rowItemCountName, itemCount);
  }
  private <T> T callRecurly(
      final AsyncHttpClient.BoundRequestBuilder builder, @Nullable final Class<T> clazz)
      throws IOException, ExecutionException, InterruptedException {
    final Response response =
        builder
            .addHeader("Authorization", "Basic " + key)
            .addHeader("Accept", "application/xml")
            .addHeader("Content-Type", "application/xml; charset=utf-8")
            .execute()
            .get();

    final InputStream in = response.getResponseBodyAsStream();
    try {
      final String payload = convertStreamToString(in);
      if (debug()) {
        log.info("Msg from Recurly API :: {}", payload);
      }

      // Handle errors payload
      if (response.getStatusCode() >= 300) {
        log.warn("Recurly error whilst calling: {}\n{}", response.getUri(), payload);

        if (response.getStatusCode() == 422) {
          final Errors errors;
          try {
            errors = xmlMapper.readValue(payload, Errors.class);
          } catch (Exception e) {
            // 422 is returned for transaction errors (see
            // http://docs.recurly.com/api/transactions/error-codes)
            // as well as bad input payloads
            log.debug("Unable to extract error", e);
            return null;
          }
          throw new TransactionErrorException(errors);
        } else {
          RecurlyAPIError recurlyError = null;
          try {
            recurlyError = xmlMapper.readValue(payload, RecurlyAPIError.class);
          } catch (Exception e) {
            log.debug("Unable to extract error", e);
          }
          throw new RecurlyAPIException(recurlyError);
        }
      }

      if (clazz == null) {
        return null;
      }

      final T obj = xmlMapper.readValue(payload, clazz);
      if (obj instanceof RecurlyObject) {
        ((RecurlyObject) obj).setRecurlyClient(this);
      } else if (obj instanceof RecurlyObjects) {
        final RecurlyObjects recurlyObjects = (RecurlyObjects) obj;
        recurlyObjects.setRecurlyClient(this);

        // Set the RecurlyClient on all objects for later use
        for (final Object object : recurlyObjects) {
          ((RecurlyObject) object).setRecurlyClient(this);
        }

        // Set the total number of records
        final String xRecords = response.getHeader(X_RECORDS_HEADER_NAME);
        if (xRecords != null) {
          recurlyObjects.setNbRecords(Integer.valueOf(xRecords));
        }

        // Set links for pagination
        final String linkHeader = response.getHeader(LINK_HEADER_NAME);
        if (linkHeader != null) {
          final String[] links = PaginationUtils.getLinks(linkHeader);
          recurlyObjects.setStartUrl(links[0]);
          recurlyObjects.setPrevUrl(links[1]);
          recurlyObjects.setNextUrl(links[2]);
        }
      }
      return obj;
    } finally {
      closeStream(in);
    }
  }