code: public String create(List<String> sortedIncludedHeaders, HashFunction hashFunction) {
          // Add the method and uri
          StringBuilder canonicalRequest = new StringBuilder();
          canonicalRequest.append(method).append(NEW_LINE);
          String canonicalUri = CANONICALIZE_PATH.apply(uri);
          canonicalRequest.append(canonicalUri).append(NEW_LINE);
  
          // Get the query args, replace whitespace and values that should be not encoded, sort and rejoin
          String canonicalQuery = CANONICALIZE_QUERY.apply(queryString);
          canonicalRequest.append(canonicalQuery).append(NEW_LINE);
  
          // Normalize all the headers
          Header[] normalizedHeaders = NORMALIZE_HEADERS.apply(headers);
          Map<String, List<String>> combinedHeaders = COMBINE_HEADERS.apply(normalizedHeaders);
  
          // Add the headers that we care about
          for (String header : sortedIncludedHeaders) {
              String lowercase = header.toLowerCase().trim();
  
              if (combinedHeaders.containsKey(lowercase)) {
                  List<String> values = combinedHeaders.get(lowercase);
                  Collections.sort(values);
  
                  canonicalRequest.append(lowercase)
                           .append(":")
                           .append(Joiner.on(',').join(values))
                           .append(NEW_LINE);
              }
          }
          canonicalRequest.append(NEW_LINE);
  
          // Mark the headers that we care about
          canonicalRequest.append(Joiner.on(";").join(sortedIncludedHeaders)).append(NEW_LINE);
  
          // Hash and hex the request payload
          if (!Strings.isNullOrEmpty(requestBody)) {
              String hashedPayload = hashFunction.hashString(requestBody, Charsets.UTF_8).toString();
              canonicalRequest.append(hashedPayload);
          }
          return canonicalRequest.toString();
      }
docs: Creates a canonical request string out of HTTP request components.
  
  @param sortedIncludedHeaders the headers that should be included into canonical request string
  @param hashFunction          the hashing function applied to request payload
  @return a string representing the canonical request