@Override
  public boolean checkAvailable(
      @NotNull final Editor editor,
      @NotNull final PsiFile file,
      @NotNull final MoveInfo info,
      final boolean down) {
    // if (!(file instanceof PsiJavaFile)) return false;
    final boolean available = super.checkAvailable(editor, file, info, down);
    if (!available) return false;
    LineRange range = info.toMove;

    range = expandLineRangeToCoverPsiElements(range, editor, file);
    if (range == null) return false;
    info.toMove = range;
    final int startOffset = editor.logicalPositionToOffset(new LogicalPosition(range.startLine, 0));
    final int endOffset = editor.logicalPositionToOffset(new LogicalPosition(range.endLine, 0));
    final PsiElement[] statements =
        CodeInsightUtil.findStatementsInRange(file, startOffset, endOffset);
    if (statements.length == 0) return false;
    range.firstElement = statements[0];
    range.lastElement = statements[statements.length - 1];

    if (!checkMovingInsideOutside(file, editor, range, info, down)) {
      info.toMove2 = null;
      return true;
    }
    return true;
  }
  private boolean checkMovingInsideOutside(
      PsiFile file,
      final Editor editor,
      LineRange range,
      @NotNull final MoveInfo info,
      final boolean down) {
    final int offset = editor.getCaretModel().getOffset();

    PsiElement elementAtOffset = file.getViewProvider().findElementAt(offset, StdLanguages.JAVA);
    if (elementAtOffset == null) return false;

    PsiElement guard = elementAtOffset;
    do {
      guard =
          PsiTreeUtil.getParentOfType(
              guard, PsiMethod.class, PsiClassInitializer.class, PsiClass.class, PsiComment.class);
    } while (guard instanceof PsiAnonymousClass);

    PsiElement brace = itIsTheClosingCurlyBraceWeAreMoving(file, editor);
    if (brace != null) {
      int line = editor.getDocument().getLineNumber(offset);
      final LineRange toMove = new LineRange(line, line + 1);
      toMove.firstElement = toMove.lastElement = brace;
      info.toMove = toMove;
    }

    // cannot move in/outside method/class/initializer/comment
    if (!calcInsertOffset(file, editor, info.toMove, info, down)) return false;
    int insertOffset =
        down
            ? getLineStartSafeOffset(editor.getDocument(), info.toMove2.endLine)
            : editor.getDocument().getLineStartOffset(info.toMove2.startLine);
    PsiElement elementAtInsertOffset =
        file.getViewProvider().findElementAt(insertOffset, StdLanguages.JAVA);
    PsiElement newGuard = elementAtInsertOffset;
    do {
      newGuard =
          PsiTreeUtil.getParentOfType(
              newGuard,
              PsiMethod.class,
              PsiClassInitializer.class,
              PsiClass.class,
              PsiComment.class);
    } while (newGuard instanceof PsiAnonymousClass);

    if (brace != null
        && PsiTreeUtil.getParentOfType(brace, PsiCodeBlock.class, false)
            != PsiTreeUtil.getParentOfType(elementAtInsertOffset, PsiCodeBlock.class, false)) {
      info.indentSource = true;
    }
    if (newGuard == guard && isInside(insertOffset, newGuard) == isInside(offset, guard))
      return true;

    // moving in/out nested class is OK
    if (guard instanceof PsiClass && guard.getParent() instanceof PsiClass) return true;
    if (newGuard instanceof PsiClass && newGuard.getParent() instanceof PsiClass) return true;

    return false;
  }