@Override
    public V remove(String key)
    {
        if (key == null)
        {
            throw new IllegalArgumentException();
        }
        Node<V> node = root;
        int length = key.length();
        Stack<Node<V>> nodes = new ArrayList<Node<V>>();
        nodes.push(root);
        for (int i = 0; i < length; ++i)
        {
            char c = key.charAt(i);
            if (!valid(c))
            {
                throw new IllegalArgumentException();
            }
            if (node.next[c] == null)
            {
                return null;
            }
            node = node.next[c];
            nodes.push(node);
        }
        V value = node.value;
        node.value = null;
        if (value != null)
        {
            --size;
        }
        for (int i = length - 1; i >= 0; --i)
        {
            node = nodes.pop();
            if (node.value != null)
            {
                return value;
            }
            for (int j = 0; j < ALPHABET_SIZE; ++j)
            {
                if (node.next[j] != null)
                {
                    return value;
                }
            }
            nodes.top().next[i] = null;
        }
        return value;
    }