/**
   * Executes the request and returns the result.
   *
   * @param request The AmazonWebServices request to send to the remote server
   * @param responseHandler A response handler to accept a successful response from the remote
   *     server
   * @param errorResponseHandler A response handler to accept an unsuccessful response from the
   *     remote server
   * @param executionContext Additional information about the context of this web service call
   */
  public <T> T execute(
      Request<?> request,
      HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler,
      HttpResponseHandler<AmazonServiceException> errorResponseHandler,
      ExecutionContext executionContext)
      throws AmazonClientException, AmazonServiceException {
    long startTime = System.currentTimeMillis();

    if (executionContext == null)
      throw new AmazonClientException(
          "Internal SDK Error: No execution context parameter specified.");
    List<RequestHandler> requestHandlers = executionContext.getRequestHandlers();
    if (requestHandlers == null) requestHandlers = new ArrayList<RequestHandler>();

    // Apply any additional service specific request handlers that need to be run
    for (RequestHandler requestHandler : requestHandlers) {
      requestHandler.beforeRequest(request);
    }

    try {
      TimingInfo timingInfo = new TimingInfo(startTime);
      executionContext.setTimingInfo(timingInfo);
      T t = executeHelper(request, responseHandler, errorResponseHandler, executionContext);
      timingInfo.setEndTime(System.currentTimeMillis());

      for (RequestHandler handler : requestHandlers) {
        try {
          handler.afterResponse(request, t, timingInfo);
        } catch (ClassCastException cce) {
        }
      }
      return t;
    } catch (AmazonClientException e) {
      for (RequestHandler handler : requestHandlers) {
        handler.afterError(request, e);
      }
      throw e;
    }
  }