public void DeleteNode(Node <T> NodeToDelete)
        {
            //No children -> Just Delete
            if (NodeToDelete.HasNoChildren())
            {
                if (NodeToDelete.Equals(Root))
                {
                    Root = null;
                    return;
                }

                Traverse((Node <T> node) =>
                {
                    if (node.Left != null)
                    {
                        if (node.Left.Equals(NodeToDelete))
                        {
                            node.Left = null;
                        }
                    }
                    if (node.Right != null)
                    {
                        if (node.Right.Equals(NodeToDelete))
                        {
                            node.Right = null;
                        }
                    }
                }, TraversalType.PostOrder);
                return;
            }

            //Exactly one child -> Swap
            if (NodeToDelete.HasOneChild())
            {
                if (NodeToDelete.Equals(Root))
                {
                    Root = Root.Child();
                    return;
                }

                Traverse((Node <T> node) =>
                {
                    if (node.Left != null)
                    {
                        if (node.Left.Equals(NodeToDelete))
                        {
                            node.Left = NodeToDelete.Child();
                        }
                    }
                    if (node.Right != null)
                    {
                        if (node.Right.Equals(NodeToDelete))
                        {
                            node.Right = NodeToDelete.Child();
                        }
                    }
                }, TraversalType.PostOrder);

                return;
            }

            //Find Minimum of Right sub-Tree, Copy Value, Delete Minimum
            if (NodeToDelete.HasTwoChildren())
            {
                Node <T> SuccessorNode = MinValue(NodeToDelete.Right);
                NodeToDelete.Value = SuccessorNode.Value;
                DeleteNode(SuccessorNode);

                return;
            }
        }