private boolean hardEquals(
     PsiModifierListOwner psiVar, PsiType varType, boolean negated, DfaVariableValue qualifier) {
   return psiVar == myVariable
       && Comparing.equal(
           TypeConversionUtil.erasure(varType), TypeConversionUtil.erasure(myVarType))
       && negated == myIsNegated
       && (myQualifier == null
           ? qualifier == null
           : myQualifier.hardEquals(
               qualifier.getPsiVariable(),
               qualifier.getVariableType(),
               qualifier.isNegated(),
               qualifier.getQualifier()));
 }
  @Override
  public DfaInstructionState[] visitAssign(
      AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
    DfaValue dfaSource = memState.pop();
    DfaValue dfaDest = memState.pop();

    if (dfaDest instanceof DfaVariableValue) {
      DfaVariableValue var = (DfaVariableValue) dfaDest;

      DfaValueFactory factory = runner.getFactory();
      if (dfaSource instanceof DfaVariableValue
          && factory.getVarFactory().getAllQualifiedBy(var).contains(dfaSource)) {
        Nullness nullability =
            memState.isNotNull(dfaSource)
                ? Nullness.NOT_NULL
                : ((DfaVariableValue) dfaSource).getInherentNullability();
        dfaSource =
            factory.createTypeValue(((DfaVariableValue) dfaSource).getVariableType(), nullability);
      }

      if (var.getInherentNullability() == Nullness.NOT_NULL) {
        checkNotNullable(
            memState,
            dfaSource,
            NullabilityProblem.assigningToNotNull,
            instruction.getRExpression());
      }
      final PsiModifierListOwner psi = var.getPsiVariable();
      if (!(psi instanceof PsiField) || !psi.hasModifierProperty(PsiModifier.VOLATILE)) {
        memState.setVarValue(var, dfaSource);
      }
    } else if (dfaDest instanceof DfaTypeValue && ((DfaTypeValue) dfaDest).isNotNull()) {
      checkNotNullable(
          memState, dfaSource, NullabilityProblem.assigningToNotNull, instruction.getRExpression());
    }

    memState.push(dfaDest);

    return nextInstruction(instruction, runner, memState);
  }