docs: public static boolean encode(ByteBuffer buffer, String toEncode, boolean forceLowercase) {
          if (buffer.remaining() <= toEncode.length()) {
              return false;
          }
          int start = buffer.position();
          //this sucks, but we need to put the length first
          //and we don't really have any option but to calculate it in advance to make sure we have left enough room
          //so we end up iterating twice
          int length = 0;
          for (int i = 0; i < toEncode.length(); ++i) {
              byte c = (byte) toEncode.charAt(i);
              if(forceLowercase) {
                  c = Hpack.toLower(c);
              }
              HuffmanCode code = HUFFMAN_CODES[c];
              length += code.length;
          }
          int byteLength = length / 8 + (length % 8 == 0 ? 0 : 1);
  
          buffer.put((byte) (1 << 7));
          Hpack.encodeInteger(buffer, byteLength, 7);
  
  
          int bytePos = 0;
          byte currentBufferByte = 0;
          for (int i = 0; i < toEncode.length(); ++i) {
              byte c = (byte) toEncode.charAt(i);
              if(forceLowercase) {
                  c = Hpack.toLower(c);
              }
              HuffmanCode code = HUFFMAN_CODES[c];
              if (code.length + bytePos <= 8) {
                  //it fits in the current byte
                  currentBufferByte |= ((code.value & 0xFF) << 8 - (code.length + bytePos));
                  bytePos += code.length;
              } else {
                  //it does not fit, it may need up to 4 bytes
                  int val = code.value;
                  int rem = code.length;
                  while (rem > 0) {
                      if (!buffer.hasRemaining()) {
                          buffer.position(start);
                          return false;
                      }
                      int remainingInByte = 8 - bytePos;
                      if (rem > remainingInByte) {
                          currentBufferByte |= (val >> (rem - remainingInByte));
                      } else {
                          currentBufferByte |= (val << (remainingInByte - rem));
                      }
                      if (rem > remainingInByte) {
                          buffer.put(currentBufferByte);
                          currentBufferByte = 0;
                          bytePos = 0;
                      } else {
                          bytePos = rem;
                      }
                      rem -= remainingInByte;
                  }
              }
              if (bytePos == 8) {
                  if (!buffer.hasRemaining()) {
                      buffer.position(start);
                      return false;
                  }
                  buffer.put(currentBufferByte);
                  currentBufferByte = 0;
                  bytePos = 0;
              }
              if (buffer.position() - start > toEncode.length()) {
                  //the encoded version is longer than the original
                  //just return false
                  buffer.position(start);
                  return false;
              }
          }
          if (bytePos > 0) {
              //add the EOS bytes if we have not finished on a single byte
              if (!buffer.hasRemaining()) {
                  buffer.position(start);
                  return false;
              }
              buffer.put((byte) (currentBufferByte | ((0xFF) >> bytePos)));
          }
          return true;
      }