code: static List<String> queryStringToNamesAndValues(String encodedQuery) {
          List<String> result = new ArrayList<>();
          for (int pos = 0; pos <= encodedQuery.length(); ) {
              int ampersandOffset = encodedQuery.indexOf('&', pos);
              if (ampersandOffset == -1) ampersandOffset = encodedQuery.length();
  
              int equalsOffset = encodedQuery.indexOf('=', pos);
              if (equalsOffset == -1 || equalsOffset > ampersandOffset) {
                  result.add(encodedQuery.substring(pos, ampersandOffset));
                  result.add(null); // No value for this name.
              } else {
                  result.add(encodedQuery.substring(pos, equalsOffset));
                  result.add(encodedQuery.substring(equalsOffset + 1, ampersandOffset));
              }
              pos = ampersandOffset + 1;
          }
          return result;
      }
docs: Cuts {@code encodedQuery} up into alternating parameter names and values. This divides a query
  string like {@code subject=math&easy&problem=5-2=3} into the list {@code ["subject", "math",
  "easy", null, "problem", "5-2=3"]}. Note that values may be null and may contain '='
  characters.