private static void restoreCaretAndSelection(final @NotNull PsiFile file, final @NotNull Editor editor, boolean selectionStartAtCaret,
                                               boolean hasSelection, final @NotNull SelectionContainer selectionContainer, int shift,
                                               int offset, final @NotNull MyLineRange toMove,
                                               LogicalPosition selectionBeforeMoveStart,
                                               LogicalPosition selectionBeforeMoveEnd,
                                               LogicalPosition positionOffsetAfterMove) {
    final Document document = editor.getDocument();
    final SelectionModel selectionModel = editor.getSelectionModel();
    final CaretModel caretModel = editor.getCaretModel();
    int selectionLen = selectionContainer.myLen;
    final PsiElement at = file.findElementAt(offset);
    if (at != null) {
      final PsiElement added = getCommentOrStatement(document, at);
      int size = toMove.size;
      if (size > 1) {
        PsiElement tmp = added.getNextSibling();
        while (size > 1 && tmp != null) {
          if (tmp instanceof PsiWhiteSpace) {
            if (!selectionStartAtCaret)
              shift += tmp.getTextLength();
            selectionLen += tmp.getTextLength();
          }
          tmp = tmp.getNextSibling();
          size -= 1;
        }
      }
      if (shift < 0) shift = 0;
      final int column = editor.offsetToLogicalPosition(added.getTextRange().getStartOffset()).column;
      if (selectionContainer.myAtTheBeginning || column < selectionContainer.myAdditional) {
        selectionLen += column;
      }
      else {
        selectionLen += selectionContainer.myAdditional;
      }
      if (selectionContainer.myAtTheBeginning && selectionStartAtCaret)
        shift = -column;
    }

    final int documentLength = document.getTextLength();
    int newCaretOffset = offset + shift;
    if (newCaretOffset >= documentLength) newCaretOffset = documentLength;
    caretModel.moveToOffset(newCaretOffset);

    if (hasSelection) {
      int selectionLinesDiff = selectionBeforeMoveEnd.line - selectionBeforeMoveStart.line;
      if (selectionLinesDiff > 1) {
        int endOffsetColumn = selectionBeforeMoveEnd.column;
        if (endOffsetColumn > 0) endOffsetColumn += positionOffsetAfterMove.column - selectionBeforeMoveStart.column;
        int startOffsetColumn = positionOffsetAfterMove.column;
        if (selectionBeforeMoveStart.column == 0) startOffsetColumn = 0;
        int startOffset = editor.logicalPositionToOffset(new LogicalPosition(positionOffsetAfterMove.line, startOffsetColumn));
        int endOffset = editor.logicalPositionToOffset(new LogicalPosition(positionOffsetAfterMove.line + selectionLinesDiff, endOffsetColumn));
        selectionModel.setSelection(startOffset, endOffset);
        if (selectionStartAtCaret) {
          caretModel.moveToOffset(startOffset);
        }
        else {
          caretModel.moveToOffset(endOffset);
        }
      }
      else {
        if (selectionStartAtCaret) {
          int newSelectionEnd = newCaretOffset + selectionLen;
          selectionModel.setSelection(newCaretOffset, newSelectionEnd);
        }
        else {
          int newSelectionStart = newCaretOffset - selectionLen;
          selectionModel.setSelection(newSelectionStart, newCaretOffset);
        }
      }
    }
  }
private static void restoreCaretAndSelection(final @NotNull PsiFile file, final @NotNull Editor editor, boolean selectionStartAtCaret,
                                               boolean hasSelection, final @NotNull SelectionContainer selectionContainer, int shift,
                                               int offset, final @NotNull MyLineRange toMove,
                                               LogicalPosition selectionBeforeMoveStart,
                                               LogicalPosition selectionBeforeMoveEnd,
                                               LogicalPosition positionOffsetAfterMove)