class IndexUtils {

    @NotNull
    public MerkleTree buildMerkleTree(@NotNull Partition partition) {
        List<IndexElt> elts = indexService.getListByPartition(partition);

        SortedMap<Long, Block> blocks = elts.stream()
                .collect(groupingBy(IndexElt::getId))
                .values()
                .stream()
                .map(groupedElts -> new Block(groupedElts.get(0).getId(), groupedElts.stream()
                        .map(IndexElt::toBlockElt)
                        .sorted(new BlockEltComparator())
                        .collect(ImmutableList.toImmutableList()))
                ).collect(
                        // TODO: replace with ImmutableSortedMap
                        toMap(
                                Block::getId,
                                Function.identity(),
                                Utils.throwingMerger(),
                                TreeMap::new
                        )
                );

        MerkleTree tree = new MerkleTree(indexService.getMinMaxRange(partition), MAX_LEVEL);
        MerkleTree.fillTree(tree, blocks);
        tree.calculate();

        return tree;
    }

}