private BinarySearchTreeNode <T> FindNodeAndParent(T value, out BinarySearchTreeNode <T> parent)
        {
            if (_count == 0)
            {
                throw new InvalidOperationException("Binary Search Tree is empty!");
            }
            parent = null;
            BinarySearchTreeNode <T> pointer = _root;

            while (pointer != null)
            {
                //go to left
                if (pointer.CompareTo(value) > 0)
                {
                    parent  = pointer;
                    pointer = pointer.Left;
                }
                //go to right
                else if (pointer.CompareTo(value) < 0)
                {
                    parent  = pointer;
                    pointer = pointer.Right;
                }
                //match!
                else
                {
                    break;
                }
            }
            return(pointer);
        }
 private void Add(BinarySearchTreeNode <T> node, BinarySearchTreeNode <T> parent)
 {
     //go to left
     if (parent.CompareTo(node.Value) > 0)
     {
         if (parent.Left == null)
         {
             parent.Left = node;
         }
         else
         {
             Add(node, parent.Left);
         }
     }
     //go to right
     else
     {
         if (parent.Right == null)
         {
             parent.Right = node;
         }
         else
         {
             Add(node, parent.Right);
         }
     }
 }
        /// <summary>
        /// Removes a node by specifying its value.
        /// </summary>
        /// <param name="value">Any generic type that implements IComparable of T interface.</param>
        /// <returns>True if deleted. Otherwise false.</returns>
        /// <exception cref="InvalidOperationException">Binary Search Tree is empty.</exception>
        public bool Remove(T value)
        {
            if (_count == 0)
            {
                throw new InvalidOperationException("Binary Search Tree is empty!");
            }
            BinarySearchTreeNode <T> parent = null;
            BinarySearchTreeNode <T> node   = FindNodeAndParent(value, out parent);

            if (node == null)
            {
                return(false);
            }
            //decrement first!
            _count--;

            if (node.Right == null)
            {
                //it's a root!!
                if (parent == null)
                {
                    _root = node.Left;
                }
                else
                {
                    //it's left
                    if (parent.CompareTo(value) > 0)
                    {
                        parent.Left = node.Left;
                    }
                    else
                    {
                        parent.Right = node.Left;
                    }
                }
            }
            else if (node.Right.Left == null)
            {
                node.Right.Left = node.Left;
                if (parent == null)
                {
                    _root = node.Right;
                }
                else
                {
                    if (parent.CompareTo(value) > 0)
                    {
                        parent.Left = node.Right;
                    }
                    else
                    {
                        parent.Right = node.Right;
                    }
                }
            }
            else
            {
                BinarySearchTreeNode <T> parentLeftEnd = node.Right;
                BinarySearchTreeNode <T> leftEnd       = node.Right.Left;

                while (leftEnd.Left != null)
                {
                    parentLeftEnd = leftEnd;
                    leftEnd       = leftEnd.Left;
                }

                parentLeftEnd.Left = leftEnd.Right;
                leftEnd.Left       = node.Left;
                leftEnd.Right      = node.Right;

                if (parent == null)
                {
                    _root = leftEnd;
                }
                else
                {
                    if (parent.CompareTo(value) > 0)
                    {
                        parent.Left = leftEnd;
                    }
                    else
                    {
                        parent.Right = leftEnd;
                    }
                }
            }
            node = null;
            return(true);
        }