docs: private void processAJPHeader() {
          int oldState = this.state;
          if (anyAreSet(oldState, FLAG_START)) {
  
              PooledByteBuffer[] byteBuffers = null;
  
              //merge the cookies into the header map
              Connectors.flattenCookies(exchange);
  
              PooledByteBuffer pooled = pool.allocate();
              ByteBuffer buffer = pooled.getBuffer();
              buffer.put((byte) 'A');
              buffer.put((byte) 'B');
              buffer.put((byte) 0); //we fill the size in later
              buffer.put((byte) 0);
              buffer.put((byte) 4);
              putInt(buffer, exchange.getStatusCode());
              String reason = exchange.getReasonPhrase();
              if(reason == null) {
                  reason = StatusCodes.getReason(exchange.getStatusCode());
              }
              if(reason.length() + 4 > buffer.remaining()) {
                  pooled.close();
                  throw UndertowMessages.MESSAGES.reasonPhraseToLargeForBuffer(reason);
              }
              putString(buffer, reason);
  
              int headers = 0;
              //we need to count the headers
              final HeaderMap responseHeaders = exchange.getResponseHeaders();
              for (HttpString name : responseHeaders.getHeaderNames()) {
                  headers += responseHeaders.get(name).size();
              }
  
              putInt(buffer, headers);
  
  
              for (final HttpString header : responseHeaders.getHeaderNames()) {
                  for (String headerValue : responseHeaders.get(header)) {
                      if(buffer.remaining() < header.length() + headerValue.length() + 6) {
                          //if there is not enough room in the buffer we need to allocate more
                          buffer.flip();
                          if(byteBuffers == null) {
                              byteBuffers = new PooledByteBuffer[2];
                              byteBuffers[0] = pooled;
                          } else {
                              PooledByteBuffer[] old = byteBuffers;
                              byteBuffers = new PooledByteBuffer[old.length + 1];
                              System.arraycopy(old, 0, byteBuffers, 0, old.length);
                          }
                          pooled = pool.allocate();
                          byteBuffers[byteBuffers.length - 1] = pooled;
                          buffer = pooled.getBuffer();
                      }
  
                      Integer headerCode = HEADER_MAP.get(header);
                      if (headerCode != null) {
                          putInt(buffer, headerCode);
                      } else {
                          putHttpString(buffer, header);
                      }
                      putString(buffer, headerValue);
                  }
              }
              if(byteBuffers == null) {
                  int dataLength = buffer.position() - 4;
                  buffer.put(2, (byte) ((dataLength >> 8) & 0xFF));
                  buffer.put(3, (byte) (dataLength & 0xFF));
                  buffer.flip();
                  queueFrame(new PooledBufferFrameCallback(pooled), buffer);
              } else {
                  ByteBuffer[] bufs = new ByteBuffer[byteBuffers.length];
                  for(int i = 0; i < bufs.length; ++i) {
                      bufs[i] = byteBuffers[i].getBuffer();
                  }
                  int dataLength = (int) (Buffers.remaining(bufs) - 4);
                  bufs[0].put(2, (byte) ((dataLength >> 8) & 0xFF));
                  bufs[0].put(3, (byte) (dataLength & 0xFF));
                  buffer.flip();
                  queueFrame(new PooledBuffersFrameCallback(byteBuffers), bufs);
              }
              state &= ~FLAG_START;
          }
      }