### Question:
QueryStringDecoder { public static String decodeComponent(final String s) { return decodeComponent(s, HttpConstants.DEFAULT_CHARSET); } QueryStringDecoder(String uri);  QueryStringDecoder(String uri, boolean hasPath);  QueryStringDecoder(String uri, Charset charset);  QueryStringDecoder(String uri, Charset charset, boolean hasPath);  QueryStringDecoder(String uri, Charset charset, boolean hasPath, int maxParams);  QueryStringDecoder(URI uri);  QueryStringDecoder(URI uri, Charset charset);  QueryStringDecoder(URI uri, Charset charset, int maxParams); @Override String toString(); String uri(); String path(); Map<String, List<String>> parameters(); static String decodeComponent(final String s); static String decodeComponent(final String s, final Charset charset);  }### Answer:
@Test public void testUrlDecoding() throws Exception { final String caffe = new String( new byte[] {'C', 'a', 'f', 'f', (byte) 0xC3, (byte) 0xA9}, "UTF-8"); final String[] tests = { "", "", "foo", "foo", "f+o", "f o", "f++", "f ", "fo%", "unterminated escape sequence at index 2 of: fo%", "%42", "B", "%5f", "_", "f%4", "unterminated escape sequence at index 1 of: f%4", "%x2", "invalid hex byte 'x2' at index 1 of '%x2'", "%4x", "invalid hex byte '4x' at index 1 of '%4x'", "Caff%C3%A9", caffe, "случайный праздник", "случайный праздник", "случайный%20праздник", "случайный праздник", "случайный%20праздник%20%E2%98%BA", "случайный праздник ☺", }; for (int i = 0; i < tests.length; i += 2) { final String encoded = tests[i]; final String expected = tests[i + 1]; try { final String decoded = QueryStringDecoder.decodeComponent(encoded); Assert.assertEquals(expected, decoded); } catch (IllegalArgumentException e) { Assert.assertEquals(expected, e.getMessage()); } } }