@Override
    public V remove(K key)
    {
        if (key == null)
        {
            throw new IllegalArgumentException();
        }
        if (root == null)
        {
            return null;
        }
        Stack<Node<K, V>> ancestors = new ArrayList<Node<K, V>>();
        Node<K, V> parent = null;
        Node<K, V> child = root;
        while (child != null)
        {
            int c = key.compareTo(child.key);
            if (c == 0)
            {
                break;
            }
            else
            {
                parent = child;
                ancestors.push(parent);
                if (c < 0)
                {
                    child = child.less;
                }
                else
                {
                    child = child.greater;
                }
            }
        }
        if (child != null)
        {
            V value = child.value;
            remove(parent, child);
            while (!ancestors.empty())
            {
                Node<K, V> node = ancestors.pop();
                --node.size;
                balance(node);
            }
            return value;
        }
        return null;
    }