anchor.diff:        left = read;
       }
   
  -    ObjectAccessTarget binaryTarget = inferrer.findInterfaceMember(
  -        readType, node.binaryName, node.binaryOffset,
  -        includeExtensionMethods: true);
  -
  -    MethodContravarianceCheckKind binaryCheckKind =
  -        inferrer.preCheckInvocationContravariance(readType, binaryTarget,
  -            isThisReceiver: false);
  -
  -    DartType binaryType = inferrer.getReturnType(binaryTarget, readType);
  -    DartType rhsType =
  -        inferrer.getPositionalParameterTypeForTarget(binaryTarget, readType, 0);
  -
  -    ExpressionInferenceResult rhsResult =
  -        inferrer.inferExpression(node.rhs, rhsType, true, isVoidAllowed: true);
  -    Expression rhs = inferrer.ensureAssignableResult(rhsType, rhsResult);
  -
  -    if (inferrer.isOverloadedArithmeticOperatorAndType(
  -        binaryTarget, readType)) {
  -      binaryType = inferrer.typeSchemaEnvironment
  -          .getTypeOfOverloadedArithmetic(readType, rhsResult.inferredType);
  -    }
  -
  -    Expression binary;
  -    if (binaryTarget.isMissing) {
  -      binary = inferrer.helper.buildProblem(
  -          templateUndefinedMethod.withArguments(node.binaryName.name, readType),
  -          node.binaryOffset,
  -          node.binaryName.name.length);
  -    } else if (binaryTarget.isExtensionMember) {
  -      assert(binaryTarget.extensionMethodKind != ProcedureKind.Setter);
  -      binary = new StaticInvocation(
  -          binaryTarget.member,
  -          new Arguments(<Expression>[
  -            left,
  -            rhs,
  -          ], types: binaryTarget.inferredExtensionTypeArguments)
  -            ..fileOffset = node.binaryOffset)
  -        ..fileOffset = node.binaryOffset;
  -    } else {
  -      binary = new MethodInvocation(
  -          left,
  -          node.binaryName,
  -          new Arguments(<Expression>[
  -            rhs,
  -          ])
  -            ..fileOffset = node.binaryOffset,
  -          binaryTarget.member)
  -        ..fileOffset = node.binaryOffset;
  -
  -      if (binaryCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
  -        if (inferrer.instrumentation != null) {
  -          inferrer.instrumentation.record(
  -              inferrer.uriForInstrumentation,
  -              node.binaryOffset,
  -              'checkReturn',
  -              new InstrumentationValueForType(readType));
  -        }
  -        binary = new AsExpression(binary, binaryType)
  -          ..isTypeError = true
  -          ..fileOffset = node.binaryOffset;
  -      }
  -    }
  +    ExpressionInferenceResult binaryResult = _computeBinaryExpression(
  +        node.binaryOffset, left, readType, node.binaryName, node.rhs);
  +    Expression binary = binaryResult.expression;
  +    DartType binaryType = binaryResult.inferredType;
   
       ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
           receiverType, indexSetName, node.writeOffset,
  
positive.code:       left = read;
      }
  
      ObjectAccessTarget binaryTarget = inferrer.findInterfaceMember(
          readType, node.binaryName, node.binaryOffset,
          includeExtensionMethods: true);
  
      MethodContravarianceCheckKind binaryCheckKind =
          inferrer.preCheckInvocationContravariance(readType, binaryTarget,
              isThisReceiver: false);
  
      DartType binaryType = inferrer.getReturnType(binaryTarget, readType);
      DartType rhsType =
          inferrer.getPositionalParameterTypeForTarget(binaryTarget, readType, 0);
  
      ExpressionInferenceResult rhsResult =
          inferrer.inferExpression(node.rhs, rhsType, true, isVoidAllowed: true);
      Expression rhs = inferrer.ensureAssignableResult(rhsType, rhsResult);
  
      if (inferrer.isOverloadedArithmeticOperatorAndType(
          binaryTarget, readType)) {
        binaryType = inferrer.typeSchemaEnvironment
            .getTypeOfOverloadedArithmetic(readType, rhsResult.inferredType);
      }
  
      Expression binary;
      if (binaryTarget.isMissing) {
        binary = inferrer.helper.buildProblem(
            templateUndefinedMethod.withArguments(node.binaryName.name, readType),
            node.binaryOffset,
            node.binaryName.name.length);
      } else if (binaryTarget.isExtensionMember) {
        binary = new StaticInvocation(
            binaryTarget.member,
            new Arguments(<Expression>[
              left,
              rhs,
            ], types: binaryTarget.inferredExtensionTypeArguments)
              ..fileOffset = node.binaryOffset)
          ..fileOffset = node.binaryOffset;
      } else {
        binary = new MethodInvocation(
            left,
            node.binaryName,
            new Arguments(<Expression>[
              rhs,
            ])
              ..fileOffset = node.binaryOffset,
            binaryTarget.member)
          ..fileOffset = node.binaryOffset;
  
        if (binaryCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
          if (inferrer.instrumentation != null) {
            inferrer.instrumentation.record(
                inferrer.uriForInstrumentation,
                node.binaryOffset,
                'checkReturn',
                new InstrumentationValueForType(readType));
          }
          binary = new AsExpression(binary, binaryType)
            ..isTypeError = true
            ..fileOffset = node.binaryOffset;
        }
      }
  
      ObjectAccessTarget writeTarget = node.setter != null
          ? new ObjectAccessTarget.interfaceMember(node.setter)
  
negative.code:       left = read;
      }
  
      ExpressionInferenceResult binaryResult = _computeBinaryExpression(
          node.binaryOffset, left, readType, node.binaryName, node.rhs);
      Expression binary = binaryResult.expression;
      DartType binaryType = binaryResult.inferredType;
  
      ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
          receiverType, node.propertyName, node.writeOffset,
  