void (@Nullable TreeElement end, boolean invalidate) { if(this == end) return; CompositeElement parent = getTreeParent(); TreeElement startPrev = getTreePrev(); TreeElement endPrev = end != null ? end.getTreePrev() : null; assert end == null || end.getTreeParent() == parent : "Trying to remove non-child"; if (end != null) { TreeElement element; for (element = this; element != end && element != null; element = element.getTreeNext()); assert element == end : end + " is not successor of " + this +" in the .getTreeNext() chain"; } if (parent != null){ if (getTreePrev() == null) { parent.setFirstChildNode(end); } if (end == null) { parent.setLastChildNode(startPrev); } } if (startPrev != null){ startPrev.setTreeNext(end); } if (end != null){ end.setTreePrev(startPrev); } setTreePrev(null); if (endPrev != null){ endPrev.setTreeNext(null); } if (parent != null){ for(TreeElement element = this; element != null; element = element.getTreeNext()){ element.setTreeParent(null); if (invalidate) { element.onInvalidated(); } } } DebugUtil.checkTreeStructure(parent); DebugUtil.checkTreeStructure(this); }