@Override
  protected void doExecute(@NotNull Editor editor, @Nullable Caret targetCaret, DataContext dataContext) {
    if (targetCaret != null) {
      if (!EditorUtil.checkMaxCarets(editor)) {
        targetCaret.clone(myCloneAbove);
      }
      return;
    }
    int currentLevel = 0;
    List<Caret> currentCarets = new ArrayList<>();
    for (Caret caret : editor.getCaretModel().getAllCarets()) {
      int level = getLevel(caret);
      if (Math.abs(level) > Math.abs(currentLevel)) {
        currentLevel = level;
        currentCarets.clear();
      }
      if (Math.abs(level) == Math.abs(currentLevel)) {
        currentCarets.add(caret);
      }
    }
    boolean removeCarets = currentLevel > 0 && myCloneAbove || currentLevel < 0 && !myCloneAbove;
    Integer newLevel = myCloneAbove ? currentLevel - 1 : currentLevel + 1;
    for (Caret caret : currentCarets) {
      if (removeCarets) {
        editor.getCaretModel().removeCaret(caret);
      }
      else {
        Caret clone = caret;
        do {
          Caret original = clone;
          clone = clone.clone(myCloneAbove);
          if (original != caret) {
            editor.getCaretModel().removeCaret(original);
          }
        } while (clone != null && caret.hasSelection() && !clone.hasSelection());
        if (clone == null) {
          if (EditorUtil.checkMaxCarets(editor)) break;
        }
        else {
          clone.putUserData(LEVEL, newLevel);
        }
      }
    }
    if (removeCarets) {
      editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
    }
  }
@Override
  protected void doExecute(@NotNull Editor editor, @Nullable Caret targetCaret, DataContext dataContext)