class MerkleHashBuilder {

  private byte[] getRootHash(List<byte[]> hashes) {
    if (hashes.isEmpty()) {
      return new byte[32];
    }

    // build the merkle tree
    int numRemainingHashes = hashes.size();

    Hasher hasher = Hashes::sha3_256;
    while (numRemainingHashes > 1) {

      for (int i = 0; i < numRemainingHashes; i += 2) {
        if (i + 1 < numRemainingHashes) {
          hashes.add(i / 2, hasher.hash(hashes.get(i), hashes.get(i + 1)));
          continue;
        }

        // if there is an odd number of hashes, duplicate the last one
        hashes.add(i / 2, hasher.hash(hashes.get(i), hashes.get(i)));
        ++numRemainingHashes;
      }

      numRemainingHashes /= 2;
    }

    return hashes.get(0);
  }

  public  MerkleHashBuilder();

}