class HttpUtil {

    public static String createUri(final URL baseUrl, final Map<String, String> queryStringKvp) {
        String query = baseUrl.getQuery();
        Map<String, String> finalKvpMap = new TreeMap<String, String>(queryStringKvp);
        if (query != null && query.length() > 0) {
            Map<String, String> userParams = new CaseInsensitiveMap(queryStringKvp);
            
            // there might be a "&amp;" at the end, make sure to remove it
            if (query.endsWith("&amp;")) {
            	query = query.substring(0, query.length() - 5);
            }
            
            String[] rawUrlKvpSet = query.split("&");
            for (String rawUrlKvp : rawUrlKvpSet) {
                int eqIdx = rawUrlKvp.indexOf('=');
                String key, value;
                if (eqIdx > 0) {
                    key = rawUrlKvp.substring(0, eqIdx);
                    value = rawUrlKvp.substring(eqIdx + 1);
                } else {
                    key = rawUrlKvp;
                    value = null;
                }
                try {
                    value = URLDecoder.decode(value, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
                if (userParams.containsKey(key)) {
                    LOGGER.fine("user supplied value for query string argument " + key
                            + " overrides the one in the base url");
                } else {
                    finalKvpMap.put(key, value);
                }
            }
        }

        String protocol = baseUrl.getProtocol();
        String host = baseUrl.getHost();
        int port = baseUrl.getPort();
        String path = baseUrl.getPath();

        StringBuilder sb = new StringBuilder();
        sb.append(protocol).append("://").append(host);
        if (port != -1 && port != baseUrl.getDefaultPort()) {
            sb.append(':');
            sb.append(port);
        }
        if (!"".equals(path) && !path.startsWith("/")) {
            sb.append('/');
        }
        sb.append(path).append('?');

        String key, value;
        try {
            Entry<String, String> kvp;
            for (Iterator<Map.Entry<String, String>> it = finalKvpMap.entrySet().iterator(); it
                    .hasNext();) {
                kvp = it.next();
                key = kvp.getKey();
                value = kvp.getValue();
                if (value == null) {
                    value = "";
                } else {
                    value = URLEncoder.encode(value, "UTF-8");
                }
                sb.append(key);
                sb.append('=');
                sb.append(value);
                if (it.hasNext()) {
                    sb.append('&');
                }
            }
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }

        final String finalUrlString = sb.toString();
        return finalUrlString;
    }

}