/** {@inheritDoc} */
  @Override
  public ByteBuffer makeResponse(final GridRestResponse restRes, List<String> params) {
    if (restRes.getResponse() == null) return GridRedisProtocolParser.toBulkString("");

    if (restRes.getResponse() instanceof String) {
      String res = String.valueOf(restRes.getResponse());
      int startOff;
      int endOff;

      try {
        startOff = boundedStartOffset(Integer.parseInt(params.get(START_OFFSET_POS)), res.length());
        endOff = boundedEndOffset(Integer.parseInt(params.get(END_OFFSET_POS)), res.length());
      } catch (NumberFormatException e) {
        U.error(log, "Erroneous offset", e);

        return GridRedisProtocolParser.toGenericError("Offset is not an integer");
      }

      return GridRedisProtocolParser.toBulkString(res.substring(startOff, endOff));
    } else
      return GridRedisProtocolParser.toTypeError(
          "Operation against a key holding the wrong kind of value");
  }
  /**
   * Process HTTP request.
   *
   * @param act Action.
   * @param req Http request.
   * @param res Http response.
   */
  private void processRequest(String act, HttpServletRequest req, HttpServletResponse res) {
    res.setContentType("application/json");
    res.setCharacterEncoding("UTF-8");

    GridRestCommand cmd = command(req);

    if (cmd == null) {
      res.setStatus(HttpServletResponse.SC_BAD_REQUEST);

      return;
    }

    if (!authChecker.apply(req.getHeader("X-Signature"))) {
      res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

      return;
    }

    GridRestResponse cmdRes;

    Map<String, Object> params = parameters(req);

    try {
      GridRestRequest cmdReq = createRequest(cmd, params, req);

      if (log.isDebugEnabled()) log.debug("Initialized command request: " + cmdReq);

      cmdRes = hnd.handle(cmdReq);

      if (cmdRes == null)
        throw new IllegalStateException("Received null result from handler: " + hnd);

      byte[] sesTok = cmdRes.sessionTokenBytes();

      if (sesTok != null) cmdRes.setSessionToken(U.byteArray2HexString(sesTok));

      res.setStatus(HttpServletResponse.SC_OK);
    } catch (Throwable e) {
      res.setStatus(HttpServletResponse.SC_OK);

      U.error(log, "Failed to process HTTP request [action=" + act + ", req=" + req + ']', e);

      cmdRes = new GridRestResponse(STATUS_FAILED, e.getMessage());

      if (e instanceof Error) throw (Error) e;
    }

    String json;

    try {
      json = jsonMapper.writeValueAsString(cmdRes);
    } catch (JsonProcessingException e1) {
      U.error(log, "Failed to convert response to JSON: " + cmdRes, e1);

      GridRestResponse resFailed = new GridRestResponse(STATUS_FAILED, e1.getMessage());

      try {
        json = jsonMapper.writeValueAsString(resFailed);
      } catch (JsonProcessingException e2) {
        json = "{\"successStatus\": \"1\", \"error:\" \"" + e2.getMessage() + "\"}}";
      }
    }

    try {
      if (log.isDebugEnabled()) log.debug("Parsed command response into JSON object: " + json);

      res.getWriter().write(json);

      if (log.isDebugEnabled())
        log.debug(
            "Processed HTTP request [action=" + act + ", jsonRes=" + cmdRes + ", req=" + req + ']');
    } catch (IOException e) {
      U.error(log, "Failed to send HTTP response: " + json, e);
    }
  }