@Override
 public DfaInstructionState[] visitInstanceof(
     InstanceofInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
   memState.pop();
   memState.pop();
   memState.push(
       new DfaInstanceofValue(
           runner.getFactory(), instruction.getLeft(), instruction.getCastType()));
   return new DfaInstructionState[] {
     new DfaInstructionState(runner.getInstruction(instruction.getIndex() + 1), memState)
   };
 }
    @Override
    public DfaInstructionState[] visitAssign(
        AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
      final Instruction nextInstruction = runner.getInstruction(instruction.getIndex() + 1);

      final DfaValue dfaSource = memState.pop();
      final DfaValue dfaDest = memState.pop();

      if (dfaDest instanceof DfaVariableValue) {
        DfaVariableValue var = (DfaVariableValue) dfaDest;
        final PsiExpression rightValue = instruction.getRExpression();
        final PsiElement parent = rightValue == null ? null : rightValue.getParent();
        final IElementType type =
            parent instanceof PsiAssignmentExpression
                ? ((PsiAssignmentExpression) parent).getOperationTokenType()
                : JavaTokenType.EQ;
        // store current value - to use in case of '+='
        final PsiExpression prevValue =
            ((ValuableDataFlowRunner.ValuableDfaVariableState)
                    ((ValuableDataFlowRunner.MyDfaMemoryState) memState).getVariableState(var))
                .myExpression;
        memState.setVarValue(var, dfaSource);
        // state may have been changed so re-retrieve it
        final ValuableDataFlowRunner.ValuableDfaVariableState curState =
            (ValuableDataFlowRunner.ValuableDfaVariableState)
                ((ValuableDataFlowRunner.MyDfaMemoryState) memState).getVariableState(var);
        final PsiExpression curValue = curState.myExpression;
        final PsiExpression nextValue;
        if (type == JavaTokenType.PLUSEQ && prevValue != null) {
          PsiExpression tmpExpression;
          try {
            tmpExpression =
                JavaPsiFacade.getElementFactory(myContext.getProject())
                    .createExpressionFromText(
                        prevValue.getText() + "+" + rightValue.getText(), rightValue);
          } catch (Exception e) {
            tmpExpression = curValue == null ? rightValue : curValue;
          }
          nextValue = tmpExpression;
        } else {
          nextValue = curValue == null ? rightValue : curValue;
        }
        curState.myExpression = nextValue;
      }
      memState.push(dfaDest);
      return new DfaInstructionState[] {new DfaInstructionState(nextInstruction, memState)};
    }
  @Nullable
  private DfaInstructionState[] handleRelationBinop(
      BinopInstruction instruction,
      DataFlowRunner runner,
      DfaMemoryState memState,
      DfaValue dfaRight,
      DfaValue dfaLeft) {
    DfaValueFactory factory = runner.getFactory();
    final Instruction next = runner.getInstruction(instruction.getIndex() + 1);
    DfaRelationValue dfaRelation =
        factory
            .getRelationFactory()
            .createRelation(dfaLeft, dfaRight, instruction.getOperationSign(), false);
    if (dfaRelation == null) {
      return null;
    }

    myCanBeNullInInstanceof.add(instruction);

    ArrayList<DfaInstructionState> states = new ArrayList<DfaInstructionState>();

    final DfaMemoryState trueCopy = memState.createCopy();
    if (trueCopy.applyCondition(dfaRelation)) {
      trueCopy.push(factory.getConstFactory().getTrue());
      instruction.setTrueReachable();
      states.add(new DfaInstructionState(next, trueCopy));
    }

    //noinspection UnnecessaryLocalVariable
    DfaMemoryState falseCopy = memState;
    if (falseCopy.applyCondition(dfaRelation.createNegated())) {
      falseCopy.push(factory.getConstFactory().getFalse());
      instruction.setFalseReachable();
      states.add(new DfaInstructionState(next, falseCopy));
      if (instruction instanceof InstanceofInstruction && !falseCopy.isNull(dfaLeft)) {
        myUsefulInstanceofs.add((InstanceofInstruction) instruction);
      }
    }

    return states.toArray(new DfaInstructionState[states.size()]);
  }