ConcurrentTree extends ConcurrentTreeNode<K, V> { public synchronized V remove(final K[] path) { ConcurrentTreeNode<K, V> node = getNode(path); if (node == null) { return null; } final V value = node.getValue(); node.setValue(null); ConcurrentTreeNode<K, V> parent; while (node.getChildren().isEmpty() && (node.getValue() == null) && ((parent = node.getParent()) != null)) { parent.removeChild(node.getKey()); node = parent; } return value; }  synchronized void add(final K[] path, final V value); synchronized V remove(final K[] path); V get(final K[] path); List<V> getMatches(final K[] path); @Override String toString();  }
@Test public void testRemove() { ConcurrentTree<String, String> tree = setupTree(); assertEquals(tree.remove(delimiter.split("a/b")), "a/b"); assertNull(tree.get(delimiter.split("a/b"))); assertNotNull(tree.get(delimiter.split("a/b/c/d/e/f"))); assertNotNull(tree.get(delimiter.split("a/a"))); assertEquals(tree.remove(delimiter.split("a/b/c/d/e/f")), "a/b/c/d/e/f"); assertNull(tree.remove(delimiter.split("a/b/c/d/e/f"))); assertNull(tree.remove(delimiter.split("a/b/c/d/e"))); assertNotNull(tree.get(delimiter.split("a/b/c/d"))); assertNull(tree.remove(delimiter.split("/b/b/c/d/e/f"))); assertNull(tree.remove(delimiter.split("b/b/c assertNull(tree.remove(delimiter.split("b/b/c/d/e/f/ "))); assertNotNull(tree.get(delimiter.split("b/b/c/d/e/f"))); assertNull(tree.remove(delimiter.split("b/b/c/d/e"))); assertNotNull(tree.get(delimiter.split("b/b/c/d/e/f"))); assertNotNull(tree.get(delimiter.split("b/b/c/d"))); }