public boolean delete(String key) {
		final boolean[] delete = new boolean[] { false };

		final Visitor<T> visitor = new Visitor<T>() {

			public void visit(String key, Tree<RadixData<T>> node) {
				final Tree<RadixData<T>> parent = node.getParent();
				if (parent == null)
					return;

				final RadixData<T> data = node.getData();

				delete[0] = data.isReal();

				// if it is a real node
				if (delete[0]) {

					// If there no children of the node we need to
					// delete it from the its parent children list
					if (node.numChildren() == 0) {
						node.prune(true, true);

						// if parent is not real node and has only one child
						// then they need to be merged.
						if (parent.numChildren() == 1
								&& !parent.getData().isReal()) {
							mergeNodes(parent, parent.getChildren().get(0));
						}
					} else if (node.numChildren() == 1) {
						// we need to merge the only child of this node with
						// itself
						mergeNodes(node, node.getChildren().get(0));
					} else { // we jus need to mark the node as non real.
						data.setReal(false);
					}
				}
			}

			/**
			 * Merge a child into its parent node. Operation only valid if it is
			 * only child of the parent node and parent node is not a real node.
			 * 
			 * @param parent
			 *            The parent Node
			 * @param child
			 *            The child Node
			 */
			private void mergeNodes(Tree<RadixData<T>> parent,
					Tree<RadixData<T>> child) {
				final RadixData<T> parentData = parent.getData();
				final RadixData<T> childData = child.getData();

				parentData.setKey(parentData.getKey() + childData.getKey());
				parentData.setReal(childData.isReal());
				parentData.setValue(childData.getValue());

				// delete the child, moving its children to the parent
				final List<Tree<RadixData<T>>> children = child.getChildren();
				child.prune(true, true);
				if (children != null) {
					for (Tree<RadixData<T>> gchild : children) {
						parent.addChild(gchild);
					}
				}
			}
		};

		visit(key, visitor);

		if (delete[0]) {
			size--;
		}

		return delete[0];
	}