protected AsyncRequestWrapperImpl(
      final ODataClient odataClient, final ODataRequest odataRequest) {
    this.odataRequest = odataRequest;
    this.odataRequest.setAccept(this.odataRequest.getAccept());
    this.odataRequest.setContentType(this.odataRequest.getContentType());

    extendHeader(HttpHeader.PREFER, new ODataPreferences().respondAsync());

    this.odataClient = odataClient;
    final HttpMethod method = odataRequest.getMethod();

    // target uri
    this.uri = odataRequest.getURI();

    HttpClient _httpClient =
        odataClient.getConfiguration().getHttpClientFactory().create(method, this.uri);
    if (odataClient.getConfiguration().isGzipCompression()) {
      _httpClient = new DecompressingHttpClient(_httpClient);
    }
    this.httpClient = _httpClient;

    this.request =
        odataClient.getConfiguration().getHttpUriRequestFactory().create(method, this.uri);

    if (request instanceof HttpEntityEnclosingRequestBase) {
      if (odataRequest instanceof AbstractODataBasicRequest) {
        AbstractODataBasicRequest br = (AbstractODataBasicRequest) odataRequest;
        HttpEntityEnclosingRequestBase httpRequest = ((HttpEntityEnclosingRequestBase) request);
        httpRequest.setEntity(new InputStreamEntity(br.getPayload(), -1));
      }
    }
  }
  protected HttpResponse doExecute() {
    // Add all available headers
    for (String key : odataRequest.getHeaderNames()) {
      final String value = odataRequest.getHeader(key);
      this.request.addHeader(key, value);
      LOG.debug("HTTP header being sent {}: {}", key, value);
    }

    return executeHttpRequest(httpClient, this.request);
  }
  protected final HttpResponse executeHttpRequest(
      final HttpClient client, final HttpUriRequest req) {
    final HttpResponse response;
    try {
      response = client.execute(req);
    } catch (IOException e) {
      throw new HttpClientException(e);
    } catch (RuntimeException e) {
      req.abort();
      throw new HttpClientException(e);
    }

    checkResponse(odataClient, response, odataRequest.getAccept());

    return response;
  }