private HttpResponse execute(
      HttpMethodEnum method, String path, HashMap<String, String> headers) {
    try {
      URI uri = URI.create(server.getEndpoint() + path);
      HttpResponse response;
      HttpRequestBase hrb;
      switch (method) {
        case GET:
          hrb = new HttpGet(uri);
          break;
        case PUT:
          hrb = new HttpPut(uri);
          break;
        case POST:
          hrb = new HttpPost(uri);
          break;
        case PATCH:
          hrb = new HttpPatch(uri);
          break;
          //      case Merge:
          //        hrb = new HttpMerge(uri);
          //        break;
        case DELETE:
          hrb = new HttpDelete(uri);
          break;
        default:
          throw new RuntimeException("Method unsupported: " + method);
      }

      if (null != headers) {
        for (String header : headers.keySet()) hrb.setHeader(header, headers.get(header));
      }

      response = client.execute(hrb);
      hrb.reset();
      return response;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * @param uri Url.
   * @param params Params.
   * @param demo Use demo node.
   * @param mtd Method.
   * @param headers Headers.
   * @param body Body.
   */
  protected RestResult executeRest(
      String uri,
      Map<String, Object> params,
      boolean demo,
      String mtd,
      Map<String, Object> headers,
      String body)
      throws IOException, URISyntaxException {
    if (log.isDebugEnabled())
      log.debug(
          "Start execute REST command [method="
              + mtd
              + ", uri=/"
              + (uri == null ? "" : uri)
              + ", parameters="
              + params
              + "]");

    final URIBuilder builder;

    if (demo) {
      // try start demo if needed.
      AgentClusterDemo.testDrive(cfg);

      // null if demo node not started yet.
      if (cfg.demoNodeUri() == null) return RestResult.fail("Demo node is not started yet.", 404);

      builder = new URIBuilder(cfg.demoNodeUri());
    } else builder = new URIBuilder(cfg.nodeUri());

    if (builder.getPort() == -1) builder.setPort(DFLT_NODE_PORT);

    if (uri != null) {
      if (!uri.startsWith("/") && !cfg.nodeUri().endsWith("/")) uri = '/' + uri;

      builder.setPath(uri);
    }

    if (params != null) {
      for (Map.Entry<String, Object> entry : params.entrySet()) {
        if (entry.getValue() != null)
          builder.addParameter(entry.getKey(), entry.getValue().toString());
      }
    }

    HttpRequestBase httpReq = null;

    try {
      if ("GET".equalsIgnoreCase(mtd)) httpReq = new HttpGet(builder.build());
      else if ("POST".equalsIgnoreCase(mtd)) {
        HttpPost post;

        if (body == null) {
          List<NameValuePair> nvps = builder.getQueryParams();

          builder.clearParameters();

          post = new HttpPost(builder.build());

          if (!nvps.isEmpty()) post.setEntity(new UrlEncodedFormEntity(nvps));
        } else {
          post = new HttpPost(builder.build());

          post.setEntity(new StringEntity(body));
        }

        httpReq = post;
      } else throw new IOException("Unknown HTTP-method: " + mtd);

      if (headers != null) {
        for (Map.Entry<String, Object> entry : headers.entrySet())
          httpReq.addHeader(
              entry.getKey(), entry.getValue() == null ? null : entry.getValue().toString());
      }

      try (CloseableHttpResponse resp = httpClient.execute(httpReq)) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        resp.getEntity().writeTo(out);

        Charset charset = Charsets.UTF_8;

        Header encodingHdr = resp.getEntity().getContentEncoding();

        if (encodingHdr != null) {
          String encoding = encodingHdr.getValue();

          charset = Charsets.toCharset(encoding);
        }

        return RestResult.success(
            resp.getStatusLine().getStatusCode(), new String(out.toByteArray(), charset));
      } catch (ConnectException e) {
        log.info("Failed connect to node and execute REST command [uri=" + builder.build() + "]");

        return RestResult.fail("Failed connect to node and execute REST command.", 404);
      }
    } finally {
      if (httpReq != null) httpReq.reset();
    }
  }