docs: private int processStatefulWrite(int state, final Object userData, int pos, int len) throws IOException {
          ByteBuffer buffer = pooledBuffer.getBuffer();
          long fiCookie = this.fiCookie;
          int valueIdx = this.valueIdx;
          int charIndex = this.charIndex;
          int length;
          String string = this.string;
          HeaderValues headerValues = this.headerValues;
          int res;
          // BUFFER IS FLIPPED COMING IN
          if (buffer.hasRemaining()) {
              do {
                  res = next.write(buffer);
                  if (res == 0) {
                      return state;
                  }
              } while (buffer.hasRemaining());
          }
          buffer.clear();
          HeaderMap headers = exchange.getResponseHeaders();
          // BUFFER IS NOW EMPTY FOR FILLING
          for (; ; ) {
              switch (state) {
                  case STATE_HDR_NAME: {
                      final HttpString headerName = headerValues.getHeaderName();
                      length = headerName.length();
                      while (charIndex < length) {
                          if (buffer.hasRemaining()) {
                              buffer.put(headerName.byteAt(charIndex++));
                          } else {
                              buffer.flip();
                              do {
                                  res = next.write(buffer);
                                  if (res == 0) {
                                      this.string = string;
                                      this.headerValues = headerValues;
                                      this.charIndex = charIndex;
                                      this.fiCookie = fiCookie;
                                      this.valueIdx = valueIdx;
                                      return STATE_HDR_NAME;
                                  }
                              } while (buffer.hasRemaining());
                              buffer.clear();
                          }
                      }
                      // fall thru
                  }
                  case STATE_HDR_D: {
                      if (!buffer.hasRemaining()) {
                          buffer.flip();
                          do {
                              res = next.write(buffer);
                              if (res == 0) {
                                  this.string = string;
                                  this.headerValues = headerValues;
                                  this.charIndex = charIndex;
                                  this.fiCookie = fiCookie;
                                  this.valueIdx = valueIdx;
                                  return STATE_HDR_D;
                              }
                          } while (buffer.hasRemaining());
                          buffer.clear();
                      }
                      buffer.put((byte) ':');
                      // fall thru
                  }
                  case STATE_HDR_DS: {
                      if (!buffer.hasRemaining()) {
                          buffer.flip();
                          do {
                              res = next.write(buffer);
                              if (res == 0) {
                                  this.string = string;
                                  this.headerValues = headerValues;
                                  this.charIndex = charIndex;
                                  this.fiCookie = fiCookie;
                                  this.valueIdx = valueIdx;
                                  return STATE_HDR_DS;
                              }
                          } while (buffer.hasRemaining());
                          buffer.clear();
                      }
                      buffer.put((byte) ' ');
                      //if (valueIterator == null) {
                      //    valueIterator = exchange.getResponseHeaders().get(headerName).iterator();
                      //}
                      string = headerValues.get(valueIdx++);
                      charIndex = 0;
                      // fall thru
                  }
                  case STATE_HDR_VAL: {
                      length = string.length();
                      while (charIndex < length) {
                          if (buffer.hasRemaining()) {
                              buffer.put((byte) string.charAt(charIndex++));
                          } else {
                              buffer.flip();
                              do {
                                  res = next.write(buffer);
                                  if (res == 0) {
                                      this.string = string;
                                      this.headerValues = headerValues;
                                      this.charIndex = charIndex;
                                      this.fiCookie = fiCookie;
                                      this.valueIdx = valueIdx;
                                      return STATE_HDR_VAL;
                                  }
                              } while (buffer.hasRemaining());
                              buffer.clear();
                          }
                      }
                      charIndex = 0;
                      if (valueIdx == headerValues.size()) {
                          if (!buffer.hasRemaining()) {
                              if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
                                  return STATE_HDR_EOL_CR;
                          }
                          buffer.put((byte) 13); // CR
                          if (!buffer.hasRemaining()) {
                              if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
                                  return STATE_HDR_EOL_LF;
                          }
                          buffer.put((byte) 10); // LF
                          if ((fiCookie = headers.fiNextNonEmpty(fiCookie)) != -1L) {
                              headerValues = headers.fiCurrent(fiCookie);
                              valueIdx = 0;
                              state = STATE_HDR_NAME;
                              break;
                          } else {
                              if (!buffer.hasRemaining()) {
                                  if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
                                      return STATE_HDR_FINAL_CR;
                              }
                              buffer.put((byte) 13); // CR
                              if (!buffer.hasRemaining()) {
                                  if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
                                      return STATE_HDR_FINAL_LF;
                              }
                              buffer.put((byte) 10); // LF
                              this.fiCookie = -1;
                              this.valueIdx = 0;
                              this.string = null;
                              buffer.flip();
                              //for performance reasons we use a gather write if there is user data
                              if (userData == null) {
                                  do {
                                      res = next.write(buffer);
                                      if (res == 0) {
                                          return STATE_BUF_FLUSH;
                                      }
                                  } while (buffer.hasRemaining());
                              } else if(userData instanceof ByteBuffer) {
                                  ByteBuffer[] b = {buffer, (ByteBuffer) userData};
                                  do {
                                      long r = next.write(b, 0, b.length);
                                      if (r == 0 && buffer.hasRemaining()) {
                                          return STATE_BUF_FLUSH;
                                      }
                                  } while (buffer.hasRemaining());
                              } else {
                                  ByteBuffer[] b = new ByteBuffer[1 + len];
                                  b[0] = buffer;
                                  System.arraycopy(userData, pos, b, 1, len);
                                  do {
                                      long r = next.write(b, 0, b.length);
                                      if (r == 0 && buffer.hasRemaining()) {
                                          return STATE_BUF_FLUSH;
                                      }
                                  } while (buffer.hasRemaining());
                              }
                              bufferDone();
                              return STATE_BODY;
                          }
                          // not reached
                      }
                      // fall thru
                  }
                  // Clean-up states
                  case STATE_HDR_EOL_CR: {
                      if (!buffer.hasRemaining()) {
                          if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
                              return STATE_HDR_EOL_CR;
                      }
                      buffer.put((byte) 13); // CR
                  }
                  case STATE_HDR_EOL_LF: {
                      if (!buffer.hasRemaining()) {
                          if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
                              return STATE_HDR_EOL_LF;
                      }
                      buffer.put((byte) 10); // LF
                      if (valueIdx < headerValues.size()) {
                          state = STATE_HDR_NAME;
                          break;
                      } else if ((fiCookie = headers.fiNextNonEmpty(fiCookie)) != -1L) {
                          headerValues = headers.fiCurrent(fiCookie);
                          valueIdx = 0;
                          state = STATE_HDR_NAME;
                          break;
                      }
                      // fall thru
                  }
                  case STATE_HDR_FINAL_CR: {
                      if (!buffer.hasRemaining()) {
                          if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
                              return STATE_HDR_FINAL_CR;
                      }
                      buffer.put((byte) 13); // CR
                      // fall thru
                  }
                  case STATE_HDR_FINAL_LF: {
                      if (!buffer.hasRemaining()) {
                          if (flushHeaderBuffer(buffer, string, headerValues, charIndex, fiCookie, valueIdx))
                              return STATE_HDR_FINAL_LF;
                      }
                      buffer.put((byte) 10); // LF
                      this.fiCookie = -1L;
                      this.valueIdx = 0;
                      this.string = null;
                      buffer.flip();
                      //for performance reasons we use a gather write if there is user data
                      if (userData == null) {
                          do {
                              res = next.write(buffer);
                              if (res == 0) {
                                  return STATE_BUF_FLUSH;
                              }
                          } while (buffer.hasRemaining());
                      } else if(userData instanceof ByteBuffer) {
                          ByteBuffer[] b = {buffer, (ByteBuffer) userData};
                          do {
                              long r = next.write(b, 0, b.length);
                              if (r == 0 && buffer.hasRemaining()) {
                                  return STATE_BUF_FLUSH;
                              }
                          } while (buffer.hasRemaining());
                      } else {
                          ByteBuffer[] b = new ByteBuffer[1 + len];
                          b[0] = buffer;
                          System.arraycopy(userData, pos, b, 1, len);
                          do {
                              long r = next.write(b, 0, b.length);
                              if (r == 0 && buffer.hasRemaining()) {
                                  return STATE_BUF_FLUSH;
                              }
                          } while (buffer.hasRemaining());
                      }
                      // fall thru
                  }
                  case STATE_BUF_FLUSH: {
                      // buffer was successfully flushed above
                      bufferDone();
                      return STATE_BODY;
                  }
                  default: {
                      throw new IllegalStateException();
                  }
              }
          }
      }