protected void paint(
    @NotNull Editor editor,
    @NotNull VisualPosition lineStartPosition,
    @NotNull VisualPosition lineEndPosition,
    int startOffset,
    int endOffset,
    @NotNull Document doc,
    @NotNull Graphics g
  ) {
    int indentColumn = lineStartPosition.column;
    if (indentColumn < 0) return; // 0 is possible in Rider virtual formatting, and it is logically sound

    FoldingModel foldingModel = editor.getFoldingModel();
    if (foldingModel.isOffsetCollapsed(startOffset)) return;

    FoldRegion headerRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(doc.getLineNumber(startOffset)));
    FoldRegion tailRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineStartOffset(doc.getLineNumber(endOffset)));

    if (tailRegion != null && tailRegion == headerRegion) return;

    final var virtualGuideInfo = VirtualFormattingIndentGuideInfo.getInstance();
    final var isVirtualFormattingEnabled = virtualGuideInfo.isVirtualFormattingEnabled(editor);

    if (!isVirtualFormattingEnabled && indentColumn == 0) return; // 0 is impossible outside Rider virtual formatting context

    var vfmtRightShift = 0;
    if (virtualGuideInfo.isVirtualFormattingEnabled(editor)) {
      vfmtRightShift = virtualGuideInfo
        .getVisualFormattingInlineInlays(editor, doc.getLineStartOffset(doc.getLineNumber(startOffset)),
                                         doc.getLineEndOffset(doc.getLineNumber(startOffset)))
        .stream()
        .map(inlay -> inlay.getWidthInPixels())
        .reduce(0, Integer::sum);
    }

    final boolean selected = isSelected(editor, endOffset, startOffset, lineStartPosition.column);
    final boolean stickyPainting = editor instanceof EditorImpl editorImpl && editorImpl.isStickyLinePainting();
    Color color = getIndentColor(editor, startOffset, selected, stickyPainting);
    if (color == null) {
      return;
    }

    final int lineHeight = editor.getLineHeight();
    Point start = editor.visualPositionToXY(lineStartPosition);
    start.x += vfmtRightShift;
    start.y += lineHeight;
    Point end = editor.visualPositionToXY(lineEndPosition);
    int maxY = end.y;
    if (lineEndPosition.line == editor.offsetToVisualPosition(doc.getTextLength()).line) {
      maxY += lineHeight;
    }

    Rectangle clip = g.getClipBounds();
    if (clip != null) {
      if (clip.y >= maxY || clip.y + clip.height <= start.y) {
        return;
      }
      maxY = Math.min(maxY, clip.y + clip.height);
    }

    if (start.y >= maxY) return;

    int targetX = Math.max(0, start.x + EditorPainter.getIndentGuideShift(editor));
    g.setColor(color);
    // There is a possible case that indent line intersects soft wrap-introduced text. Example:
    //     this is a long line <soft-wrap>
    // that| is soft-wrapped
    //     |
    //     | <- vertical indent
    //
    // Also it's possible that no additional intersections are added because of soft wrap:
    //     this is a long line <soft-wrap>
    //     |   that is soft-wrapped
    //     |
    //     | <- vertical indent
    // We want to use the following approach then:
    //     1. Show only active indent if it crosses soft wrap-introduced text;
    //     2. Show indent as is if it doesn't intersect with soft wrap-introduced text;
    List<? extends SoftWrap> softWraps = ((EditorEx)editor).getSoftWrapModel().getRegisteredSoftWraps();
    if (selected || softWraps.isEmpty()) {
      LinePainter2D.paint((Graphics2D)g, targetX, start.y, targetX, maxY - 1);
    }
    else {
      int startY = start.y;
      int startVisualLine = lineStartPosition.line + 1;
      if (clip != null && startY < clip.y) {
        startY = clip.y;
        startVisualLine = editor.yToVisualLine(clip.y);
      }
      VisualLinesIterator it = new VisualLinesIterator((EditorImpl)editor, startVisualLine);
      while (!it.atEnd()) {
        int currY = it.getY();
        if (currY >= startY) {
          if (currY >= maxY) break;
          if (it.startsWithSoftWrap()) {
            SoftWrap softWrap = softWraps.get(it.getStartOrPrevWrapIndex());
            if (softWrap.getIndentInColumns() < indentColumn) {
              if (startY < currY) {
                LinePainter2D.paint((Graphics2D)g, targetX, startY, targetX, currY - 1);
              }
              startY = currY + lineHeight;
            }
          }
        }
        it.advance();
      }
      if (startY < maxY) {
        LinePainter2D.paint((Graphics2D)g, targetX, startY, targetX, maxY - 1);
      }
    }
  }
protected void paint(
    @NotNull Editor editor,
    @NotNull VisualPosition lineStartPosition,
    @NotNull VisualPosition lineEndPosition,
    int startOffset,
    int endOffset,
    @NotNull Document doc,
    @NotNull Graphics g
  )