@Override
  public void visitAssignmentExpression(@NotNull PsiAssignmentExpression expression) {
    super.visitAssignmentExpression(expression);

    final PsiExpression lExpression = expression.getLExpression();
    final TypeView left = new TypeView(lExpression);

    final PsiExpression rExpression = expression.getRExpression();
    if (rExpression == null) return;
    final TypeView right = new TypeView(rExpression);

    final IElementType sign = expression.getOperationTokenType();
    final PsiType ltype = left.getType();
    final PsiType rtype = right.getType();
    if (ltype == null || rtype == null) return;

    if (sign != JavaTokenType.EQ) {
      final IElementType binaryOperator = TypeConversionUtil.convertEQtoOperation(sign);
      if (!TypeConversionUtil.isBinaryOperatorApplicable(binaryOperator, ltype, rtype, false)) {
        if (left.isChanged()) {
          findConversionOrFail(expression, lExpression, left.getTypePair());
        }
        if (right.isChanged()) {
          findConversionOrFail(expression, rExpression, right.getTypePair());
        }
        return;
      }
      if (binaryOperator == JavaTokenType.PLUS && !left.isChanged() && right.isChanged() &&
          ltype.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
        return;
      }
    }

    switch (TypeInfection.getInfection(left, right)) {
      case NONE_INFECTED -> {}
      case LEFT_INFECTED ->
        myLabeler.migrateExpressionType(rExpression, ltype, myStatement,
                                        TypeConversionUtil.isAssignable(ltype, rtype) && !isSetter(expression), true);
      case RIGHT_INFECTED -> {
        if (lExpression instanceof PsiReferenceExpression &&
            ((PsiReferenceExpression)lExpression).resolve() instanceof PsiLocalVariable &&
            !canBeVariableType(rtype)) {
          tryToRemoveLocalVariableAssignment((PsiLocalVariable)Objects.requireNonNull(((PsiReferenceExpression)lExpression).resolve()),
                                             rExpression, rtype);
        }
        else {
          myLabeler.migrateExpressionType(lExpression, rtype, myStatement, TypeConversionUtil.isAssignable(ltype, rtype), false);
        }
      }
      case BOTH_INFECTED -> {
        addTypeUsage(lExpression);
        addTypeUsage(rExpression);
      }
    }
  }
@Override
  public void visitAssignmentExpression(@NotNull PsiAssignmentExpression expression)