@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);
    }
  }
 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);
 }