code: private String normalizeParameters(MultiValueMap<String, String> collectedParameters) {
  		// Normalizes the collected parameters for baseString calculation, per https://tools.ietf.org/html/rfc5849#section-3.4.1.3.2
  		MultiValueMap<String, String> sortedEncodedParameters = new TreeMultiValueMap<String, String>();
  		for (Iterator<Entry<String, List<String>>> entryIt = collectedParameters.entrySet().iterator(); entryIt.hasNext();) {
  			Entry<String, List<String>> entry = entryIt.next();
  			String collectedName = entry.getKey();
  			List<String> collectedValues = entry.getValue();	
  			List<String> encodedValues = new ArrayList<String>(collectedValues.size());
  			sortedEncodedParameters.put(oauthEncode(collectedName), encodedValues);
  			for (Iterator<String> valueIt = collectedValues.iterator(); valueIt.hasNext();) {
  				String value = valueIt.next();
  				encodedValues.add(value != null ? oauthEncode(value) : "");
  			}
  			Collections.sort(encodedValues);
  		}
  		StringBuilder paramsBuilder = new StringBuilder();
  		for (Iterator<Entry<String, List<String>>> entryIt = sortedEncodedParameters.entrySet().iterator(); entryIt.hasNext();) {
  			Entry<String, List<String>> entry = entryIt.next();
  			String name = entry.getKey();
  			List<String> values = entry.getValue();
  			for (Iterator<String> valueIt = values.iterator(); valueIt.hasNext();) {
  				String value = valueIt.next();
  				paramsBuilder.append(name).append('=').append(value);
  				if (valueIt.hasNext()) {
  					paramsBuilder.append("&");
  				}
  			}
  			if (entryIt.hasNext()) {
  				paramsBuilder.append("&");
  			}
  		}
  		return paramsBuilder.toString();
  	}
docs: internal helpers