private static boolean __isDeviceAvailable(
      EspSocketClient client,
      String uriStr,
      String router,
      String deviceBssid,
      String localInetAddress,
      int port) {
    log.debug("__isDeviceAvailable()");
    // create request
    String content =
        __createIsDeviceAvailableRequestContent(router, deviceBssid, localInetAddress, port);
    IEspSocketRequest requestEntity = new EspSocketRequestBaseEntity(METHOD_POST, uriStr, content);
    // send request
    if (!__sendRequest(client, requestEntity)) {
      log.warn("__isDeviceAvailable(): send request fail");
      return false;
    }
    // receive response
    IEspSocketResponse responseEntity = __receiveOneResponse(client);
    log.info("__isDeviceAvailable() response:\n" + responseEntity);
    String command = null;
    if (responseEntity != null) {
      try {
        JSONObject resultJson = new JSONObject(responseEntity.getContentBodyStr());
        command = resultJson.getString(COMMAND);
      } catch (JSONException e) {
        e.printStackTrace();
      }
    }

    // analyze the response to decide whether the device is available
    return command != null ? __checkIsDeviceAvailable(command) : false;
  }
  private static JSONArray __executeForJsonArray(
      EspSocketClient client,
      String method,
      String uriStr,
      String router,
      String deviceBssid,
      JSONObject json,
      boolean checkIsDeviceAvailable,
      boolean closeClientImmdeiately,
      int targetPort,
      HeaderPair... headers) {
    log.debug("__executeForJsonArray()");
    boolean isConnectRequired = false;
    JSONArray jsonArrayResult = new JSONArray();

    // it is used just to get host by uri
    IEspSocketRequest request1 = new EspSocketRequestBaseEntity(method, uriStr);
    // check whether the uri is about to ask topology
    if (!request1.equals("")) {
      deviceBssid = null;
    }
    String host = request1.getHost();
    if (client == null) {
      client = new EspSocketClient();
      isConnectRequired = true;
    }
    client.setSoTimeout(SO_TIMEOUT);

    // connect
    boolean isConnectSuc = false;
    if (isConnectRequired) {
      for (int i = 0; i < CONNECT_RETRY; i++) {
        if (__connect(client, host, targetPort, SO_TIMEOUT)) {
          isConnectSuc = true;
          break;
        }
        try {
          Thread.sleep(500);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    } else {
      isConnectSuc = true;
    }
    if (!isConnectSuc) {
      __closeClient(client);
      return null;
    }
    String localInetAddress = client.getLocalAddressStr();
    int localPort = client.getLocalPort();

    // add necessary elements in json
    json = __addNecessaryElements(json, router, deviceBssid, localInetAddress, localPort);
    log.debug("json = " + json);
    EspSocketRequestBaseEntity request =
        new EspSocketRequestBaseEntity(method, uriStr, json.toString());

    if (headers != null) {
      // add headers
      for (HeaderPair header : headers) {
        request.putHeaderParams(header.getName(), header.getValue());
      }
    }

    // check whether device is available
    if (checkIsDeviceAvailable
        && !__isDeviceAvailable(client, uriStr, router, deviceBssid, localInetAddress, localPort)) {
      __closeClient(client);
      return null;
    }

    // send request
    if (!__sendRequest(client, request)) {
      log.warn("__executeForJsonArray(): send request fail");
      __closeClient(client);
      return null;
    }

    log.error("jsonArrayResult (start) ip: " + host);
    // receive response
    IEspSocketResponse responseEntity = __receiveOneResponse(client);
    JSONObject jsonResult = null;
    while (responseEntity != null) {
      try {
        jsonResult = new JSONObject(responseEntity.getContentBodyStr());
      } catch (JSONException e) {
        e.printStackTrace();
      }
      if (jsonResult != null) {
        jsonArrayResult.put(jsonResult);
        log.debug("one response is received");
        responseEntity = __receiveOneResponse(client);
      } else {
        break;
      }
    }
    log.debug("receive responses end");
    if (closeClientImmdeiately) {
      __closeClient(client);
    }
    log.error("jsonArrayResult (end) ip: " + host);
    log.error("jsonArrayResult.length(): " + jsonArrayResult.length());
    log.error("jsonArrayResult: " + jsonArrayResult);
    return (jsonArrayResult.length() == 0) ? (null) : (jsonArrayResult);
  }