@Override
  public void visitUnaryExpression(GrUnaryExpression expression) {
    final GrExpression operand = expression.getOperand();
    if (operand == null) return;

    if (expression.getOperationTokenType() != mLNOT) {
      operand.accept(this);
      visitCall(expression);
      return;
    }

    ConditionInstruction cond = new ConditionInstruction(expression);
    addNodeAndCheckPending(cond);
    registerCondition(cond);

    operand.accept(this);
    visitCall(expression);

    myConditions.removeFirstOccurrence(cond);

    List<GotoInstruction> negations = collectAndRemoveAllPendingNegations(expression);

    InstructionImpl head = myHead;
    addNodeAndCheckPending(new PositiveGotoInstruction(expression, cond));
    handlePossibleReturn(expression);
    addPendingEdge(expression, myHead);

    if (negations.isEmpty()) {
      myHead = head;
    } else {
      myHead = reduceAllNegationsIntoInstruction(expression, negations);
    }
  }
  @Override
  protected void processIntention(@NotNull PsiElement element, Project project, Editor editor)
      throws IncorrectOperationException {
    PsiElement parent = element.getParent();

    if (!"if".equals(element.getText()) || !(parent instanceof GrIfStatement)) {
      throw new IncorrectOperationException("Not invoked on an if");
    }
    GrIfStatement parentIf = (GrIfStatement) parent;
    GroovyPsiElementFactory groovyPsiElementFactory = GroovyPsiElementFactory.getInstance(project);

    GrExpression condition = parentIf.getCondition();
    if (condition == null) {
      throw new IncorrectOperationException("Invoked on an if with empty condition");
    }

    GrExpression negatedCondition = null;
    if (condition instanceof GrUnaryExpression) {
      GrUnaryExpression unaryCondition = (GrUnaryExpression) condition;
      if ("!".equals(unaryCondition.getOperationToken().getText())) {
        negatedCondition = stripParenthesis(unaryCondition.getOperand());
      }
    }

    if (negatedCondition == null) {
      // Now check whether this is a simple expression
      condition = stripParenthesis(condition);
      String negatedExpressionText;
      if (condition instanceof GrCallExpression || condition instanceof GrReferenceExpression) {
        negatedExpressionText = "!" + condition.getText();
      } else {
        negatedExpressionText = "!(" + condition.getText() + ")";
      }
      negatedCondition =
          groovyPsiElementFactory.createExpressionFromText(negatedExpressionText, parentIf);
    }

    GrStatement thenBranch = parentIf.getThenBranch();
    final boolean thenIsNotEmpty = isNotEmpty(thenBranch);

    String newIfText = "if (" + negatedCondition.getText() + ") {}";
    if (thenIsNotEmpty) {
      newIfText += " else {}";
    }

    GrIfStatement newIf =
        (GrIfStatement)
            groovyPsiElementFactory.createStatementFromText(newIfText, parentIf.getContext());
    generateElseBranchTextAndRemoveTailStatements(parentIf, newIf);

    if (thenIsNotEmpty) {
      final GrStatement elseBranch = newIf.getElseBranch();
      assert elseBranch != null;
      elseBranch.replaceWithStatement(thenBranch);
    }

    parentIf.replace(newIf);
  }
 private static boolean postfixExpressionsAreEquivalent(
     @NotNull GrUnaryExpression postfixExp1, @NotNull GrUnaryExpression postfixExp2) {
   final IElementType sign1 = postfixExp1.getOperationTokenType();
   final IElementType sign2 = postfixExp2.getOperationTokenType();
   if (!sign1.equals(sign2)) {
     return false;
   }
   final GrExpression operand1 = postfixExp1.getOperand();
   final GrExpression operand2 = postfixExp2.getOperand();
   return expressionsAreEquivalent(operand1, operand2);
 }