@Override
  public void executeWriteAction(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) {
    if (caret == null) caret = editor.getCaretModel().getPrimaryCaret();
    Document document = editor.getDocument();
    Couple<Integer> lineRange = getTargetLineRange(caret);
    if (lineRange == null) {
      return;
    }
    int startLine = lineRange.first;
    int endLine = lineRange.second;
    int lineCount = endLine - startLine + 1;
    String[] lines = new String[lineCount];
    for (int i = 0; i < lineCount; i++) {
      int line = i + startLine;
      lines[i] = document.getText(new TextRange(document.getLineStartOffset(line), document.getLineEndOffset(line)));
    }
    boolean hasSelection = caret.hasSelection();
    String caretLineContent = null;
    int caretOffsetInLine = 0;
    if (!hasSelection) {
      int caretLine = caret.getLogicalPosition().line;
      if (caretLine <= endLine) {
        caretLineContent = lines[caretLine - startLine];
        caretOffsetInLine = caret.getOffset() - document.getLineStartOffset(caretLine);
      }
    }
    permute(lines);
    String newContent = String.join("\n", lines);
    int toReplaceStart = document.getLineStartOffset(startLine);
    int toReplaceEnd = document.getLineEndOffset(endLine);
    document.replaceString(toReplaceStart, toReplaceEnd, newContent);
    if (hasSelection) {
      int selectionEnd = endLine < document.getLineCount() - 1 ? document.getLineStartOffset(endLine + 1) : document.getTextLength();
      caret.moveToOffset(selectionEnd);
      caret.setSelection(toReplaceStart, selectionEnd);
    }
    else if (caretLineContent != null) {
      for (int i = 0; i < lineCount; i++) {
        if (Strings.areSameInstance(lines[i], caretLineContent)) {
          caret.moveToOffset(document.getLineStartOffset(startLine + i) + caretOffsetInLine);
          break;
        }
      }
    }
    editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
  }
@Override
  public void executeWriteAction(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext)