code:     public SocketState process(SocketWrapper<Long> socket)
          throws IOException {
          RequestInfo rp = request.getRequestProcessor();
          rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
  
          // Setting up the socket
          this.socket = socket;
          long socketRef = socket.getSocket().longValue();
          Socket.setrbb(socketRef, inputBuffer);
          Socket.setsbb(socketRef, outputBuffer);
  
          // Error flag
          error = false;
  
          boolean keptAlive = false;
  
          while (!error && !endpoint.isPaused()) {
  
              // Parsing the request header
              try {
                  // Get first message of the request
                  if (!readMessage(requestHeaderMessage, 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 = requestHeaderMessage.getByte();
                  if (type == Constants.JK_AJP13_CPING_REQUEST) {
                      if (Socket.send(socketRef, pongMessageArray, 0,
                              pongMessageArray.length) < 0) {
                          error = true;
                      }
                      continue;
                  } else if(type != Constants.JK_AJP13_FORWARD_REQUEST) {
                      // Usually the servlet didn't read the previous request body
                      if(log.isDebugEnabled()) {
                          log.debug("Unexpected message: "+type);
                      }
                      continue;
                  }
  
                  keptAlive = true;
                  request.setStartTime(System.currentTimeMillis());
              } catch (IOException e) {
                  error = true;
                  break;
              } catch (Throwable t) {
                  ExceptionUtils.handleThrowable(t);
                  log.debug(sm.getString("ajpprocessor.header.error"), t);
                  // 400 - Bad Request
                  response.setStatus(400);
                  adapter.log(request, response, 0);
                  error = true;
              }
  
              if (!error) {
                  // Setting up filters, and parse some request headers
                  rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
                  try {
                      prepareRequest();
                  } catch (Throwable t) {
                      ExceptionUtils.handleThrowable(t);
                      log.debug(sm.getString("ajpprocessor.request.prepare"), t);
                      // 400 - Internal Server Error
                      response.setStatus(400);
                      adapter.log(request, response, 0);
                      error = true;
                  }
              }
  
              // Process the request in the adapter
              if (!error) {
                  try {
                      rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
                      adapter.service(request, response);
                  } catch (InterruptedIOException e) {
                      error = true;
                  } catch (Throwable t) {
                      ExceptionUtils.handleThrowable(t);
                      log.error(sm.getString("ajpprocessor.request.process"), t);
                      // 500 - Internal Server Error
                      response.setStatus(500);
                      adapter.log(request, response, 0);
                      error = true;
                  }
              }
  
              if (isAsync() && !error) {
                  break;
              }
  
              // Finish the response if not done yet
              if (!finished) {
                  try {
                      finish();
                  } catch (Throwable t) {
                      ExceptionUtils.handleThrowable(t);
                      error = true;
                  }
              }
  
              // If there was an error, make sure the request is counted as
              // and error, and update the statistics counter
              if (error) {
                  response.setStatus(500);
              }
              request.updateCounters();
  
              rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
              recycle(false);
          }
  
          rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
          
          if (error || endpoint.isPaused()) {
              return SocketState.CLOSED;
          } else if (isAsync()) {
              return SocketState.LONG;
          } else {
              return SocketState.OPEN;
          }
      }
  
  
      // ----------------------------------------------------- ActionHook Methods
  
  
      /**
       * Send an action to the connector.
       *
       * @param actionCode Type of the action
       * @param param Action parameter
       */
      @Override
  