private static void divideInsideAndOutsideInOneRoot(@NotNull PsiFile root,
                                                      long restrictRange,
                                                      long priorityRange,
                                                      @NotNull List<PsiElement> inside,
                                                      @NotNull LongList insideRanges,
                                                      @NotNull List<PsiElement> outside,
                                                      @NotNull LongList outsideRanges,
                                                      @NotNull List<? super PsiElement> outParents,
                                                      @NotNull LongList outParentRanges) {
    int startOffset = TextRangeScalarUtil.startOffset(restrictRange);
    int endOffset = TextRangeScalarUtil.endOffset(restrictRange);

    List<Condition<PsiElement>> filters = CollectHighlightsUtil.EP_NAME.getExtensionList();

    IntStack starts = new IntArrayList(STARTING_TREE_HEIGHT);
    starts.push(startOffset);
    Stack<PsiElement> elements = new Stack<>(STARTING_TREE_HEIGHT);
    Stack<PsiElement> children = new Stack<>(STARTING_TREE_HEIGHT);
    PsiElement element = root;

    PsiElement child = HAVE_TO_GET_CHILDREN;
    int offset = 0;
    while (true) {
      ProgressManager.checkCanceled();

      for (Condition<PsiElement> filter : filters) {
        if (!filter.value(element)) {
          assert child == HAVE_TO_GET_CHILDREN;
          child = null; // do not want to process children
          break;
        }
      }

      boolean startChildrenVisiting;
      if (child == HAVE_TO_GET_CHILDREN) {
        startChildrenVisiting = true;
        child = element.getFirstChild();
      }
      else {
        startChildrenVisiting = false;
      }

      if (child == null) {
        if (startChildrenVisiting) {
          // leaf element
          offset += element.getTextLength();
        }

        int start = starts.popInt();
        if (startOffset <= start && offset <= endOffset) {
          if (TextRangeScalarUtil.containsRange(priorityRange, start, offset)) {
            inside.add(element);
            insideRanges.add(TextRangeScalarUtil.toScalarRange(start, offset));
          }
          else {
            outside.add(element);
            outsideRanges.add(TextRangeScalarUtil.toScalarRange(start, offset));
          }
        }

        if (elements.isEmpty()) break;
        element = elements.pop();
        child = children.pop();
      }
      else {
        // composite element
        if (offset > endOffset) break;
        children.push(child.getNextSibling());
        starts.push(offset);
        elements.push(element);
        element = child;
        child = HAVE_TO_GET_CHILDREN;
      }
    }

    PsiElement parent = !outside.isEmpty() ? outside.get(outside.size() - 1) :
                        !inside.isEmpty() ? inside.get(inside.size() - 1) :
                        CollectHighlightsUtil.findCommonParent(root, startOffset, endOffset);
    while (parent != null && !(parent instanceof PsiFile)) {
      parent = parent.getParent();
      if (parent != null) {
        outParents.add(parent);
        TextRange textRange = parent.getTextRange();
        assert textRange != null : "Text range for " + parent + " is null. " + parent.getClass() +"; root: "+root+": "+root.getVirtualFile();
        outParentRanges.add(TextRangeScalarUtil.toScalarRange(textRange));
      }
    }

    assert inside.size() == insideRanges.size();
    assert outside.size() == outsideRanges.size();
    assert outParents.size() == outParentRanges.size();
  }
private static void divideInsideAndOutsideInOneRoot(@NotNull PsiFile root,
                                                      long restrictRange,
                                                      long priorityRange,
                                                      @NotNull List<PsiElement> inside,
                                                      @NotNull LongList insideRanges,
                                                      @NotNull List<PsiElement> outside,
                                                      @NotNull LongList outsideRanges,
                                                      @NotNull List<? super PsiElement> outParents,
                                                      @NotNull LongList outParentRanges)