@Override
 public boolean waitForExist(String reqId) throws TimeoutException, ErrorResultReceivedException {
   boolean res = false;
   int countTimeOut = WAIT_TIMEOUT;
   int incOffset = 500;
   client.keepAlive();
   if (existsResponseMap.containsKey(reqId)) {
     while (VOID_RESULT.equals(existsResponseMap.get(reqId))) {
       try {
         client.keepAlive();
         Thread.sleep(500);
         countTimeOut = countTimeOut - incOffset;
         if (countTimeOut <= 0) {
           existsResponseMap.remove(reqId);
           throw new TimeoutException(
               "No Response received for request: "
                   + reqId
                   + " after "
                   + (WAIT_TIMEOUT / 1000)
                   + "s !");
         }
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
     if (existsResponseMap.get(reqId) instanceof TestResult) {
       throw new ErrorResultReceivedException((TestResult) existsResponseMap.get(reqId));
     }
     res = (Boolean) existsResponseMap.get(reqId);
     existsResponseMap.remove(reqId);
   }
   return res;
 }
 private void checkConnection() {
   if (!started) {
     start(host);
   }
   if (!client.isConnected()) {
     reconnect();
   }
 }
 protected void startConnectionLoop() {
   while (!client.isConnected()) {
     reconnect();
     try {
       Thread.sleep(RECONNECTION_RATE);
     } catch (InterruptedException e) {
       e.printStackTrace();
     }
   }
 }
 @Override
 public void start(String host) {
   try {
     client.connect(300000, host, CommonIOUtils.DRIVER_TCP_PORT);
     this.started = true;
   } catch (IOException e) {
     LOG.error(e.getMessage(), e);
     // startConnectionLoop();
   }
 }
 @Override
 public void process(IIdRequest request) {
   checkConnection();
   init();
   if (request.getId() != null) {
     existsResponseMap.put(request.getId(), VOID_RESULT);
   }
   // TODO: block any request with No ID !!
   client.sendRequest(request);
 }
 protected void reconnect() {
   try {
     client.reconnect();
     this.started = true;
   } catch (Exception e) {
     LOG.error(
         String.format(
             "Server unreachable, reattempting to connect in %d !", RECONNECTION_RATE / 1000));
   }
 }
 private ValueResponse waitForValue(final IIdRequest request)
     throws TimeoutException, ErrorResultReceivedException {
   client.keepAlive();
   final String idRequest = request.getId();
   ValueResponse res = null;
   int countTimeOut = WAIT_TIMEOUT;
   int incOffset = 500;
   if (valueResponseMap.containsKey(idRequest)) {
     while (VOID_RESULT.equals(valueResponseMap.get(idRequest))) {
       try {
         client.keepAlive();
         Thread.sleep(incOffset);
         countTimeOut = countTimeOut - incOffset;
         if (countTimeOut <= 0) {
           valueResponseMap.remove(idRequest);
           throw new TimeoutException(
               "No Response received for request: "
                   + idRequest
                   + " after "
                   + (WAIT_TIMEOUT / 1000)
                   + "s !");
         }
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
     if (valueResponseMap.get(idRequest) instanceof ITestResult) {
       ITestResult result = (ITestResult) valueResponseMap.get(idRequest);
       ValueResponse valueResponse =
           new ValueResponse(idRequest, result.getMessage(), result.getScreenShot());
       valueResponseMap.remove(idRequest);
       return valueResponse;
     }
     res = (ValueResponse) valueResponseMap.get(idRequest);
     valueResponseMap.remove(idRequest);
   }
   return res;
 }
  @Override
  public ITestResult processAndWaitForValue(IIdRequest request)
      throws IllegalAccessException, TimeoutException, ErrorResultReceivedException {

    final String idRequest = request.getId();
    if (idRequest == null) {
      throw new IllegalAccessException("Request requires an Id to wait for a value.");
    }
    init();
    valueResponseMap.put(idRequest, VOID_RESULT);
    client.sendRequest(request);
    ValueResponse valueResponse = waitForValue(request);
    ITestResult res = new SuccessResult(valueResponse.value);
    res.setScreenShot(valueResponse.getBase64ScreenShot());
    return res;
  }
 private void initListeners() {
   client.addResponseHandler(
       new ITCPResponseReceivedHandler() {
         @Override
         public void onResponseReceived(Object object) {
           if (object instanceof ExistsResponse) {
             handleExistsResponse(object);
           } else if (object instanceof ValueResponse) {
             handleValueResponse(object);
           } else if (object instanceof ErrorResponse) {
             handleErrorResponse(object);
           } else if (object instanceof InitResponse) {
             handleInitResponse(object);
           } else {
             handleRemainingResponse(object);
           }
         }
       });
 }
 @Override
 public void stop() {
   client.close();
 }
 /**
  * to call before any request
  *
  * @return
  */
 public void init() {
   checkConnection();
   InitInspectionRequest request = new InitInspectionRequest();
   client.sendRequest(request);
 }