/// <summary>
        /// Builds the Merkle Tree recursivly from the list of Leaf nodes to the root node.
        /// </summary>
        /// <remarks>
        /// Merkle tree is built from lowest level to the highest (root) level.
        /// In each level nodes are paired and their parent node is constructed.
        /// If there is odd number of nodes, then last parent node is calculated using same node for both childs.
        /// </remarks>
        /// <param name="nodes">The list of nodes.</param>
        private void BuildTree(IList <MerkleNodeBase> nodes)
        {
            // if only one node, then we reached the root level
            if (nodes.Count == 1)
            {
                this.root = nodes[0];
                return;
            }

            // new list of next level nodes
            var nextLevelNodes = new List <MerkleNodeBase>();

            // the lenght of list where each node has a pair.
            var lenghtOfPairs = (nodes.Count / 2) * 2;

            // calculate next level nodes for each current level node pair
            for (var i = 0; i < lenghtOfPairs; i += 2)
            {
                var newNode = new MerkleNode(this.hashProvider, nodes[i], nodes[i + 1]);
                nextLevelNodes.Add(newNode);
            }

            // if there is one node left without pair (odd number of nodes), then use same node for both childs
            if (nodes.Count > lenghtOfPairs)
            {
                var newNode = new MerkleNode(this.hashProvider, nodes[nodes.Count - 1], nodes[nodes.Count - 1]);
                nextLevelNodes.Add(newNode);
            }

            this.BuildTree(nextLevelNodes);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="MerkleNode"/> class.
 /// </summary>
 /// <param name="hashProvider">The hash provider.</param>
 /// <param name="left">The left child node.</param>
 /// <param name="right">The right child node.</param>
 internal MerkleNode(IHashProvider hashProvider, MerkleNodeBase left, MerkleNodeBase right)
 {
     this.right    = right;
     this.left     = left;
     this.nodeHash = hashProvider.ComputeHash(left.Hash.GetHashBytes().Concat(right.Hash.GetHashBytes()).ToArray());
 }