public static Map<String, String> uriToMap(String uri) {
        if (StringUtils.isBlank(uri)) {
            return null;
        }
        try {
            // LinkedHashMap is our impl choice, because order of params is awesome sometimes
            Map<String, String> params = new LinkedHashMap<String, String>();
            String query = "";

            // remove '/?' from uri if need
            if (uri.contains("?")) {
                String[] urlParts = uri.split("\\?");
                if (urlParts.length > 1) {
                    query = urlParts[1].trim();
                }
            } else {
                query = uri;
            }

            // split string to key value pair and put to map
            for (String param : query.split("&")) {
                String[] pair = param.split("=");

                String key;
                try {
                    key = URLDecoder.decode(pair[0], "UTF-8");
                } catch (IllegalArgumentException e) {
                    key = pair[0];
                }

                String value = "";
                if (pair.length > 1) {
                    try {
                        value = URLDecoder.decode(pair[1], "UTF-8");
                    } catch (IllegalArgumentException e) {
                        key = pair[1];
                    }
                }
                boolean isValueExist = params.get(key) != null;
                if (!isValueExist) {
                    params.put(key, value);
                }
            }
            return params;
        } catch (UnsupportedEncodingException e) {
            throw new AssertionError(e);
        }
    }