/// <summary>
        /// This method replaces the old node with the new node. If the parent is null, the new node will
        /// become the root. Else, if the old node is its parent's left child, its parent's left will become
        /// the new node; else, the parent's right will become the new node. If the new node isn't null, the
        /// new node's parent will become the old parent.
        /// </summary>
        private void Replace(ColoredTreeNode <K, V> oldNode, ColoredTreeNode <K, V> newNode)
        {
            // If the old node's parent is null, become the root.
            if (oldNode.Parent == null)
            {
                _root = newNode;
            }
            else
            {
                if (oldNode.Equals(oldNode.Parent.Left))
                {
                    oldNode.Parent.Left = newNode;
                }
                else
                {
                    oldNode.Parent.Right = newNode;
                }
            }

            // If the new node is not null, assign the new node's parent as the old node's parent:
            if (newNode != null)
            {
                newNode.Parent = oldNode.Parent;
            }
            oldNode = null;
        }
        /// <summary>
        /// This method returns the value at the specified key if the tree was able to remove it from the
        /// tree structure successfully; else, it returns null. After removal, the tree is restructured.
        /// </summary>
        public V TryRemove(K key)
        {
            // Find the node to be deleted:
            V result;
            ColoredTreeNode <K, V> current = _root;

            while (current != null)
            {
                if (current.Key.Equals(key))
                {
                    break;
                }
                else if (key.CompareTo(current.Key) < 0)
                {
                    current = current.Left;
                }
                else
                {
                    current = current.Right;
                }
            }
            result = current.Value;

            // If the node cannot be found, return null:
            if (current == null)
            {
                return(default(V));
            }

            // If current node is not a leaf, copy the key/value from the predecessor and then delete it instead.
            if (current.Left != null && current.Right != null)
            {
                ColoredTreeNode <K, V> predecessor = current.Left;
                while (predecessor.Right != null)
                {
                    predecessor = predecessor.Right;
                }
                current.Key   = predecessor.Key;
                current.Value = predecessor.Value;
                current       = predecessor;
            }

            // Get the node to be checked for restructuring:
            ColoredTreeNode <K, V> child = (current.Right == null) ? current.Left : current.Right;

            if (ConfirmColor(current) == NodeColor.Black)
            {
                current.Color = ConfirmColor(child);
                RestructureAfterDeletion(current);
            }

            // Replace the node (deleting the old node):
            Replace(current, child);
            if (ConfirmColor(_root) == NodeColor.Red)
            {
                _root.Color = NodeColor.Black;
            }
            return(result);
        }
        /// <summary>
        /// This method restructures the red-black tree after an append. If the structure was changed, and the
        /// change is a parent node with branching children, the tree with restructure itself.
        /// </summary>
        private void RestructureAfterAppend(ColoredTreeNode <K, V> currentNode)
        {
            // If the parent is null, change the current node to black. It is now the new root!
            if (currentNode.Parent == null)
            {
                currentNode.Color = NodeColor.Black; return;
            }

            // If the parent is black, the tree is still structured (no imbalance).
            else if (ConfirmColor(currentNode.Parent) == NodeColor.Black)
            {
                return;
            }

            // If the uncle of the current node is red, restructure the colors and check again for restructuring:
            else if (ConfirmColor(currentNode.Uncle) == NodeColor.Red)
            {
                currentNode.Parent.Color      = NodeColor.Black;
                currentNode.Uncle.Color       = NodeColor.Black;
                currentNode.Grandparent.Color = NodeColor.Red;
                RestructureAfterAppend(currentNode.Grandparent);
                return;
            }

            // If this node is the right child node, and the parent is the grandparent's left node, rotate to the left.
            if (currentNode == currentNode.Parent.Right &&
                currentNode.Parent == currentNode.Grandparent.Left)
            {
                RotateLeft(currentNode.Parent);
                currentNode = currentNode.Left;
            }

            // If this node is the left child node, and the parent is the grandparent's right node, rotate to the right.
            else if (currentNode == currentNode.Parent.Left &&
                     currentNode.Parent == currentNode.Grandparent.Right)
            {
                RotateRight(currentNode.Parent);
                currentNode = currentNode.Right;
            }

            // Set the parent's color to black and grandparent to red:
            currentNode.Parent.Color      = NodeColor.Black;
            currentNode.Grandparent.Color = NodeColor.Red;

            // If the node is the parent's left, and the parent is the grandparent's left, rotate to the right.
            if (currentNode == currentNode.Parent.Left &&
                currentNode.Parent == currentNode.Grandparent.Left)
            {
                RotateRight(currentNode.Grandparent);
            }

            // If the node is the parent's right, and the parent is the grandparent's right, rotate to the left.
            else if (currentNode == currentNode.Parent.Right &&
                     currentNode.Parent == currentNode.Grandparent.Right)
            {
                RotateLeft(currentNode.Grandparent);
            }
        }
        /// <summary>
        /// This method appends a key and value to the tree. It does this by starting at the
        /// root, then following child branches until a position is found in the tree. The tree is then
        /// resorted for the most optimized key-value pair lookups. If the key already has a value
        /// associated with it, this method will return false; else, it will return true (if the key and
        /// value were both added to the tree).
        /// </summary>
        public bool TryAppend(K key, V value)
        {
            // Create the new node (always starts with red) - then error check:
            ColoredTreeNode <K, V> createdNode = new ColoredTreeNode <K, V>(null, null, key, value, NodeColor.Red);

            if (_root == null)
            {
                _root = createdNode; _root.Color = NodeColor.Red; return(true);
            }

            // Find the position where the node will be placed:
            ColoredTreeNode <K, V> currentNode = _root;

            while (true)
            {
                // Is the key already in the red-black tree? If so, update the value:
                if (key.Equals(currentNode.Key))
                {
                    return(false);
                }
                else if (key.CompareTo(currentNode.Key) < 0)
                {
                    // The key is less than the current node's key. Go to the left.
                    // If there is no left, become the new left child of the current node:
                    if (currentNode.Left != null)
                    {
                        currentNode = currentNode.Left;
                    }
                    else
                    {
                        currentNode.Left = createdNode; break;
                    }
                }
                else
                {
                    // The key is greater than the current node's key. Go to the right.
                    // If there is no right, become the new right child of the current node:
                    if (currentNode.Right != null)
                    {
                        currentNode = currentNode.Right;
                    }
                    else
                    {
                        currentNode.Right = createdNode; break;
                    }
                }
            }

            // Correct the tree:
            RestructureAfterAppend(createdNode);
            return(true);
        }
        /// <summary>
        /// This method rotates the branch to the left. It does this by taking the right, replacing the current
        /// node with the right node, then making the right node equal the left node. If the left node isn't null,
        /// the left parent will equal the current node. Then, the right's left will be the current node, and the
        /// current node's parent will become the right.
        /// </summary>
        private void RotateLeft(ColoredTreeNode <K, V> node)
        {
            ColoredTreeNode <K, V> right = node.Right;

            Replace(node, right);
            node.Right = right.Left;

            if (right.Left != null)
            {
                right.Left.Parent = node;
            }

            right.Left  = node;
            node.Parent = right;
        }
        /// <summary>
        /// This method rotates the branch to the right. It does this by taking the left, replacing the current node
        /// with the left node, then making the left node equal the right node. If the right node isn't null, the
        /// right parent will equal the current node. Then, the left's right will be the current node, and the
        /// current node's parent will become the left.
        /// </summary>
        private void RotateRight(ColoredTreeNode <K, V> node)
        {
            ColoredTreeNode <K, V> left = node.Left;

            Replace(node, left);
            node.Left = left.Right;

            if (left.Right != null)
            {
                left.Right.Parent = node;
            }

            left.Right  = node;
            node.Parent = left;
        }
        public NodeColor Color;                // The color of the node (red or black).

        /// <summary>
        /// This class encapsulates a colored tree node for the implementation of a red-black tree. It consists of
        /// the node's key and value, left and right branches, parent, and methods for retrieving values and nodes
        /// from further up in the tree (grandparent, uncle, sibling, etc).
        /// </summary>
        /// <param name="right">The right branch / child connected to the node.</param>
        /// <param name="left">The left branch / child connected to the node.</param>
        /// <param name="key">The key held in the node.</param>
        /// <param name="value">The value held in the node.</param>
        /// <param name="color">The color of the node (red or black).</param>
        public ColoredTreeNode(ColoredTreeNode <K, V> right, ColoredTreeNode <K, V> left, K key,
                               V value, NodeColor color)
        {
            Right = right;
            Left  = left;
            Key   = key;
            Value = value;
            Color = color;

            if (left != null)
            {
                left.Parent = this;
            }
            if (right != null)
            {
                right.Parent = this;
            }
            Parent = null;
        }
        /// <summary>
        /// This method returns the value at a specified key if the tree contains the key specified; else, it ..
        /// returns null. It finds the key by starting at the root; then, if the search key is less than the
        /// current key, it goes left - else, right.
        /// </summary>
        public V TryGetValue(K key)
        {
            ColoredTreeNode <K, V> current = _root;

            while (current != null)
            {
                if (current.Key.Equals(key))
                {
                    return(current.Value);
                }
                else if (key.CompareTo(current.Key) < 0)
                {
                    current = current.Left;
                }
                else
                {
                    current = current.Right;
                }
            }
            return(default(V));
        }
        /// <summary>
        /// This method returns true if the tree contains the key specified; else, it returns
        /// false. It finds the key by starting at the root; then, if the search key is less than the
        /// current key, it goes left - else, right.
        /// </summary>
        public bool Contains(K key)
        {
            ColoredTreeNode <K, V> current = _root;

            while (current != null)
            {
                if (current.Key.Equals(key))
                {
                    return(true);
                }
                else if (key.CompareTo(current.Key) < 0)
                {
                    current = current.Left;
                }
                else
                {
                    current = current.Right;
                }
            }
            return(false);
        }
        private void RestructureAfterDeletion(ColoredTreeNode <K, V> currentNode)
        {
            // Is the current node now the root of the tree?
            if (currentNode.Parent == null)
            {
                return;
            }

            // If the sibling color is red, recolor and rotate accordingly.
            if (ConfirmColor(currentNode.Sibling) == NodeColor.Red)
            {
                currentNode.Parent.Color  = NodeColor.Red;
                currentNode.Sibling.Color = NodeColor.Black;
                if (currentNode == currentNode.Parent.Left)
                {
                    RotateLeft(currentNode.Parent);
                }
                else
                {
                    RotateRight(currentNode.Parent);
                }
            }

            // If the branch is all black, recolor and recall the restructuring:
            if (ConfirmColor(currentNode.Parent) == NodeColor.Black &&
                ConfirmColor(currentNode.Sibling) == NodeColor.Black &&
                ConfirmColor(currentNode.Sibling.Left) == NodeColor.Black &&
                ConfirmColor(currentNode.Sibling.Right) == NodeColor.Black)
            {
                currentNode.Sibling.Color = NodeColor.Red;
                RestructureAfterDeletion(currentNode.Parent);
            }

            // Check coloring and correct if the parent is red and the children and sibling are all black:
            else if (ConfirmColor(currentNode.Parent) == NodeColor.Red &&
                     ConfirmColor(currentNode.Sibling) == NodeColor.Black &&
                     ConfirmColor(currentNode.Sibling.Left) == NodeColor.Black &&
                     ConfirmColor(currentNode.Sibling.Right) == NodeColor.Black)
            {
                currentNode.Sibling.Color = NodeColor.Red;
                currentNode.Parent.Color  = NodeColor.Black;
            }
            else
            {
                // If the current node is the parent's left child, the sibling is black, and the sibling's left child is
                // red and right child is black, recolor and rotate to the right.
                if (currentNode == currentNode.Parent.Left &&
                    ConfirmColor(currentNode.Sibling) == NodeColor.Black &&
                    ConfirmColor(currentNode.Sibling.Left) == NodeColor.Red &&
                    ConfirmColor(currentNode.Sibling.Right) == NodeColor.Black)
                {
                    currentNode.Sibling.Color      = NodeColor.Red;
                    currentNode.Sibling.Left.Color = NodeColor.Black;
                    RotateRight(currentNode.Sibling);
                }

                // If the current node is the parent's right child, the sibling is black, and the sibling's right child is
                // red and left child is black, recolor and rotate to the left.
                else if (currentNode == currentNode.Parent.Right &&
                         ConfirmColor(currentNode.Sibling) == NodeColor.Black &&
                         ConfirmColor(currentNode.Sibling.Right) == NodeColor.Red &&
                         ConfirmColor(currentNode.Sibling.Left) == NodeColor.Black)
                {
                    currentNode.Sibling.Color       = NodeColor.Red;
                    currentNode.Sibling.Right.Color = NodeColor.Black;
                    RotateLeft(currentNode.Sibling);
                }

                // Change the color of the sibling to the color of the parent, and the color of the parent to black.
                // Then, recheck and rotate accordingly:
                currentNode.Sibling.Color = ConfirmColor(currentNode.Parent);
                currentNode.Parent.Color  = NodeColor.Black;
                if (currentNode == currentNode.Parent.Left)
                {
                    currentNode.Sibling.Right.Color = NodeColor.Black;
                    RotateLeft(currentNode.Parent);
                }
                else
                {
                    currentNode.Sibling.Left.Color = NodeColor.Black;
                    RotateRight(currentNode.Parent);
                }
            }
        }
        ColoredTreeNode <K, V> _root; // The root of the red-black tree.

        /// <summary>
        /// A red–black tree is a type of self-balancing binary search tree. The self-balancing is provided by
        /// painting each node with one of two colors (these are typically called 'red' and 'black', hence the
        /// name of the trees) in such a way that the resulting painted tree satisfies certain properties that
        /// don't allow it to become significantly unbalanced. When the tree is modified, the new tree is
        /// subsequently rearranged and repainted to restore the coloring properties. The properties are
        /// designed in such a way that this rearranging and recoloring can be performed efficiently. The
        /// efficiency of the algorithm is O(log n).
        /// </summary>
        public RedBlackTree()
        {
            _root = null;
        }
 /// <summary>
 /// This method is used to confirm the color of the passed node. If the current node is equal to NULL,
 /// the method will return black; else, it will return the color of the current node.
 /// </summary>
 private NodeColor ConfirmColor(ColoredTreeNode <K, V> node)
 {
     return(node == null ? NodeColor.Black : node.Color);
 }