// Suppose t != null.
        void RemoveTarget(BstNode <T> t)
        {
            if (t.TypedLeft == null || t.TypedRight == null)
            {
                var c = t.TypedLeft ?? t.TypedRight;

                if (t.TypedParent == null)
                {
                    Root = c;
                }
                else if (t.TypedParent.TypedLeft == t)
                {
                    t.TypedParent.TypedLeft = c;
                }
                else
                {
                    t.TypedParent.TypedRight = c;
                }
            }
            else
            {
                var t2 = t.SearchNextNode() as BstNode <T>;
                t.Key = t2.Key;
                RemoveTarget(t2);
            }
        }
        BstNode <T> Add(BstNode <T> node, T item)
        {
            if (node == null)
            {
                ++Count;

                return(new BstNode <T> {
                    Key = item
                });
            }

            var d = compare(item, node.Key);

            if (d == 0)
            {
                return(node);
            }

            if (d < 0)
            {
                node.TypedLeft = Add(node.TypedLeft, item);
            }
            else
            {
                node.TypedRight = Add(node.TypedRight, item);
            }
            return(node);
        }