private void processMouseDragged(@NotNull MouseEvent e) {
    if (!SwingUtilities.isLeftMouseButton(e) && !SwingUtilities.isMiddleMouseButton(e)
        || (Registry.is("editor.disable.drag.with.right.button") && SwingUtilities.isRightMouseButton(e))) {
      return;
    }

    if (!myMouseDragStarted) {
      var point = convertPoint(e.getComponent(), e.getPoint(), myEditorComponent);
      var sensitivity = Registry.intValue("editor.drag.sensitivity", 5, 0, 25);
      myMouseDragStarted = myLastMousePressedPoint == null
                           || !myLastPressedOnGutter // Small drags aren't a problem in the editor, only on the gutter.
                           || Math.abs(myLastMousePressedPoint.x - point.x) >= sensitivity
                           || Math.abs(myLastMousePressedPoint.y - point.y) >= sensitivity;
      if (!myMouseDragStarted) {
        return;
      }

      if (mySuppressedByBreakpointsLastPressPosition != null) {
        getCaretModel().removeSecondaryCarets();
        getCaretModel().moveToVisualPosition(mySuppressedByBreakpointsLastPressPosition);
        mySuppressedByBreakpointsLastPressPosition = null;
      }
    }

    EditorMouseEventArea eventArea = getMouseEventArea(e);
    if (eventArea == EditorMouseEventArea.ANNOTATIONS_AREA) return;
    if (eventArea == EditorMouseEventArea.LINE_MARKERS_AREA ||
        eventArea == EditorMouseEventArea.FOLDING_OUTLINE_AREA && !isInsideGutterWhitespaceArea(e)) {
      // The general idea is that we don't want to change caret position on gutter marker area click (e.g., on setting a breakpoint)
      // but do want to allow bulk selection on gutter marker mouse drag. However, when a drag is performed, the first event is
      // a 'mouse pressed' event, that's why we remember target line on 'mouse pressed' processing and use that information on
      // further dragging (if any).
      if (myDragOnGutterSelectionStartLine >= 0) {
        mySelectionModel.removeSelection();
        myCaretModel.moveToOffset(myDragOnGutterSelectionStartLine < myDocument.getLineCount()
                                  ? myDocument.getLineStartOffset(myDragOnGutterSelectionStartLine) : myDocument.getTextLength());
      }
      myDragOnGutterSelectionStartLine = -1;
    }

    if (eventArea == EditorMouseEventArea.LINE_NUMBERS_AREA &&
        NewUI.isEnabled() && EditorUtil.isBreakPointsOnLineNumbers() &&
        getMouseSelectionState() != MOUSE_SELECTION_STATE_LINE_SELECTED &&
        //IDEA-295653 We should not select a line if we are dragging an object. For example, a breakpoint
        !myLastPressedOnGutterIcon && !myDragSelectionStarted) {
      selectLineAtCaret(true); //IDEA-305975
      getGutterComponentEx().putClientProperty("active.line.number", null); //clear hovered breakpoint
      myDragSelectionStarted = true;
    }

    boolean columnSelectionDragEvent = isColumnSelectionDragEvent(e);
    boolean toggleCaretEvent = isToggleCaretEvent(e);
    boolean addRectangularSelectionEvent = isAddRectangularSelectionEvent(e);
    boolean columnSelectionDrag = isColumnMode() && !myLastPressCreatedCaret || columnSelectionDragEvent;
    if (!columnSelectionDragEvent && toggleCaretEvent && !myLastPressCreatedCaret) {
      return; // ignoring drag after removing a caret
    }
    if (myLastPressWasAtBlockInlay) {
      return; // ignoring drag originating over block inlay
    }

    Rectangle visibleArea = getScrollingModel().getVisibleArea();

    int x = e.getX();

    if (e.getSource() == myGutterComponent) {
      x = 0;
    }

    int dx = 0;
    if (x < visibleArea.x && visibleArea.x > 0) {
      dx = x - visibleArea.x;
    }
    else {
      if (x > visibleArea.x + visibleArea.width) {
        dx = x - visibleArea.x - visibleArea.width;
      }
    }

    int dy = 0;
    int y = e.getY();
    if (y < visibleArea.y && visibleArea.y > 0) {
      dy = y - visibleArea.y;
    }
    else {
      if (y > visibleArea.y + visibleArea.height && visibleArea.y + visibleArea.height < myEditorComponent.getHeight()) {
        dy = y - visibleArea.y - visibleArea.height;
      }
    }
    if (dx == 0 && dy == 0) {
      myScrollingTimer.stop();

      if (myLastPressedOnGutterIcon) {
        return;
      }

      SelectionModel selectionModel = getSelectionModel();
      Caret leadCaret = getLeadCaret();
      int oldSelectionStart = leadCaret.getLeadSelectionOffset();
      VisualPosition oldVisLeadSelectionStart = leadCaret.getLeadSelectionPosition();
      int oldCaretOffset = getCaretModel().getOffset();
      boolean multiCaretSelection = columnSelectionDrag || toggleCaretEvent;
      VisualPosition newVisualCaret = getTargetPosition(x, y, !multiCaretSelection, leadCaret);
      LogicalPosition newLogicalCaret = visualToLogicalPosition(newVisualCaret);
      if (multiCaretSelection) {
        myMultiSelectionInProgress = true;
        myRectangularSelectionInProgress = columnSelectionDrag || addRectangularSelectionEvent;
        myTargetMultiSelectionPosition = xyToVisualPosition(new Point(Math.max(x, 0), Math.max(y, 0)));
      }
      else {
        getCaretModel().moveToVisualPosition(newVisualCaret);
      }

      int newCaretOffset = getCaretModel().getOffset();
      newVisualCaret = getCaretModel().getVisualPosition();
      int caretShift = newCaretOffset - mySavedSelectionStart;

      if (myMousePressedEvent != null && getMouseEventArea(myMousePressedEvent) != EditorMouseEventArea.EDITING_AREA &&
          getMouseEventArea(myMousePressedEvent) != EditorMouseEventArea.LINE_NUMBERS_AREA) {
        selectionModel.setSelection(oldSelectionStart, newCaretOffset);
        myDragSelectionStarted = true;
      }
      else {
        if (multiCaretSelection) {
          if (myLastMousePressedLocation != null && (myCurrentDragIsSubstantial || !newLogicalCaret.equals(myLastMousePressedLocation))) {
            createSelectionTill(newLogicalCaret);
            blockActionsIfNeeded(e, myLastMousePressedLocation, newLogicalCaret);
            myDragSelectionStarted = true;
          }
        }
        else {
          if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) {
            setupSpecialSelectionOnMouseDrag(newCaretOffset, caretShift);
            cancelAutoResetForMouseSelectionState();
            return;
          }

          if (!myKeepSelectionOnMousePress) {
            // There is a possible case that lead selection position should be adjusted in accordance with the mouse move direction.
            // E.g., consider a situation when a user selects the whole line by clicking at 'line numbers' area.
            // 'Line end' is considered to be lead selection point then.
            // However, when the mouse is dragged down, we want to consider 'line start' to be lead selection point.
            if ((myMousePressArea == EditorMouseEventArea.LINE_NUMBERS_AREA
                 || myMousePressArea == EditorMouseEventArea.LINE_MARKERS_AREA)
                && selectionModel.hasSelection()) {
              if (newCaretOffset >= selectionModel.getSelectionEnd()) {
                oldSelectionStart = selectionModel.getSelectionStart();
                oldVisLeadSelectionStart = selectionModel.getSelectionStartPosition();
              }
              else if (newCaretOffset <= selectionModel.getSelectionStart()) {
                oldSelectionStart = selectionModel.getSelectionEnd();
                oldVisLeadSelectionStart = selectionModel.getSelectionEndPosition();
              }
            }
            else if (EditorUtil.isBlockLikeCaret(getCaretModel().getPrimaryCaret()) && Registry.is("editor.block.caret.selection.vim-like")) {
              // adjust selection range, so that it covers caret location
              if (mySelectionModel.hasSelection() && oldVisLeadSelectionStart.equals(mySelectionModel.getSelectionEndPosition())) {
                oldVisLeadSelectionStart = prevSelectionVisualPosition(oldVisLeadSelectionStart);
              }
              if (newVisualCaret.after(oldVisLeadSelectionStart)) {
                newVisualCaret = nextSelectionVisualPosition(newVisualCaret);
                newCaretOffset = visualPositionToOffset(newVisualCaret);
              }
              else if (oldVisLeadSelectionStart.after(newVisualCaret) ||
                       oldVisLeadSelectionStart.equals(newVisualCaret) && mySelectionModel.hasSelection()) {
                oldVisLeadSelectionStart = nextSelectionVisualPosition(oldVisLeadSelectionStart);
              }
              oldSelectionStart = visualPositionToOffset(oldVisLeadSelectionStart);
            }
            setSelectionAndBlockActions(e, oldVisLeadSelectionStart, oldSelectionStart, newVisualCaret, newCaretOffset);
            cancelAutoResetForMouseSelectionState();
            myDragSelectionStarted = true;
          }
          else {
            if (caretShift != 0) {
              if (myMousePressedEvent != null) {
                if (mySettings.isDndEnabled()) {
                  if (!myDragStarted) {
                    if (ApplicationManager.getApplication().isUnitTestMode()) {
                      // It can lead to process hanging, and breaking drag-n-drop in other applications
                      throw new UnsupportedOperationException("Drag'n'drop operation shouldn't be started in tests");
                    }
                    myDragStarted = true;
                    boolean isCopy = UIUtil.isControlKeyDown(e) || isViewer() || !getDocument().isWritable();
                    mySavedCaretOffsetForDNDUndoHack = oldCaretOffset;
                    getContentComponent().getTransferHandler().exportAsDrag(getContentComponent(), e, isCopy ? TransferHandler.COPY
                                                                                                             : TransferHandler.MOVE);
                  }
                }
                else {
                  selectionModel.removeSelection();
                }
              }
            }
          }
        }
      }
    }
    else {
      myScrollingTimer.start(dx, dy);
      onSubstantialDrag(e);
    }
  }
private void processMouseDragged(@NotNull MouseEvent e)