anchor.diff:    /// [_declaredMethod].
     final int _end;
   
  -  MethodInferenceNode(this._interfaceResolver, this._declaredMethod,
  +  MemberInferenceNode(this._interfaceResolver, this._declaredMethod,
         this._candidates, this._start, this._end);
  +
  +  DartType _matchTypes(Iterable<DartType> types) {
  +    var iterator = types.iterator;
  +    if (!iterator.moveNext()) {
  +      // No overridden types.  Infer `dynamic`.
  +      return const DynamicType();
  +    }
  +    var inferredType = iterator.current;
  +    while (iterator.moveNext()) {
  +      if (inferredType != iterator.current) {
  +        // TODO(paulberry): Types don't match.  Report an error.
  +        return const DynamicType();
  +      }
  +    }
  +    return inferredType;
  +  }
  +}
  +
  +/// Concrete class derived from [InferenceNode] to represent type inference of
  +/// methods.
  +class MethodInferenceNode extends MemberInferenceNode {
  +  MethodInferenceNode(InterfaceResolver interfaceResolver,
  +      Procedure declaredMethod, List<Member> candidates, int start, int end)
  +      : super(interfaceResolver, declaredMethod, candidates, start, end);
   
     @override
     void resolveInternal() {
  -    // First collect types of overridden methods
  +    var declaredMethod = _declaredMethod;
       var overriddenTypes = _computeMethodOverriddenTypes();
  -
  -    // Now infer types.
  -    DartType matchTypes(Iterable<DartType> types) {
  -      var iterator = types.iterator;
  -      if (!iterator.moveNext()) {
  -        // No overridden types.  Infer `dynamic`.
  -        return const DynamicType();
  -      }
  -      var inferredType = iterator.current;
  -      while (iterator.moveNext()) {
  -        if (inferredType != iterator.current) {
  -          // TODO(paulberry): Types don't match.  Report an error.
  -          return const DynamicType();
  -        }
  -      }
  -      return inferredType;
  -    }
  -
  -    if (ShadowProcedure.hasImplicitReturnType(_declaredMethod)) {
  -      _declaredMethod.function.returnType =
  -          matchTypes(overriddenTypes.map((type) => type.returnType));
  -    }
  -    var positionalParameters = _declaredMethod.function.positionalParameters;
  +    if (ShadowProcedure.hasImplicitReturnType(declaredMethod)) {
  +      declaredMethod.function.returnType =
  +          _matchTypes(overriddenTypes.map((type) => type.returnType));
  +    }
  +    var positionalParameters = declaredMethod.function.positionalParameters;
       for (int i = 0; i < positionalParameters.length; i++) {
         if (ShadowVariableDeclaration
             .isImplicitlyTyped(positionalParameters[i])) {
  
positive.code:   /// [candidates] a list containing the procedures overridden by [procedure],
    /// if any.  [start] is the index of the first such procedure, and [end] is
    /// the past-the-end index of the last such procedure.
    InferenceNode _createInferenceNode(Class class_, Procedure procedure,
        List<Member> candidates, int start, int end) {
      if (!_requiresTypeInference(procedure)) return null;
      switch (procedure.kind) {
        case ProcedureKind.Getter:
  
negative.code:       var candidateFunction = candidate.function;
        if (candidateFunction == null) {
          // This can happen if there are errors.  Just skip this override.
          continue;
        }
        var substitution = _interfaceResolver._substitutionFor(
            candidate, _declaredMethod.enclosingClass);
  