private boolean deleteImpl(@NotNull final ByteIterable key) { final ByteIterator it = key.iterator(); NodeBase node = root; final Deque<ChildReferenceTransient> stack = new ArrayDeque<>(); for (; ; ) { if (node == null || node.matchesKeySequence(it).matchingLength < 0) { return false; } if (!it.hasNext()) { break; } final byte nextByte = it.next(); stack.push(new ChildReferenceTransient(nextByte, node)); node = node.getChild(this, nextByte); } if (!node.hasValue()) { return false; } --size; MutableNode mutableNode = node.getMutableCopy(this); ChildReferenceTransient parent = stack.peek(); final boolean hasChildren = mutableNode.hasChildren(); if (!hasChildren && parent != null) { stack.pop(); mutableNode = parent.mutate(this); mutableNode.removeChild(parent.firstByte); if (!mutableNode.hasValue() && mutableNode.getChildrenCount() == 1) { mutableNode.mergeWithSingleChild(this); } } else { mutableNode.setValue(null); if (!hasChildren) { mutableNode.setKeySequence(ByteIterable.EMPTY); } else if (mutableNode.getChildrenCount() == 1) { mutableNode.mergeWithSingleChild(this); } } mutateUp(stack, mutableNode); return true; }