code: public static void decodeUtf8To(InputStream in, MultiMap<String> map, int maxLength, int maxKeys)
              throws IOException {
          synchronized (map) {
              Utf8StringBuilder buffer = new Utf8StringBuilder();
              String key = null;
              String value = null;
  
              int b;
  
              int totalLength = 0;
              while ((b = in.read()) >= 0) {
                  switch ((char) b) {
                      case '&':
                          value = buffer.toReplacedString();
                          buffer.reset();
                          if (key != null) {
                              map.add(key, value);
                          } else if (value != null && value.length() > 0) {
                              map.add(value, "");
                          }
                          key = null;
                          value = null;
                          if (maxKeys > 0 && map.size() > maxKeys)
                              throw new IllegalStateException(String.format("Form with too many keys [%d > %d]", map.size(), maxKeys));
                          break;
  
                      case '=':
                          if (key != null) {
                              buffer.append((byte) b);
                              break;
                          }
                          key = buffer.toReplacedString();
                          buffer.reset();
                          break;
  
                      case '+':
                          buffer.append((byte) ' ');
                          break;
  
                      case '%':
                          char code0 = (char) in.read();
                          char code1 = (char) in.read();
                          buffer.append(decodeHexByte(code0, code1));
                          break;
  
                      default:
                          buffer.append((byte) b);
                          break;
                  }
                  if (maxLength >= 0 && (++totalLength > maxLength))
                      throw new IllegalStateException("Form is too large");
              }
  
              if (key != null) {
                  value = buffer.toReplacedString();
                  buffer.reset();
                  map.add(key, value);
              } else if (buffer.length() > 0) {
                  map.add(buffer.toReplacedString(), "");
              }
          }
      }
docs: Decoded parameters to Map.
  
  @param in        InputSteam to read
  @param map       MultiMap to add parameters to
  @param maxLength maximum form length to decode
  @param maxKeys   the maximum number of keys to read or -1 for no limit
  @throws IOException if unable to decode input stream