UriDecoder { protected static List<QueryOption> splitAndDecodeOptions(final String queryOptionString) throws UriParserSyntaxException { List<QueryOption> queryOptions = new ArrayList<>(); formEncoding = false; for (final String option : split(queryOptionString, '&')) { final int pos = option.indexOf('='); final String name = pos >= 0 ? option.substring(0, pos) : option; final String text = pos >= 0 ? option.substring(pos + 1) : ""; if(ACCEPT_FORM_ENCODING.equals(name)){ formEncoding = Boolean.parseBoolean(text); } queryOptions.add(new CustomQueryOptionImpl() .setName(decode(name).trim()) .setText(decode(text).trim())); } return queryOptions; }  static boolean isFormEncoding(); static String decode(final String encoded);  }
@Test public void options() throws Exception { checkOption("", "", ""); checkOption("a", "a", ""); checkOption("a=b", "a", "b"); checkOption("=", "", ""); checkOption("=b", "", "b"); checkOption("a&c", "a", ""); checkOption("a&c", "c", ""); checkOption("a=b&c", "a", "b"); checkOption("a=b&c", "c", ""); checkOption("a=b&c=d", "a", "b"); checkOption("a=b&c=d", "c", "d"); checkOption("=&=", "", ""); assertEquals(2, UriDecoder.splitAndDecodeOptions("=&=").size()); assertEquals(13, UriDecoder.splitAndDecodeOptions("&&&&&&&&&&&&").size()); checkOption("=&c=d", "", ""); checkOption("=&c=d", "c", "d"); checkOption("a%62c=d%65f", "abc", "def"); checkOption("a='%26%3D'", "a", "'&='"); }