docs: public static String calculateTreeHash(List<byte[]> checksums) throws AmazonClientException {
  
          /*
           * The tree hash algorithm involves concatenating adjacent pairs of
           * individual checksums, then taking the checksum of the resulting bytes
           * and storing it, then recursing on this new list until there is only
           * one element. Any final odd-numbered parts at each step are carried
           * over to the next iteration as-is.
           */
          List<byte[]> hashes = new ArrayList<byte[]>();
          hashes.addAll(checksums);
          while ( hashes.size() > 1 ) {
              List<byte[]> treeHashes = new ArrayList<byte[]>();
              for ( int i = 0; i < hashes.size() / 2; i++ ) {
                  byte[] firstPart = hashes.get(2 * i);
                  byte[] secondPart = hashes.get(2 * i + 1);
                  byte[] concatenation = new byte[firstPart.length + secondPart.length];
                  System.arraycopy(firstPart, 0, concatenation, 0, firstPart.length);
                  System.arraycopy(secondPart, 0, concatenation, firstPart.length, secondPart.length);
                  try {
  					treeHashes.add(computeSHA256Hash(concatenation));
  				} catch (Exception e) {
  					throw new AmazonClientException("Unable to compute hash", e);
  				}
              }
              if ( hashes.size() % 2 == 1 ) {
                  treeHashes.add(hashes.get(hashes.size() - 1));
              }
              hashes = treeHashes;
          }
  
          return BinaryUtils.toHex(hashes.get(0));
      }