private boolean processOverlappingWithOutside(@Nullable IntervalNode<T> root,
                                                int start,
                                                int end,
                                                int modCountBefore,
                                                int deltaUpToRootExclusive,
                                                @NotNull Processor<? super T> processor) {
    if (root == null) {
      return true;
    }
    assert root.isValid();

    int delta = deltaUpToRootExclusive + root.delta;
    int rootMaxEnd = maxEndOf(root, deltaUpToRootExclusive);
    int rootStartOffset = root.intervalStart() + delta;
    int rootEndOffset = root.intervalEnd() + delta;

    if (!processOverlappingWithOutside(root.getLeft(), start, end, modCountBefore, delta, processor)) return false;

    boolean toProcess = rootStartOffset < start || rootEndOffset > end;
    if (toProcess) {
      if (!root.processAliveKeys(processor)) return false;
      if (getModCount() != modCountBefore) throw new ConcurrentModificationException();
    }

    if (rootStartOffset >= start && rootMaxEnd <= end) return true; // cant intersect outside

    return processOverlappingWithOutside(root.getRight(), start, end, modCountBefore, delta, processor);
  }
private boolean processOverlappingWithOutside(@Nullable IntervalNode<T> root,
                                                int start,
                                                int end,
                                                int modCountBefore,
                                                int deltaUpToRootExclusive,
                                                @NotNull Processor<? super T> processor)