class UriUtils {

    public static URI extendUri(URI uri, String path) {
        String query = null;
        if (path != null) {
            final int indexOfFirstQueryChar = path.indexOf(URI_QUERY_CHAR_CONST);
            if (indexOfFirstQueryChar >= 0) {
                if (indexOfFirstQueryChar < path.length() - 1) {
                    query = path.substring(indexOfFirstQueryChar + 1);
                }
                path = path.substring(0, indexOfFirstQueryChar);
            }
        }
        return buildUri(uri.getScheme(), uri.getHost(), uri.getPort(),
                buildUriPath(uri.getPath(), path), query);
    }

}

class TestUriUtils {

    @Test
    public void extendUri() throws URISyntaxException {

        String basePath = UriUtils.buildUriPath("some", UUID.randomUUID().toString());
        URI baseUri = new URI("http://localhost:8000");
        URI baseHttpsUri = new URI("https://localhost:8000");
        URI httpBase = UriUtils.buildUri(baseUri, basePath);
        URI httpsBase = UriUtils.buildUri(baseHttpsUri, basePath);

        String path = UUID.randomUUID().toString();
        URI u = UriUtils.extendUri(httpBase, path);
        assertEquals("http", u.getScheme());
        assertEquals(basePath + "/" + path, u.getPath());
        assertTrue(u.getQuery() == null);

        u = UriUtils.extendUri(httpsBase, path);
        assertEquals("https", u.getScheme());
        assertEquals(basePath + "/" + path, u.getPath());
        assertTrue(u.getQuery() == null);
        assertEquals(8000, u.getPort());

        String query = "key=value&key2=value2";
        String pathWithQuery = path + "?" + query;
        u = UriUtils.extendUri(httpBase, pathWithQuery);
        assertEquals(basePath + "/" + path, u.getPath());
        assertEquals(query, u.getQuery());

        String queryContainingQueryChar = "key=value&url=/url/with?query=true";
        String pathWithQueryChars = path + "?" + queryContainingQueryChar;
        u = UriUtils.extendUri(httpBase, pathWithQueryChars);
        assertEquals(basePath + "/" + path, u.getPath());
        assertEquals(queryContainingQueryChar, u.getQuery());

        String pathEndingWithQueryChar = path + "?";
        u = UriUtils.extendUri(httpBase, pathEndingWithQueryChar);
        assertEquals(basePath + "/" + path, u.getPath());
        assertEquals(null, u.getQuery());

        String queryContainingOnlyQueryChars = "??";
        String pathEndingWithQueryChars = path + "?" + queryContainingOnlyQueryChars;
        u = UriUtils.extendUri(httpBase, pathEndingWithQueryChars);
        assertEquals(basePath + "/" + path, u.getPath());
        assertEquals(queryContainingOnlyQueryChars, u.getQuery());

        u = UriUtils.extendUri(httpBase, "/bar/./../foo");
        assertEquals(httpBase.getPath() + "/foo", u.getPath());

        u = UriUtils.extendUri(httpBase, "/bar/./foo");
        assertEquals(httpBase.getPath() + "/bar/foo", u.getPath());
    }

}