private static ImmutableHashTree <TKey, TValue> RotateRight(ImmutableHashTree <TKey, TValue> node)
 {
     return(new ImmutableHashTree <TKey, TValue>(
                node.Left.Key,
                node.Left.Value,
                node.Left.Left,
                new ImmutableHashTree <TKey, TValue>(node.Key, node.Value, node.Left.Right, node.Right)));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ImmutableHashTree{TKey,TValue}"/> class
 /// and adds a new entry in the <see cref="Duplicates"/> list.
 /// </summary>
 /// <param name="key">The key for this node.</param>
 /// <param name="value">The value for this node.</param>
 /// <param name="hashTree">The <see cref="ImmutableHashTree{TKey,TValue}"/> that contains existing duplicates.</param>
 public ImmutableHashTree(TKey key, TValue value, ImmutableHashTree <TKey, TValue> hashTree)
 {
     Duplicates = hashTree.Duplicates.Add(new KeyValue <TKey, TValue>(key, value));
     Key        = hashTree.Key;
     Value      = hashTree.Value;
     Height     = hashTree.Height;
     HashCode   = hashTree.HashCode;
     Left       = hashTree.Left;
     Right      = hashTree.Right;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ImmutableHashTree{TKey,TValue}"/> class.
        /// </summary>
        /// <param name="key">The key for this node.</param>
        /// <param name="value">The value for this node.</param>
        /// <param name="left">The left node.</param>
        /// <param name="right">The right node.</param>
        public ImmutableHashTree(TKey key, TValue value, ImmutableHashTree <TKey, TValue> left, ImmutableHashTree <TKey, TValue> right)
        {
            var balance = left.Height - right.Height;

            if (balance == -2)
            {
                if (right.IsLeftHeavy())
                {
                    right = RotateRight(right);
                }

                // Rotate left
                Key   = right.Key;
                Value = right.Value;
                Left  = new ImmutableHashTree <TKey, TValue>(key, value, left, right.Left);
                Right = right.Right;
            }
            else if (balance == 2)
            {
                if (left.IsRightHeavy())
                {
                    left = RotateLeft(left);
                }

                // Rotate right
                Key   = left.Key;
                Value = left.Value;
                Right = new ImmutableHashTree <TKey, TValue>(key, value, left.Right, right);
                Left  = left.Left;
            }
            else
            {
                Key   = key;
                Value = value;
                Left  = left;
                Right = right;
            }

            Height = 1 + Math.Max(Left.Height, Right.Height);

            Duplicates = ImmutableList <KeyValue <TKey, TValue> > .Empty;

            HashCode = Key.GetHashCode();
        }