/**
   * Call recurly API.
   *
   * @param <T> the generic type
   * @param <E> the element type
   * @param path the path
   * @param payload the payload
   * @param responseClass the response class
   * @param method the method
   * @param headers the headers
   * @return the t
   * @throws RecurlyException the recurly exception
   */
  protected <T, E> T call(
      String path, E payload, Class<T> responseClass, HttpMethod method, HttpHeaders headers)
      throws RecurlyException {

    URI uri = null;
    ResponseEntity<T> responseEntity = null;
    T reponse = null;
    HttpEntity<?> entity = null;
    try {
      if (headers == null) {
        entity = new HttpEntity<>(payload, recurly.getRecurlyHeaders());
      } else {
        entity = new HttpEntity<>(payload, headers);
      }
      uri = new URI(URIUtil.encodeQuery(recurly.getRecurlyServerURL() + path, "UTF-8"));
      getLogger().debug("Calling Recurly URL {}, method: {}", uri.toString(), method.toString());
      responseEntity = restTemplate.exchange(uri, method, entity, responseClass);
      if (responseEntity != null) reponse = responseEntity.getBody();

    } catch (URIException | UnsupportedEncodingException | URISyntaxException e) {
      throw new RecurlyException("Not able to reach recurly. Please check the URL.", e);
    } catch (RestClientException e) {
      String err = ((HttpStatusCodeException) e).getResponseBodyAsString();
      int code = ((HttpStatusCodeException) e).getStatusCode().value();
      publishError(uri.toString(), err, code);
      RecurlyException ex = handleError(err, code, e);
      throw ex;
    }
    return reponse;
  }
 /**
  * Publish error via Notify method passed in.
  *
  * @param url the api path.
  * @param error the error
  * @param code the error http code
  */
 private void publishError(String url, String error, Integer code) {
   if (recurly.getErrorNotifier() != null) {
     recurly.getErrorNotifier().publish(error, code);
     getLogger().info("Notified Error via publish message.");
   }
 }