code: private synchronized Map<String, String[]> parseParameters(String s)
      {
          Map<String, List<String>> parameterMap;
          Map<String, String[]> result;
          StringTokenizer st;
  
          parameterMap = new HashMap<>();
          result = new HashMap<>();
  
          if (s == null)
          {
              return result;
          }
  
          st = new StringTokenizer(s, "&");
          while (st.hasMoreTokens())
          {
              String parameter;
              Matcher parameterMatcher;
              String name;
              String value;
              List<String> values;
  
              parameter = st.nextToken();
              parameterMatcher = PARAMETER_PATTERN.matcher(parameter);
              if (parameterMatcher.matches())
              {
                  try
                  {
                      name = URLDecoder.decode(parameterMatcher.group(1), "UTF-8");
                      value = URLDecoder.decode(parameterMatcher.group(2), "UTF-8");
                  }
                  catch (UnsupportedEncodingException e)
                  {
                      logger.error("Unable to decode parameter '" + parameter + "'", e);
                      continue;
                  }
              }
              else
              {
                  try
                  {
                      name = URLDecoder.decode(parameter, "UTF-8");
                      value = "";
                  }
                  catch (UnsupportedEncodingException e)
                  {
                      logger.error("Unable to decode parameter '" + parameter + "'", e);
                      continue;
                  }
              }
  
              if (parameterMap.get(name) == null)
              {
                  values = new ArrayList<>();
                  values.add(value);
                  parameterMap.put(name, values);
              }
              else
              {
                  values = parameterMap.get(name);
                  values.add(value);
              }
          }
  
          for (Map.Entry<String, List<String>> entry : parameterMap.entrySet())
          {
              String[] valueArray;
  
              valueArray = new String[entry.getValue().size()];
              result.put(entry.getKey(), entry.getValue().toArray(valueArray));
          }
  
          return result;
      }
docs: Parses the given parameter string and caches the result.
  
  @param s the parameter string to parse
  @return a Map made up of parameter names their values