@Override
  public Response handle(Request request) {
    ResponseDefinition responseDefinition = handleRequest(request);
    responseDefinition.setOriginalRequest(request);

    Response response = responseRenderer.render(responseDefinition);
    for (RequestListener listener : listeners) {
      listener.requestReceived(request, response);
    }

    if (responseDefinition.getCallbackRequest() != null) {
      CallbackRequestDispatcher.dispatch(responseDefinition.getCallbackRequest(), request);
    }

    return response;
  }
 private static void addBodyIfPostOrPut(HttpRequest httpRequest, ResponseDefinition response)
     throws UnsupportedEncodingException {
   Request originalRequest = response.getOriginalRequest();
   if (originalRequest.getMethod().isOneOf(PUT, POST)) {
     HttpEntityEnclosingRequest requestWithEntity = (HttpEntityEnclosingRequest) httpRequest;
     requestWithEntity.setEntity(buildEntityFrom(originalRequest));
   }
 }
 private static void addRequestHeaders(HttpRequest httpRequest, ResponseDefinition response) {
   Request originalRequest = response.getOriginalRequest();
   for (String key : originalRequest.getAllHeaderKeys()) {
     if (headerShouldBeTransferred(key)) {
       String value = originalRequest.getHeader(key);
       httpRequest.addHeader(key, value);
     }
   }
 }
  private static HttpUriRequest getHttpRequestFor(ResponseDefinition response) {
    RequestMethod method = response.getOriginalRequest().getMethod();
    String url = response.getProxyUrl();
    notifier().info("Proxying: " + method + " " + url);

    switch (method) {
      case GET:
        return new HttpGet(url);
      case POST:
        return new HttpPost(url);
      case PUT:
        return new HttpPut(url);
      case DELETE:
        return new HttpDelete(url);
      case HEAD:
        return new HttpHead(url);
      case OPTIONS:
        return new HttpOptions(url);
      case TRACE:
        return new HttpTrace(url);
      default:
        throw new RuntimeException("Cannot create HttpMethod for " + method);
    }
  }