protected void initHttpClient() {
    try {
      HttpClientBuilder builder = HttpClient.uri(url);

      // set method, default to GET
      builder = builder.method(null == method ? HttpMethod.GET : method);

      // set credentials
      if (null != credentials && credentials.isValid()) {
        builder = builder.credentials(credentials.getUsername(), credentials.getPassword());
      }

      // set keystore
      if (null != keystore && keystore.isValid()) {
        builder = builder.keyStore(new FileInputStream(keystore.getFile()), keystore.getPassword());
      }

      // set headers
      if (null != headers && headers.isValid()) {
        for (final HeaderNode header : headers.getHeaders()) {
          builder = builder.header(header.getName(), header.getValue());
        }
      }

      // set query parameters
      if (null != query && query.isValid()) {
        for (final QueryParameterNode qp : query.getParameters()) {
          builder = builder.query(qp.getName(), qp.getValue());
        }
      }

      // set request entity
      if (null != entity && entity.isValid()) {
        // prefer file
        if (null != entity.getFile()) {
          final FileInputStream is = new FileInputStream(entity.getFile());
          final ByteArrayOutputStream os = new ByteArrayOutputStream();
          final byte[] buf = new byte[1024];
          try {
            for (int num; (num = is.read(buf)) != -1; ) {
              os.write(buf, 0, num);
            }
          } catch (final IOException e) {
            throw new BuildException(e);
          }

          builder = builder.entity(new ByteArrayInputStream(os.toByteArray()));
        } else {
          builder = builder.entity(entity.getText());
        }
      }

      httpClient = builder.toHttpClient();

    } catch (final Throwable t) {
      throw new BuildException(t);
    }
  }
  @Override
  public void execute() {
    super.execute();

    // setup HttpClient
    initHttpClient();

    if (printRequestHeaders) {
      log("********************");
      log("HTTP Request");
      log("********************");
      log("URL:\t\t" + httpClient.getUri());
      log("Method:\t\t" + httpClient.getMethod().name());
      log("Credentials:\t" + (null == httpClient.getUsername() ? "no" : "yes"));
      if (httpClient.getHeaders().size() > 0) {
        log("Headers:\t\tyes");
        for (final Entry<String, String> entry : httpClient.getHeaders().entrySet()) {
          log("\t" + entry.getKey() + ": " + entry.getValue());
        }
      } else {
        log("Headers:\t\tno");
      }
      if (httpClient.getQueryUnencoded().size() > 0) {
        log("Query Parameters:\tyes");
        for (final Entry<String, String> entry : httpClient.getQueryUnencoded().entrySet()) {
          log("\t" + entry.getKey() + "=" + entry.getValue());
        }
      } else {
        log("Query Parameters:\tno");
      }
      log("Entity:\t\t" + (null == httpClient.getEntity() ? "no" : "yes"));
      if (null != httpClient.getEntity() && printRequest) {
        try {
          log("------ BEGIN ENTITY ------");
          log(httpClient.getEntityAsString());
          log("------- END ENTITY -------");
        } catch (final IOException e) {
          log(e, Project.MSG_ERR);
          throw new BuildException(e);
        }
      }
    } else {
      log("HTTP " + httpClient.getMethod().name() + " request to " + httpClient.getUri());
    }

    // invoke HttpClient
    HttpResponse response = null;
    try {
      response = httpClient.invoke();
    } catch (final HttpInvocationException e) {
      throw new BuildException(e);
    } catch (final HttpCertificateException e) {
      throw new BuildException(e);
    } catch (final Throwable t) {
      throw new BuildException(t);
    }

    if (null != response) {
      if (printResponseHeaders) {
        log("");
        log("********************");
        log("HTTP Response");
        log("********************");
        log("Status:\t\t" + response.getStatus());
        if (response.getHeaders().size() > 0) {
          log("Headers:\t\tyes");
          for (final Entry<String, List<String>> entry : response.getHeaders().entrySet()) {
            for (final String value : entry.getValue()) {
              if (null == entry.getKey()) {
                log("\t" + value);
              } else {
                log("\t" + entry.getKey() + ": " + value);
              }
            }
          }
        } else {
          log("Headers:\t\tno");
        }
      }

      if (null == outFile) {
        log("Entity:\t\t" + (null == response.getEntity() ? "no" : "yes"));
        if (null != response.getEntity() && printResponse) {
          try {
            log("------ BEGIN ENTITY ------");
            log(response.getEntityAsString());
            log("------- END ENTITY -------");
          } catch (final IOException e) {
            log(e, Project.MSG_ERR);
            throw new BuildException(e);
          }
        }
      } else if (null != response.getEntity()) {
        if (printResponse) {
          log("Entity written to file:\t" + outFile.getAbsolutePath());
        }
        try {
          final FileOutputStream fos = new FileOutputStream(outFile);
          fos.write(response.getEntity());
          fos.close();
        } catch (final Throwable t) {
          throw new BuildException(
              "Failed to write response entity to file: " + outFile.getAbsolutePath(), t);
        }
      }

      if (response.getStatus() != expected && failOnUnexpected) {
        throw new BuildException(
            "Expected Status [" + expected + "] but got [" + response.getStatus() + "]");
      }
    }
  }