protected static int insertStringAtCaretNoScrolling(@NotNull Editor editor, @NotNull String s, boolean toProcessOverwriteMode, boolean toMoveCaret, int caretShift) {
    // There is a possible case that particular soft wraps become hard wraps if the caret is located at soft wrap-introduced virtual
    // space, hence, we need to give editor a chance to react accordingly.
    editor.getSoftWrapModel().beforeDocumentChangeAtCaret();
    int oldOffset = editor.getSelectionModel().getSelectionStart();

    String filler = editor.getSelectionModel().hasSelection() ? "" : calcStringToFillVirtualSpace(editor);
    if (!filler.isEmpty()) {
      s = filler + s;
    }

    Document document = editor.getDocument();
    SelectionModel selectionModel = editor.getSelectionModel();
    if (editor.isInsertMode() || !toProcessOverwriteMode) {
      if (selectionModel.hasSelection()) {
        document.replaceString(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), s);
      } else {
        document.insertString(oldOffset, s);
      }
    } else {
      deleteSelectedText(editor);
      if (s.length() == 1 && Character.isLowSurrogate(s.charAt(0)) &&
          oldOffset > 0 && Character.isHighSurrogate(document.getImmutableCharSequence().charAt(oldOffset - 1))) {
        // Hack to support input of surrogate pairs in editor via InputMethodEvent.
        // Such input is processed char-by-char using EditorImpl.processKeyTyped.
        document.insertString(oldOffset, s);
      }
      else {
        int lineNumber = editor.getCaretModel().getLogicalPosition().line;
        int lineEndOffset = document.getLineEndOffset(lineNumber);
        int inputCodePointCount = s.codePointCount(0, s.length());
        int endOffset;
        try {
          endOffset = Math.min(lineEndOffset,
                               Character.offsetByCodePoints(document.getImmutableCharSequence(), oldOffset, inputCodePointCount));
        }
        catch (IndexOutOfBoundsException e) {
          endOffset = lineEndOffset;
        }
        document.replaceString(oldOffset, endOffset, s);
      }
    }

    int offset = oldOffset + filler.length() + caretShift;
    if (toMoveCaret){
      editor.getCaretModel().moveToVisualPosition(editor.offsetToVisualPosition(offset, false, true));
      selectionModel.removeSelection();
    }
    else if (editor.getCaretModel().getOffset() != oldOffset) { // handling the case when caret model tracks document changes
      editor.getCaretModel().moveToOffset(oldOffset);
    }

    return offset;
  }
protected static int insertStringAtCaretNoScrolling(@NotNull Editor editor, @NotNull String s, boolean toProcessOverwriteMode, boolean toMoveCaret, int caretShift)