/**
   * Wrap the incoming value into quotes and escape any inner quotes with double quotes.
   *
   * @param value - The value to wrap quotes around
   * @return '-' if empty of null. Otherwise, toString() will be called on the object and the value
   *     will be wrapped in quotes and any quotes will be escaped with 2 sets of quotes.
   */
  public String wrap(Object value) {
    String svalue;
    // Does the value contain a " ? If so must encode it
    if (value == null || "-".equals(value)) {
      return "-";
    }

    try {
      svalue = value.toString();
      if ("".equals(svalue)) {
        return "-";
      }
    } catch (Throwable e) {
      ExceptionUtils2.handleThrowable(e);
      /* Log error */
      return "-";
    }

    /* Wrap all quotes in double quotes. */
    StringBuilder buffer = new StringBuilder(svalue.length() + 2);
    buffer.append('\'');
    int i = 0;
    while (i < svalue.length()) {
      int j = svalue.indexOf('\'', i);
      if (j == -1) {
        buffer.append(svalue.substring(i));
        i = svalue.length();
      } else {
        buffer.append(svalue.substring(i, j + 1));
        buffer.append('"');
        i = j + 2;
      }
    }

    buffer.append('\'');
    return buffer.toString();
  }
  /**
   * Process pipelined HTTP requests using the specified input and output streams.
   *
   * @throws IOException error during an I/O operation
   */
  @Override
  public SocketState process(SocketWrapper<Long> socket) throws IOException {
    RequestInfo rp = getRequest().getRequestProcessor();
    rp.setStage(Constants24.getStageParse());

    // Setting up the socket
    this.setSocketWrapper(socket);
    long socketRef = socket.getSocket().longValue();
    Socket.setrbb(socketRef, inputBuffer);
    Socket.setsbb(socketRef, outputBuffer);
    boolean cping = false;

    boolean keptAlive = false;

    while (!getErrorState().isError() && !getEndpoint().isPaused()) {
      // Parsing the request header
      try {
        // Get first message of the request
        if (!readMessage(getRequestHeaderMessage(), true, keptAlive)) {
          // This means that no data is available right now
          // (long keepalive), so that the processor should be recycled
          // and the method should return true
          break;
        }
        // Check message type, process right away and break if
        // not regular request processing
        int type = getRequestHeaderMessage().getByte();
        if (type == Constants25.getJkAjp13CpingRequest()) {
          if (getEndpoint().isPaused()) {
            recycle(true);
            break;
          }
          cping = true;
          if (Socket.send(socketRef, getPongmessagearray(), 0, getPongmessagearray().length) < 0) {
            setErrorState(ErrorState.CLOSE_NOW, null);
          }
          continue;
        } else if (type != Constants25.getJkAjp13ForwardRequest()) {
          // Unexpected packet type. Unread body packets should have
          // been swallowed in finish().
          if (log.isDebugEnabled()) {
            log.debug("Unexpected message: " + type);
          }
          setErrorState(ErrorState.CLOSE_NOW, null);
          break;
        }
        keptAlive = true;
        getRequest().setStartTime(System.currentTimeMillis());
      } catch (IOException e) {
        setErrorState(ErrorState.CLOSE_NOW, e);
        break;
      } catch (Throwable t) {
        ExceptionUtils2.handleThrowable(t);
        log.debug(getSm().getString("ajpprocessor.header.error"), t);
        // 400 - Bad Request
        getResponse().setStatus(400);
        setErrorState(ErrorState.CLOSE_CLEAN, t);
        getAdapter().log(getRequest(), getResponse(), 0);
      }

      if (!getErrorState().isError()) {
        // Setting up filters, and parse some request headers
        rp.setStage(Constants24.getStagePrepare());
        try {
          prepareRequest();
        } catch (Throwable t) {
          ExceptionUtils2.handleThrowable(t);
          log.debug(getSm().getString("ajpprocessor.request.prepare"), t);
          // 500 - Internal Server Error
          getResponse().setStatus(500);
          setErrorState(ErrorState.CLOSE_CLEAN, t);
          getAdapter().log(getRequest(), getResponse(), 0);
        }
      }

      if (!getErrorState().isError() && !cping && getEndpoint().isPaused()) {
        // 503 - Service unavailable
        getResponse().setStatus(503);
        setErrorState(ErrorState.CLOSE_CLEAN, null);
        getAdapter().log(getRequest(), getResponse(), 0);
      }
      cping = false;

      // Process the request in the adapter
      if (!getErrorState().isError()) {
        try {
          rp.setStage(Constants24.getStageService());
          getAdapter().service(getRequest(), getResponse());
        } catch (InterruptedIOException e) {
          setErrorState(ErrorState.CLOSE_NOW, e);
        } catch (Throwable t) {
          ExceptionUtils2.handleThrowable(t);
          log.error(getSm().getString("ajpprocessor.request.process"), t);
          // 500 - Internal Server Error
          getResponse().setStatus(500);
          setErrorState(ErrorState.CLOSE_CLEAN, t);
          getAdapter().log(getRequest(), getResponse(), 0);
        }
      }

      if (isAsync() && !getErrorState().isError()) {
        break;
      }

      // Finish the response if not done yet
      if (!isFinished() && getErrorState().isIoAllowed()) {
        try {
          finish();
        } catch (Throwable t) {
          ExceptionUtils2.handleThrowable(t);
          setErrorState(ErrorState.CLOSE_NOW, t);
        }
      }

      // If there was an error, make sure the request is counted as
      // and error, and update the statistics counter
      if (getErrorState().isError()) {
        getResponse().setStatus(500);
      }
      getRequest().updateCounters();

      rp.setStage(Constants24.getStageKeepalive());
      recycle(false);
    }

    rp.setStage(Constants24.getStageEnded());

    if (!getErrorState().isError() && !getEndpoint().isPaused()) {
      if (isAsync()) {
        return SocketState.LONG;
      } else {
        return SocketState.OPEN;
      }
    } else {
      return SocketState.CLOSED;
    }
  }