public @NotNull IntervalTreeImpl.IntervalNode<T> addInterval(@NotNull T interval, int start, int end,
                                                               boolean greedyToLeft, boolean greedyToRight, boolean stickingToRight, int layer) {
    l.writeLock().lock();
    try {
      if (firingRemove) {
        throw new IncorrectOperationException("Must not add range marker from within removed() listener");
      }
      checkMax(true);
      processReferenceQueue();
      incModCount();
      IntervalNode<T> newNode = createNewNode(interval, start, end, greedyToLeft, greedyToRight, stickingToRight, layer);
      IntervalNode<T> insertedNode = findOrInsert(newNode);
      if (insertedNode == newNode) {
        setNode(interval, insertedNode);
      }
      else {
        // merged
        insertedNode.addInterval(interval);
      }
      checkMax(true);
      checkBelongsToTheTree(interval, true);
      return insertedNode;
    }
    finally {
      l.writeLock().unlock();
    }
  }
public @NotNull IntervalTreeImpl.IntervalNode<T> addInterval(@NotNull T interval, int start, int end,
                                                               boolean greedyToLeft, boolean greedyToRight, boolean stickingToRight, int layer)