private CaretEvent doMoveToLogicalPosition(@NotNull LogicalPosition pos,
                                             boolean locateBeforeSoftWrap,
                                             @NonNls @Nullable StringBuilder debugBuffer,
                                             boolean adjustForInlays,
                                             boolean fireListeners) {
    assertIsDispatchThread();
    checkDisposal();
    updateCachedStateIfNeeded();
    if (debugBuffer != null) {
      debugBuffer.append("Start moveToLogicalPosition(). Locate before soft wrap: ").append(locateBeforeSoftWrap).append(", position: ")
        .append(pos).append("\n");
    }
    myDesiredX = -1;
    assertNotUpdating();
    int column = pos.column;
    int line = pos.line;
    boolean leansForward = pos.leansForward;

    Document doc = myEditor.getDocument();

    int lineCount = doc.getLineCount();
    if (lineCount == 0) {
      if (debugBuffer != null) {
        debugBuffer.append("Resetting target logical line to zero as the document is empty\n");
      }
      line = 0;
    }
    else if (line > lineCount - 1) {
      if (debugBuffer != null) {
        debugBuffer.append("Resetting target logical line (").append(line).append(") to ").append(lineCount - 1)
          .append(" as it is greater than total document lines number\n");
      }
      line = lineCount - 1;
    }

    EditorSettings editorSettings = myEditor.getSettings();

    if (!editorSettings.isVirtualSpace() && line < lineCount) {
      int lineEndOffset = doc.getLineEndOffset(line);
      final LogicalPosition endLinePosition = myEditor.offsetToLogicalPosition(lineEndOffset);
      int lineEndColumnNumber = endLinePosition.column;
      if (column > lineEndColumnNumber) {
        int oldColumn = column;
        column = lineEndColumnNumber;
        leansForward = true;
        if (debugBuffer != null) {
          debugBuffer.append("Resetting target logical column (").append(oldColumn).append(") to ").append(lineEndColumnNumber)
            .append(" because caret is not allowed to be located after line end (offset: ").append(lineEndOffset).append(", ")
            .append("logical position: ").append(endLinePosition).append(").\n");
        }
      }
    }

    VerticalInfo oldVerticalInfo = myVerticalInfo;
    LogicalPosition oldCaretPosition = myLogicalCaret;
    VisualPosition oldVisualPosition = myVisibleCaret;
    boolean oldInVirtualSpace = isInVirtualSpace();

    LogicalPosition logicalPositionToUse = new LogicalPosition(line, column, leansForward);
    final int offset = myEditor.logicalPositionToOffset(logicalPositionToUse);
    if (debugBuffer != null) {
      debugBuffer.append("Resulting logical position to use: ").append(logicalPositionToUse).append(". It's mapped to offset ").append(offset).append("\n");
    }

    FoldRegion collapsedAt = myEditor.getFoldingModel().getCollapsedRegionAtOffset(offset);

    if (collapsedAt != null && offset > collapsedAt.getStartOffset()) {
      if (debugBuffer != null) {
        debugBuffer.append("Scheduling expansion of fold region ").append(collapsedAt).append("\n");
      }
      Runnable runnable = () -> {
        FoldRegion[] allCollapsedAt = myEditor.getFoldingModel().fetchCollapsedAt(offset);
        for (FoldRegion foldRange : allCollapsedAt) {
          foldRange.setExpanded(true);
        }
      };

      mySkipChangeRequests = true;
      try {
        myEditor.getFoldingModel().runBatchFoldingOperation(runnable, false, false, true);
      }
      finally {
        mySkipChangeRequests = false;
      }
    }

    myEditor.getFoldingModel().flushCaretPosition(this);

    myLogicalCaret = logicalPositionToUse;
    myColumnNumberForCloning = -1;
    myDesiredSelectionStartColumn = myDesiredSelectionEndColumn = -1;
    myVisibleCaret = myEditor.logicalToVisualPosition(myLogicalCaret);
    myVisualColumnAdjustment = 0;

    updateOffsetsFromLogicalPosition();
    int newOffset = getOffset();
    if (debugBuffer != null) {
      debugBuffer.append("Storing offset ").append(newOffset).append(" (mapped from logical position ").append(myLogicalCaret).append(")\n");
    }

    if (adjustForInlays) {
      VisualPosition correctPosition = EditorUtil.inlayAwareOffsetToVisualPosition(myEditor, newOffset);
      assert correctPosition.line == myVisibleCaret.line;
      myVisualColumnAdjustment = correctPosition.column - myVisibleCaret.column;
      myVisibleCaret = correctPosition;
    }

    updateVisualLineInfo();

    myEditor.updateCaretCursor();
    requestRepaint(oldVerticalInfo);

    if (locateBeforeSoftWrap && SoftWrapHelper.isCaretAfterSoftWrap(this)) {
      int lineToUse = myVisibleCaret.line - 1;
      if (lineToUse >= 0) {
        final VisualPosition visualPosition = new VisualPosition(lineToUse, EditorUtil.getLastVisualLineColumnNumber(myEditor, lineToUse));
        if (debugBuffer != null) {
          debugBuffer.append("Adjusting caret position by moving it before soft wrap. Moving to visual position ").append(visualPosition).append("\n");
        }
        final int tmpOffset = myEditor.visualPositionToOffset(visualPosition);
        if (tmpOffset == newOffset) {
          moveToVisualPosition(visualPosition);
          return null;
        }
        else {
          LOG.error("Invalid editor dimension mapping", new Throwable(), AttachmentFactory.createContext(
            "Expected to map visual position '" +
            visualPosition + "' to offset " + newOffset + " but got the following: -> offset " + tmpOffset +
            ". State: " + myEditor.dumpState()));
        }
      }
    }

    if (!oldVisualPosition.equals(myVisibleCaret) || !oldCaretPosition.equals(myLogicalCaret)) {
      if (oldInVirtualSpace || isInVirtualSpace()) {
        myCaretModel.validateEditorSize();
      }
      CaretEvent event = new CaretEvent(this, oldCaretPosition, myLogicalCaret);
      if (fireListeners) {
        myCaretModel.fireCaretPositionChanged(event);
      }
      else {
        return event;
      }
    }
    return null;
  }
private CaretEvent doMoveToLogicalPosition(@NotNull LogicalPosition pos,
                                             boolean locateBeforeSoftWrap,
                                             @NonNls @Nullable StringBuilder debugBuffer,
                                             boolean adjustForInlays,
                                             boolean fireListeners)